@tomflow/proflow-platform-cli 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/deployment/adapter.d.ts +5 -5
- package/dist/deployment/descriptor.d.ts +1 -1
- package/dist/deployment/descriptor.js +1 -1
- package/dist/src/apply/driver.d.ts +4 -0
- package/dist/src/apply/driver.js +73 -0
- package/dist/src/cli.js +29 -2
- package/package.json +1 -1
- package/proflow.module.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @tomflow/proflow-platform-cli
|
|
2
2
|
|
|
3
|
+
## 0.1.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fully clean Workspace uninstall artifacts by removing empty ProFlow layout directories and stale pnpm release-age entries across prior managed versions.
|
|
8
|
+
|
|
9
|
+
## 0.1.12
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Clean pnpm release-age and empty-root lockfile artifacts after whole Workspace uninstall, and remove the `.proflow` root only when it is empty while preserving non-deployment data.
|
|
14
|
+
|
|
3
15
|
## 0.1.11
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -5,7 +5,7 @@ export declare const behaviorAdapter: {
|
|
|
5
5
|
ok: boolean;
|
|
6
6
|
status: "SUCCEEDED";
|
|
7
7
|
moduleRef: "platform-cli";
|
|
8
|
-
moduleVersion: "0.1.
|
|
8
|
+
moduleVersion: "0.1.13";
|
|
9
9
|
data?: {} | null;
|
|
10
10
|
};
|
|
11
11
|
observedEffects: never[];
|
|
@@ -16,7 +16,7 @@ export declare const behaviorAdapter: {
|
|
|
16
16
|
ok: boolean;
|
|
17
17
|
status: "SUCCEEDED";
|
|
18
18
|
moduleRef: "platform-cli";
|
|
19
|
-
moduleVersion: "0.1.
|
|
19
|
+
moduleVersion: "0.1.13";
|
|
20
20
|
data?: {} | null;
|
|
21
21
|
};
|
|
22
22
|
observedEffects: never[];
|
|
@@ -27,7 +27,7 @@ export declare const behaviorAdapter: {
|
|
|
27
27
|
ok: boolean;
|
|
28
28
|
status: "SUCCEEDED";
|
|
29
29
|
moduleRef: "platform-cli";
|
|
30
|
-
moduleVersion: "0.1.
|
|
30
|
+
moduleVersion: "0.1.13";
|
|
31
31
|
data?: {} | null;
|
|
32
32
|
};
|
|
33
33
|
observedEffects: never[];
|
|
@@ -38,7 +38,7 @@ export declare const behaviorAdapter: {
|
|
|
38
38
|
ok: boolean;
|
|
39
39
|
status: "SUCCEEDED";
|
|
40
40
|
moduleRef: "platform-cli";
|
|
41
|
-
moduleVersion: "0.1.
|
|
41
|
+
moduleVersion: "0.1.13";
|
|
42
42
|
data?: {} | null;
|
|
43
43
|
};
|
|
44
44
|
observedEffects: never[];
|
|
@@ -49,7 +49,7 @@ export declare const behaviorAdapter: {
|
|
|
49
49
|
ok: boolean;
|
|
50
50
|
status: "SUCCEEDED";
|
|
51
51
|
moduleRef: "platform-cli";
|
|
52
|
-
moduleVersion: "0.1.
|
|
52
|
+
moduleVersion: "0.1.13";
|
|
53
53
|
data?: {} | null;
|
|
54
54
|
};
|
|
55
55
|
observedEffects: never[];
|
|
@@ -3,7 +3,7 @@ export declare const descriptor: {
|
|
|
3
3
|
readonly contractVersion: "1.0.0";
|
|
4
4
|
readonly moduleRef: "platform-cli";
|
|
5
5
|
readonly packageName: "@tomflow/proflow-platform-cli";
|
|
6
|
-
readonly moduleVersion: "0.1.
|
|
6
|
+
readonly moduleVersion: "0.1.13";
|
|
7
7
|
readonly kind: "cli";
|
|
8
8
|
readonly templateVersion: "1.0.0";
|
|
9
9
|
readonly platformCompatibility: ">=1.0.0 <2.0.0";
|
|
@@ -3,7 +3,7 @@ export const descriptor = {
|
|
|
3
3
|
contractVersion: "1.0.0",
|
|
4
4
|
moduleRef: "platform-cli",
|
|
5
5
|
packageName: "@tomflow/proflow-platform-cli",
|
|
6
|
-
moduleVersion: "0.1.
|
|
6
|
+
moduleVersion: "0.1.13",
|
|
7
7
|
kind: "cli",
|
|
8
8
|
templateVersion: "1.0.0",
|
|
9
9
|
platformCompatibility: ">=1.0.0 <2.0.0",
|
|
@@ -17,6 +17,10 @@ export interface PackageManagerDriver {
|
|
|
17
17
|
* no-op driver to claim a product Workspace package mutation succeeded.
|
|
18
18
|
*/
|
|
19
19
|
export declare function workspaceResidentDriver(): PackageManagerDriver;
|
|
20
|
+
export declare function cleanupWorkspacePackageManagerArtifacts(options: {
|
|
21
|
+
workspaceRoot: string;
|
|
22
|
+
removedModules: readonly ResolvedModule[];
|
|
23
|
+
}): Promise<void>;
|
|
20
24
|
export declare function createWorkspacePackageManagerDriver(options: {
|
|
21
25
|
workspaceRoot: string;
|
|
22
26
|
runner?: PackageCommandRunner;
|
package/dist/src/apply/driver.js
CHANGED
|
@@ -18,6 +18,14 @@ export function workspaceResidentDriver() {
|
|
|
18
18
|
async remove() { },
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
+
export async function cleanupWorkspacePackageManagerArtifacts(options) {
|
|
22
|
+
const manager = await readWorkspacePackageManagerSelection(options.workspaceRoot);
|
|
23
|
+
if (manager.name !== "pnpm")
|
|
24
|
+
return;
|
|
25
|
+
const removedPackageNames = new Set(options.removedModules.map((module) => module.packageName));
|
|
26
|
+
await cleanupPnpmReleaseAgeExcludes(options.workspaceRoot, removedPackageNames);
|
|
27
|
+
await normalizeEmptyPnpmRootImporter(options.workspaceRoot);
|
|
28
|
+
}
|
|
21
29
|
export function createWorkspacePackageManagerDriver(options) {
|
|
22
30
|
const runner = options.runner ?? systemPackageCommandRunner();
|
|
23
31
|
const executableAvailable = options.executableAvailable ?? findExecutable;
|
|
@@ -148,6 +156,71 @@ async function readWorkspaceManifest(workspaceRoot) {
|
|
|
148
156
|
return undefined;
|
|
149
157
|
}
|
|
150
158
|
}
|
|
159
|
+
async function cleanupPnpmReleaseAgeExcludes(workspaceRoot, removedPackageNames) {
|
|
160
|
+
const path = join(workspaceRoot, "pnpm-workspace.yaml");
|
|
161
|
+
let raw;
|
|
162
|
+
try {
|
|
163
|
+
raw = await readFile(path, "utf8");
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
if (isMissingFile(error))
|
|
167
|
+
return;
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
const lines = raw.split("\n");
|
|
171
|
+
const keyIndex = lines.indexOf("minimumReleaseAgeExclude:");
|
|
172
|
+
if (keyIndex < 0)
|
|
173
|
+
return;
|
|
174
|
+
let endIndex = keyIndex + 1;
|
|
175
|
+
while (endIndex < lines.length &&
|
|
176
|
+
(lines[endIndex]?.trim() === "" || /^\s/.test(lines[endIndex] ?? ""))) {
|
|
177
|
+
endIndex += 1;
|
|
178
|
+
}
|
|
179
|
+
const retained = lines.slice(keyIndex + 1, endIndex).filter((line) => {
|
|
180
|
+
const match = /^\s*-\s+(.+?)\s*$/.exec(line);
|
|
181
|
+
if (match === null)
|
|
182
|
+
return true;
|
|
183
|
+
const value = stripYamlQuotes(match[1] ?? "");
|
|
184
|
+
for (const packageName of removedPackageNames) {
|
|
185
|
+
if (value === packageName || value.startsWith(`${packageName}@`))
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
return true;
|
|
189
|
+
});
|
|
190
|
+
const hasListItem = retained.some((line) => /^\s*-\s+/.test(line));
|
|
191
|
+
const replacement = hasListItem ? [lines[keyIndex] ?? "", ...retained] : [];
|
|
192
|
+
let next = [
|
|
193
|
+
...lines.slice(0, keyIndex),
|
|
194
|
+
...replacement,
|
|
195
|
+
...lines.slice(endIndex),
|
|
196
|
+
].join("\n");
|
|
197
|
+
if (raw.endsWith("\n") && !next.endsWith("\n"))
|
|
198
|
+
next += "\n";
|
|
199
|
+
if (next !== raw)
|
|
200
|
+
await atomicWrite(path, next);
|
|
201
|
+
}
|
|
202
|
+
async function normalizeEmptyPnpmRootImporter(workspaceRoot) {
|
|
203
|
+
const path = join(workspaceRoot, "pnpm-lock.yaml");
|
|
204
|
+
let raw;
|
|
205
|
+
try {
|
|
206
|
+
raw = await readFile(path, "utf8");
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
if (isMissingFile(error))
|
|
210
|
+
return;
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
213
|
+
const next = raw.replace("\nimporters:\n\n .: {}\n", "\nimporters:\n .: {}\n");
|
|
214
|
+
if (next !== raw)
|
|
215
|
+
await atomicWrite(path, next);
|
|
216
|
+
}
|
|
217
|
+
function stripYamlQuotes(value) {
|
|
218
|
+
if ((value.startsWith("'") && value.endsWith("'")) ||
|
|
219
|
+
(value.startsWith('"') && value.endsWith('"'))) {
|
|
220
|
+
return value.slice(1, -1);
|
|
221
|
+
}
|
|
222
|
+
return value;
|
|
223
|
+
}
|
|
151
224
|
function hasOwn(record, key) {
|
|
152
225
|
return record !== undefined && Object.hasOwn(record, key);
|
|
153
226
|
}
|
package/dist/src/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { readFile, rm } from "node:fs/promises";
|
|
2
|
+
import { readFile, rm, rmdir } from "node:fs/promises";
|
|
3
3
|
import { parseModuleDescriptor, } from "@tomflow/proflow-module-contract";
|
|
4
4
|
import { descriptor as platformCliDescriptor } from "../deployment/descriptor.js";
|
|
5
5
|
import { applyPlan } from "./apply/apply.js";
|
|
6
6
|
import { rebuildCurrentAssumptions } from "./apply/current.js";
|
|
7
|
-
import { createWorkspacePackageManagerDriver } from "./apply/driver.js";
|
|
7
|
+
import { cleanupWorkspacePackageManagerArtifacts, createWorkspacePackageManagerDriver, } from "./apply/driver.js";
|
|
8
8
|
import { acquireGlobalOperationLock, canonicalizeWorkspace, claimWorkspaceBinding, clearGlobalBinding, forgetMissingWorkspaceBinding, loadGlobalBinding, observeBoundWorkspace, requireBoundWorkspace, updateGlobalBindingState, } from "./binding/global-binding.js";
|
|
9
9
|
import { buildProductionBindings, importRawAdapter, } from "./binding/production-bindings.js";
|
|
10
10
|
import { AutoModuleCatalog, discoverModules } from "./discovery/discover.js";
|
|
@@ -845,10 +845,37 @@ async function handlePlatformInstanceUninstall(args, runtime) {
|
|
|
845
845
|
if (remaining.length > 0) {
|
|
846
846
|
throw new PlatformError("UNINSTALL_FAILED", `Platform Instance uninstall left managed modules: ${remaining.map((module) => module.moduleRef).join(", ")}`);
|
|
847
847
|
}
|
|
848
|
+
if (modules.length > 0) {
|
|
849
|
+
await cleanupWorkspacePackageManagerArtifacts({
|
|
850
|
+
workspaceRoot: binding.workspaceRealPath,
|
|
851
|
+
removedModules: modules,
|
|
852
|
+
});
|
|
853
|
+
}
|
|
848
854
|
// Deployment-owned plans/state/verification/instance identity must not leak
|
|
849
855
|
// into a future install of the same directory. Business/domain data outside
|
|
850
856
|
// `.proflow/deployment` is intentionally preserved.
|
|
851
857
|
await rm(ctx.paths.deployment, { recursive: true, force: true });
|
|
858
|
+
for (const path of [
|
|
859
|
+
ctx.paths.logsDeployment,
|
|
860
|
+
ctx.paths.logs,
|
|
861
|
+
ctx.paths.config,
|
|
862
|
+
ctx.paths.data,
|
|
863
|
+
ctx.paths.runtime,
|
|
864
|
+
ctx.paths.cache,
|
|
865
|
+
ctx.paths.tmp,
|
|
866
|
+
ctx.paths.proflow,
|
|
867
|
+
]) {
|
|
868
|
+
try {
|
|
869
|
+
await rmdir(path);
|
|
870
|
+
}
|
|
871
|
+
catch (error) {
|
|
872
|
+
const code = typeof error === "object" && error !== null
|
|
873
|
+
? Reflect.get(error, "code")
|
|
874
|
+
: undefined;
|
|
875
|
+
if (code !== "ENOENT" && code !== "ENOTEMPTY")
|
|
876
|
+
throw error;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
852
879
|
const completed = binding;
|
|
853
880
|
await clearGlobalBinding({
|
|
854
881
|
workspaceInstanceId: binding.workspaceInstanceId,
|
package/package.json
CHANGED
package/proflow.module.json
CHANGED