@tomflow/proflow-platform-cli 0.1.17 → 0.1.19
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 +13 -0
- package/SETUP.md +23 -3
- package/dist/deployment/adapter.d.ts +7 -7
- package/dist/deployment/descriptor.d.ts +1 -1
- package/dist/deployment/descriptor.js +1 -1
- package/dist/src/cli.js +60 -9
- package/dist/src/lifecycle/thin.js +14 -9
- package/package.json +4 -4
- package/proflow.module.json +1 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# @tomflow/proflow-platform-cli
|
|
2
|
+
|
|
3
|
+
## 0.1.19
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Preserve the complete platform setup guidance when machine failures and human actions are present together.
|
|
8
|
+
|
|
9
|
+
## 0.1.18
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Align all Modules to the seven-command setup contract with executable package-owned setup guidance and full Platform setup aggregation.
|
package/SETUP.md
CHANGED
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
# @tomflow/proflow-platform-cli — Module Setup
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The Platform CLI owns orchestration only. It never interprets another Module's setup details. Global `platform setup` traverses every discovered Module, skips `READY` Modules, lets each non-ready Module run its own package-owned setup workflow, and aggregates every remaining `ACTION_REQUIRED` or `FAILED` result in one response.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Step 1 — Verify the Platform CLI Module
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**Executable:**
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
platform setup --module platform-cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Success condition:**
|
|
14
|
+
|
|
15
|
+
`platform status` reports `platform-cli setup=READY`. No user/private path, token, loopback endpoint, or cross-Module fact is requested.
|
|
16
|
+
|
|
17
|
+
## Step 2 — Run the full workspace setup guide
|
|
18
|
+
|
|
19
|
+
**Executable:**
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
platform setup
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Success condition:**
|
|
26
|
+
|
|
27
|
+
All automatically solvable Module setup work is completed in the same run, and every remaining human/external action is listed together. Re-running the command re-observes reality and continues until all required Modules report `setupStatus=READY`.
|
|
@@ -6,7 +6,7 @@ export declare const behaviorAdapter: {
|
|
|
6
6
|
readonly ok: true;
|
|
7
7
|
readonly status: "SUCCEEDED";
|
|
8
8
|
readonly moduleRef: "platform-cli";
|
|
9
|
-
readonly moduleVersion: "0.1.
|
|
9
|
+
readonly moduleVersion: "0.1.19";
|
|
10
10
|
};
|
|
11
11
|
observedEffects: never[];
|
|
12
12
|
}>;
|
|
@@ -16,7 +16,7 @@ export declare const behaviorAdapter: {
|
|
|
16
16
|
readonly ok: true;
|
|
17
17
|
readonly status: "SUCCEEDED";
|
|
18
18
|
readonly moduleRef: "platform-cli";
|
|
19
|
-
readonly moduleVersion: "0.1.
|
|
19
|
+
readonly moduleVersion: "0.1.19";
|
|
20
20
|
};
|
|
21
21
|
observedEffects: never[];
|
|
22
22
|
}>;
|
|
@@ -26,7 +26,7 @@ export declare const behaviorAdapter: {
|
|
|
26
26
|
ok: true;
|
|
27
27
|
status: "SUCCEEDED";
|
|
28
28
|
moduleRef: "platform-cli";
|
|
29
|
-
moduleVersion: "0.1.
|
|
29
|
+
moduleVersion: "0.1.19";
|
|
30
30
|
data: {
|
|
31
31
|
readonly setupStatus: "READY";
|
|
32
32
|
readonly runtimeStatus: "NOT_APPLICABLE";
|
|
@@ -40,7 +40,7 @@ export declare const behaviorAdapter: {
|
|
|
40
40
|
readonly ok: true;
|
|
41
41
|
readonly status: "SUCCEEDED";
|
|
42
42
|
readonly moduleRef: "platform-cli";
|
|
43
|
-
readonly moduleVersion: "0.1.
|
|
43
|
+
readonly moduleVersion: "0.1.19";
|
|
44
44
|
};
|
|
45
45
|
observedEffects: never[];
|
|
46
46
|
}>;
|
|
@@ -50,7 +50,7 @@ export declare const behaviorAdapter: {
|
|
|
50
50
|
ok: true;
|
|
51
51
|
status: "SUCCEEDED";
|
|
52
52
|
moduleRef: "platform-cli";
|
|
53
|
-
moduleVersion: "0.1.
|
|
53
|
+
moduleVersion: "0.1.19";
|
|
54
54
|
data: {
|
|
55
55
|
docs: string;
|
|
56
56
|
setup: string;
|
|
@@ -64,7 +64,7 @@ export declare const behaviorAdapter: {
|
|
|
64
64
|
readonly ok: true;
|
|
65
65
|
readonly status: "SUCCEEDED";
|
|
66
66
|
readonly moduleRef: "platform-cli";
|
|
67
|
-
readonly moduleVersion: "0.1.
|
|
67
|
+
readonly moduleVersion: "0.1.19";
|
|
68
68
|
};
|
|
69
69
|
observedEffects: never[];
|
|
70
70
|
}>;
|
|
@@ -74,7 +74,7 @@ export declare const behaviorAdapter: {
|
|
|
74
74
|
readonly ok: true;
|
|
75
75
|
readonly status: "SUCCEEDED";
|
|
76
76
|
readonly moduleRef: "platform-cli";
|
|
77
|
-
readonly moduleVersion: "0.1.
|
|
77
|
+
readonly moduleVersion: "0.1.19";
|
|
78
78
|
};
|
|
79
79
|
observedEffects: never[];
|
|
80
80
|
}>;
|
|
@@ -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.19";
|
|
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.19",
|
|
7
7
|
kind: "cli",
|
|
8
8
|
templateVersion: "1.0.0",
|
|
9
9
|
platformCompatibility: ">=1.0.0 <2.0.0",
|
package/dist/src/cli.js
CHANGED
|
@@ -81,8 +81,6 @@ function parseArgs(argv) {
|
|
|
81
81
|
if (!COMMANDS.includes(raw))
|
|
82
82
|
throw new PlatformError("INVALID_REQUEST", `unknown command ${raw}`);
|
|
83
83
|
const command = raw;
|
|
84
|
-
if (workspace !== undefined && command !== "install")
|
|
85
|
-
throw new PlatformError("INVALID_REQUEST", "--workspace is only valid with install");
|
|
86
84
|
if ((moduleRef !== undefined || inputSeen) && command !== "setup")
|
|
87
85
|
throw new PlatformError("INVALID_REQUEST", "--module/--input are only valid with setup");
|
|
88
86
|
if (inputSeen && moduleRef === undefined)
|
|
@@ -137,7 +135,14 @@ function batchStatus(result) {
|
|
|
137
135
|
return result.blockedBy.setupStatus === "ACTION_REQUIRED"
|
|
138
136
|
? "ACTION_REQUIRED"
|
|
139
137
|
: "FAILED";
|
|
140
|
-
|
|
138
|
+
const statuses = result.results.map((item) => statusFromModule(item.result.status));
|
|
139
|
+
if (statuses.includes("FAILED"))
|
|
140
|
+
return "FAILED";
|
|
141
|
+
if (statuses.includes("BLOCKED"))
|
|
142
|
+
return "BLOCKED";
|
|
143
|
+
if (statuses.includes("ACTION_REQUIRED"))
|
|
144
|
+
return "ACTION_REQUIRED";
|
|
145
|
+
return "FAILED";
|
|
141
146
|
}
|
|
142
147
|
async function handleStatus(root) {
|
|
143
148
|
const { catalog, modules } = await buildContext(root);
|
|
@@ -312,10 +317,10 @@ async function handleStop(root) {
|
|
|
312
317
|
}
|
|
313
318
|
function helpOutcome() {
|
|
314
319
|
return outcome("help", "SUCCEEDED", undefined, {
|
|
315
|
-
usage: "platform <install|uninstall|status|setup|docs|start|stop> [--json]",
|
|
320
|
+
usage: "platform <install|uninstall|status|setup|docs|start|stop> [--workspace <path>] [--json]",
|
|
316
321
|
commands: [...COMMANDS],
|
|
317
322
|
install: "platform install [--workspace <path>]",
|
|
318
|
-
setup: "platform setup [--module <moduleRef> --input '<json>']",
|
|
323
|
+
setup: "platform setup [--workspace <path>] [--module <moduleRef> --input '<json>']",
|
|
319
324
|
});
|
|
320
325
|
}
|
|
321
326
|
export async function runCli(argv, runtime = {}) {
|
|
@@ -333,10 +338,7 @@ export async function runCli(argv, runtime = {}) {
|
|
|
333
338
|
return JSON.stringify(outcome("version", "SUCCEEDED", undefined, {
|
|
334
339
|
version: platformCliDescriptor.moduleVersion,
|
|
335
340
|
}));
|
|
336
|
-
const
|
|
337
|
-
const root = parsed.command === "install" && parsed.workspace !== undefined
|
|
338
|
-
? await canonicalWorkspace(cwd, parsed.workspace)
|
|
339
|
-
: cwd;
|
|
341
|
+
const root = await canonicalWorkspace(runtime.cwd ?? process.cwd(), parsed.workspace);
|
|
340
342
|
switch (parsed.command) {
|
|
341
343
|
case "install":
|
|
342
344
|
return JSON.stringify(await handleInstall(root, runtime));
|
|
@@ -395,7 +397,54 @@ function renderDocs(data) {
|
|
|
395
397
|
lines.push("", `## ${String(raw.moduleRef)} @ ${String(raw.version)}`, JSON.stringify(raw.docs ?? {}, null, 2));
|
|
396
398
|
return lines.join("\n");
|
|
397
399
|
}
|
|
400
|
+
function renderSetup(data) {
|
|
401
|
+
if (!isRecord(data) || !Array.isArray(data.results))
|
|
402
|
+
return "No setup actions are required.";
|
|
403
|
+
const lines = ["ProFlow Setup", ""];
|
|
404
|
+
let automatic = 0;
|
|
405
|
+
let pending = 0;
|
|
406
|
+
for (const raw of data.results) {
|
|
407
|
+
if (!isRecord(raw) || !isRecord(raw.result))
|
|
408
|
+
continue;
|
|
409
|
+
const moduleRef = String(raw.moduleRef ?? raw.result.moduleRef ?? "unknown");
|
|
410
|
+
const status = String(raw.result.status ?? "UNKNOWN");
|
|
411
|
+
if (status === "SUCCEEDED") {
|
|
412
|
+
automatic += 1;
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
pending += 1;
|
|
416
|
+
lines.push(`## ${moduleRef} — ${status}`);
|
|
417
|
+
const actionRequired = raw.result.actionRequired;
|
|
418
|
+
const error = raw.result.error;
|
|
419
|
+
if (isRecord(actionRequired)) {
|
|
420
|
+
if (actionRequired.action !== undefined)
|
|
421
|
+
lines.push(`Action: ${String(actionRequired.action)}`);
|
|
422
|
+
if (actionRequired.description !== undefined)
|
|
423
|
+
lines.push(String(actionRequired.description));
|
|
424
|
+
}
|
|
425
|
+
else if (isRecord(error)) {
|
|
426
|
+
const code = error.code === undefined ? "FAILED" : String(error.code);
|
|
427
|
+
const message = error.message === undefined
|
|
428
|
+
? "Module setup failed."
|
|
429
|
+
: String(error.message);
|
|
430
|
+
lines.push(`Error: ${code} — ${message}`);
|
|
431
|
+
}
|
|
432
|
+
else if (raw.result.data !== undefined) {
|
|
433
|
+
lines.push(JSON.stringify(raw.result.data, null, 2));
|
|
434
|
+
}
|
|
435
|
+
lines.push("");
|
|
436
|
+
}
|
|
437
|
+
if (pending === 0)
|
|
438
|
+
lines.push("All discovered Modules are setup-ready.");
|
|
439
|
+
if (automatic > 0)
|
|
440
|
+
lines.push(`Automatically completed in this run: ${automatic}`);
|
|
441
|
+
return lines.join("\n").trimEnd();
|
|
442
|
+
}
|
|
398
443
|
export function renderHumanResult(result) {
|
|
444
|
+
if (result.command === "setup" &&
|
|
445
|
+
isRecord(result.data) &&
|
|
446
|
+
Array.isArray(result.data.results))
|
|
447
|
+
return renderSetup(result.data);
|
|
399
448
|
if (result.status === "FAILED")
|
|
400
449
|
return `${result.command.toUpperCase()} FAILED${result.error ? ` [${result.error.code}] ${result.error.message}` : ""}`;
|
|
401
450
|
if (result.command === "help")
|
|
@@ -412,6 +461,8 @@ export function renderHumanResult(result) {
|
|
|
412
461
|
return String(result.data.version ?? platformCliDescriptor.moduleVersion);
|
|
413
462
|
if (result.command === "status")
|
|
414
463
|
return renderStatus(result.data);
|
|
464
|
+
if (result.command === "setup")
|
|
465
|
+
return renderSetup(result.data);
|
|
415
466
|
if (result.command === "docs")
|
|
416
467
|
return renderDocs(result.data);
|
|
417
468
|
return [
|
|
@@ -40,28 +40,33 @@ export const stopModulesThin = (catalog, modules, workspaceRoot) => runOrdered(c
|
|
|
40
40
|
export async function setupModulesThin(catalog, modules, workspaceRoot, target) {
|
|
41
41
|
const results = [];
|
|
42
42
|
let matched = target === undefined;
|
|
43
|
+
let completed = true;
|
|
43
44
|
for (const module of ordered(modules)) {
|
|
44
45
|
if (target !== undefined && module.moduleRef !== target.moduleRef)
|
|
45
46
|
continue;
|
|
46
47
|
matched = true;
|
|
47
48
|
const status = await dispatchModuleCommand(catalog, module, "status", context(workspaceRoot));
|
|
48
|
-
if (!succeeded(status.result))
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
if (!succeeded(status.result)) {
|
|
50
|
+
results.push(status);
|
|
51
|
+
completed = false;
|
|
52
|
+
if (target !== undefined)
|
|
53
|
+
break;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
54
56
|
const observed = moduleStatusObservationSchema.parse(status.result.data);
|
|
55
57
|
if (observed.setupStatus === "READY" && target?.input === undefined)
|
|
56
58
|
continue;
|
|
57
59
|
const setup = await dispatchModuleCommand(catalog, module, "setup", context(workspaceRoot, target?.input));
|
|
58
60
|
results.push(setup);
|
|
59
|
-
if (!succeeded(setup.result))
|
|
60
|
-
|
|
61
|
+
if (!succeeded(setup.result)) {
|
|
62
|
+
completed = false;
|
|
63
|
+
if (target !== undefined)
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
61
66
|
}
|
|
62
67
|
if (!matched)
|
|
63
68
|
throw new PlatformError("INVALID_REQUEST", `setup target module ${target?.moduleRef ?? ""} was not discovered`);
|
|
64
|
-
return { phase: "setup", results, completed
|
|
69
|
+
return { phase: "setup", results, completed };
|
|
65
70
|
}
|
|
66
71
|
export async function startModulesThin(catalog, modules, workspaceRoot) {
|
|
67
72
|
const results = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomflow/proflow-platform-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
"SETUP.md"
|
|
24
24
|
],
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@tomflow/proflow-module-contract": "^0.1.
|
|
26
|
+
"@tomflow/proflow-module-contract": "^0.1.5"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@tomflow/proflow-
|
|
30
|
-
"@tomflow/proflow-
|
|
29
|
+
"@tomflow/proflow-module-template": "^0.1.5",
|
|
30
|
+
"@tomflow/proflow-deployment-conformance": "^0.1.5"
|
|
31
31
|
},
|
|
32
32
|
"description": "Thin Platform CLI for Module discovery, documentation, package synchronization and lifecycle orchestration.",
|
|
33
33
|
"keywords": [
|
package/proflow.module.json
CHANGED