@tomflow/proflow-platform-cli 0.1.13 → 0.1.15

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.
Files changed (142) hide show
  1. package/README.md +48 -43
  2. package/dist/deployment/adapter.d.ts +5 -5
  3. package/dist/deployment/adapter.js +2 -1
  4. package/dist/deployment/descriptor.d.ts +2 -3
  5. package/dist/deployment/descriptor.js +2 -3
  6. package/dist/src/binding/production-bindings.d.ts +17 -15
  7. package/dist/src/binding/production-bindings.js +18 -59
  8. package/dist/src/cli.d.ts +7 -9
  9. package/dist/src/cli.js +329 -1237
  10. package/dist/src/contracts.d.ts +4 -97
  11. package/dist/src/discovery/discover.js +0 -1
  12. package/dist/src/docs/aggregate.d.ts +18 -0
  13. package/dist/src/docs/aggregate.js +44 -0
  14. package/dist/src/docs/docs.d.ts +0 -31
  15. package/dist/src/docs/docs.js +0 -61
  16. package/dist/src/docs/index.d.ts +2 -1
  17. package/dist/src/docs/index.js +1 -1
  18. package/dist/src/errors.d.ts +1 -1
  19. package/dist/src/errors.js +0 -18
  20. package/dist/src/graph/graph.d.ts +1 -4
  21. package/dist/src/graph/graph.js +1 -13
  22. package/dist/src/graph/index.d.ts +2 -2
  23. package/dist/src/graph/index.js +1 -1
  24. package/dist/src/index.d.ts +4 -24
  25. package/dist/src/index.js +2 -16
  26. package/dist/src/install/package-manager.d.ts +21 -0
  27. package/dist/src/install/package-manager.js +153 -0
  28. package/dist/src/lifecycle/dispatch.d.ts +0 -30
  29. package/dist/src/lifecycle/dispatch.js +0 -120
  30. package/dist/src/lifecycle/index.d.ts +4 -3
  31. package/dist/src/lifecycle/index.js +2 -2
  32. package/dist/src/lifecycle/thin.d.ts +11 -0
  33. package/dist/src/lifecycle/thin.js +68 -0
  34. package/dist/src/paths.d.ts +0 -14
  35. package/dist/src/paths.js +0 -39
  36. package/dist/src/persistence/config.d.ts +0 -6
  37. package/dist/src/persistence/config.js +0 -14
  38. package/dist/src/persistence/guards.d.ts +0 -6
  39. package/dist/src/persistence/guards.js +0 -114
  40. package/dist/src/persistence/index.d.ts +4 -6
  41. package/dist/src/persistence/index.js +2 -5
  42. package/dist/src/persistence/workspace-metadata.d.ts +7 -0
  43. package/dist/src/persistence/workspace-metadata.js +39 -0
  44. package/dist/src/registry/index.d.ts +1 -1
  45. package/dist/src/registry/index.js +1 -1
  46. package/dist/src/registry/npm-registry.d.ts +0 -14
  47. package/dist/src/registry/npm-registry.js +1 -132
  48. package/package.json +2 -6
  49. package/proflow.module.json +2 -3
  50. package/CHANGELOG.md +0 -79
  51. package/dist/src/apply/apply.d.ts +0 -26
  52. package/dist/src/apply/apply.js +0 -314
  53. package/dist/src/apply/cleanup.d.ts +0 -12
  54. package/dist/src/apply/cleanup.js +0 -37
  55. package/dist/src/apply/current.d.ts +0 -5
  56. package/dist/src/apply/current.js +0 -95
  57. package/dist/src/apply/driver.d.ts +0 -28
  58. package/dist/src/apply/driver.js +0 -239
  59. package/dist/src/apply/execute.d.ts +0 -36
  60. package/dist/src/apply/execute.js +0 -152
  61. package/dist/src/apply/index.d.ts +0 -8
  62. package/dist/src/apply/index.js +0 -4
  63. package/dist/src/apply/reality.d.ts +0 -20
  64. package/dist/src/apply/reality.js +0 -105
  65. package/dist/src/binding/global-binding.d.ts +0 -69
  66. package/dist/src/binding/global-binding.js +0 -349
  67. package/dist/src/doctor/doctor.d.ts +0 -41
  68. package/dist/src/doctor/doctor.js +0 -80
  69. package/dist/src/doctor/index.d.ts +0 -2
  70. package/dist/src/doctor/index.js +0 -1
  71. package/dist/src/install/bootstrap.d.ts +0 -10
  72. package/dist/src/install/bootstrap.js +0 -79
  73. package/dist/src/install/environment.d.ts +0 -30
  74. package/dist/src/install/environment.js +0 -230
  75. package/dist/src/install/index.d.ts +0 -6
  76. package/dist/src/install/index.js +0 -3
  77. package/dist/src/install/install.d.ts +0 -19
  78. package/dist/src/install/install.js +0 -172
  79. package/dist/src/lifecycle/service-process.d.ts +0 -11
  80. package/dist/src/lifecycle/service-process.js +0 -356
  81. package/dist/src/manifest/index.d.ts +0 -2
  82. package/dist/src/manifest/index.js +0 -1
  83. package/dist/src/manifest/manifest.d.ts +0 -61
  84. package/dist/src/manifest/manifest.js +0 -167
  85. package/dist/src/observer/deployment-summary.d.ts +0 -31
  86. package/dist/src/observer/deployment-summary.js +0 -34
  87. package/dist/src/persistence/atomic.d.ts +0 -2
  88. package/dist/src/persistence/atomic.js +0 -16
  89. package/dist/src/persistence/effective-config.d.ts +0 -3
  90. package/dist/src/persistence/effective-config.js +0 -20
  91. package/dist/src/persistence/generated.d.ts +0 -2
  92. package/dist/src/persistence/generated.js +0 -4
  93. package/dist/src/persistence/plans.d.ts +0 -5
  94. package/dist/src/persistence/plans.js +0 -34
  95. package/dist/src/persistence/state.d.ts +0 -7
  96. package/dist/src/persistence/state.js +0 -34
  97. package/dist/src/persistence/verification.d.ts +0 -5
  98. package/dist/src/persistence/verification.js +0 -47
  99. package/dist/src/planner/assemble.d.ts +0 -16
  100. package/dist/src/planner/assemble.js +0 -107
  101. package/dist/src/planner/check.d.ts +0 -20
  102. package/dist/src/planner/check.js +0 -107
  103. package/dist/src/planner/fingerprint.d.ts +0 -12
  104. package/dist/src/planner/fingerprint.js +0 -164
  105. package/dist/src/planner/index.d.ts +0 -13
  106. package/dist/src/planner/index.js +0 -7
  107. package/dist/src/planner/plan.d.ts +0 -15
  108. package/dist/src/planner/plan.js +0 -144
  109. package/dist/src/planner/repair.d.ts +0 -28
  110. package/dist/src/planner/repair.js +0 -131
  111. package/dist/src/planner/stale.d.ts +0 -7
  112. package/dist/src/planner/stale.js +0 -23
  113. package/dist/src/planner/steps.d.ts +0 -37
  114. package/dist/src/planner/steps.js +0 -165
  115. package/dist/src/planner/target-catalog.d.ts +0 -13
  116. package/dist/src/planner/target-catalog.js +0 -48
  117. package/dist/src/planner/upgrade.d.ts +0 -18
  118. package/dist/src/planner/upgrade.js +0 -114
  119. package/dist/src/preflight/config.d.ts +0 -11
  120. package/dist/src/preflight/config.js +0 -88
  121. package/dist/src/preflight/findings.d.ts +0 -26
  122. package/dist/src/preflight/findings.js +0 -1
  123. package/dist/src/preflight/index.d.ts +0 -7
  124. package/dist/src/preflight/index.js +0 -3
  125. package/dist/src/preflight/preflight.d.ts +0 -10
  126. package/dist/src/preflight/preflight.js +0 -190
  127. package/dist/src/preflight/requirements.d.ts +0 -11
  128. package/dist/src/preflight/requirements.js +0 -231
  129. package/dist/src/ready/index.d.ts +0 -2
  130. package/dist/src/ready/index.js +0 -1
  131. package/dist/src/ready/ready.d.ts +0 -40
  132. package/dist/src/ready/ready.js +0 -201
  133. package/dist/src/security/index.d.ts +0 -3
  134. package/dist/src/security/index.js +0 -2
  135. package/dist/src/security/lock.d.ts +0 -9
  136. package/dist/src/security/lock.js +0 -127
  137. package/dist/src/security/redact.d.ts +0 -6
  138. package/dist/src/security/redact.js +0 -48
  139. package/dist/src/verification/index.d.ts +0 -2
  140. package/dist/src/verification/index.js +0 -1
  141. package/dist/src/verification/verify.d.ts +0 -33
  142. package/dist/src/verification/verify.js +0 -114
@@ -1,144 +0,0 @@
1
- import { PlatformError } from "../errors.js";
2
- import { buildDependencyGraph } from "../graph/graph.js";
3
- import { assemblePlan } from "./assemble.js";
4
- import { planRepair } from "./repair.js";
5
- import { configStep, createSequencer, externalResourceStep, humanActionsFromModules, humanStep, lifecycleStep, packageStep, upstreamDependencies, } from "./steps.js";
6
- import { planUpgrade } from "./upgrade.js";
7
- export function planDeployment(input) {
8
- switch (input.intent) {
9
- case "upgrade":
10
- return input.modules?.every((module) => module.source.type === "registry")
11
- ? planRegistryPackageUpgrade(input)
12
- : planUpgrade(input);
13
- case "repair":
14
- return planRepair(input);
15
- case "uninstall":
16
- return planUninstall(input);
17
- case "install":
18
- case "configure":
19
- return planInstallOrConfigure(input);
20
- }
21
- }
22
- function planRegistryPackageUpgrade(input) {
23
- const modules = input.modules;
24
- if (modules === undefined) {
25
- throw new PlatformError("INVALID_REQUEST", "registry-backed upgrade requires modules");
26
- }
27
- const graph = buildDependencyGraph(modules);
28
- const byRef = new Map(modules.map((module) => [module.moduleRef, module]));
29
- const seq = createSequencer();
30
- const steps = [];
31
- for (const ref of graph.order) {
32
- const module = byRef.get(ref);
33
- if (module === undefined)
34
- continue;
35
- steps.push(packageStep(seq, module, "upgrade", []));
36
- }
37
- return assemblePlan({
38
- intent: "upgrade",
39
- modules,
40
- targets: input.targets ?? [],
41
- config: undefined,
42
- steps,
43
- humanActions: [],
44
- now: input.now ?? new Date(),
45
- });
46
- }
47
- function planInstallOrConfigure(input) {
48
- const modules = input.modules;
49
- if (modules === undefined) {
50
- throw new PlatformError("INVALID_REQUEST", `${input.intent} requires modules`);
51
- }
52
- const graph = buildDependencyGraph(modules);
53
- const steps = input.intent === "install"
54
- ? installSteps(modules, graph)
55
- : configureSteps(modules, graph, input.targets ?? [], input.config);
56
- return assemblePlan({
57
- intent: input.intent,
58
- modules,
59
- targets: input.targets ?? [],
60
- config: input.config,
61
- steps,
62
- humanActions: input.intent === "install" ? humanActionsFromModules(modules) : [],
63
- now: input.now ?? new Date(),
64
- });
65
- }
66
- function installSteps(modules, graph) {
67
- const seq = createSequencer();
68
- const deps = upstreamDependencies(graph);
69
- const byRef = new Map(modules.map((module) => [module.moduleRef, module]));
70
- const steps = [];
71
- for (const ref of graph.order) {
72
- const module = byRef.get(ref);
73
- if (module === undefined)
74
- continue;
75
- const dependencies = deps.get(ref) ?? [];
76
- steps.push(packageStep(seq, module, "install", dependencies));
77
- if (module.configSlots.length > 0) {
78
- steps.push(configStep(seq, module));
79
- }
80
- if (module.kind === "external-resource") {
81
- const step = externalResourceStep(seq, module);
82
- if (step !== undefined)
83
- steps.push(step);
84
- }
85
- for (const requirement of module.requirements) {
86
- if (requirement.kind === "human") {
87
- steps.push(humanStep(seq, module, requirement.action));
88
- }
89
- }
90
- }
91
- return steps;
92
- }
93
- function configureSteps(modules, graph, targets, config) {
94
- const seq = createSequencer();
95
- const byRef = new Map(modules.map((module) => [module.moduleRef, module]));
96
- const targetByRef = new Map(targets.map((target) => [target.moduleRef, target]));
97
- const steps = [];
98
- for (const ref of graph.order) {
99
- const module = byRef.get(ref);
100
- if (module === undefined || module.configSlots.length === 0)
101
- continue;
102
- const explicitConfig = targetByRef.get(ref)?.config;
103
- const providedConfig = config?.[ref];
104
- const hasMaterializationTarget = (explicitConfig !== undefined &&
105
- Object.keys(explicitConfig).length > 0) ||
106
- (providedConfig !== undefined && Object.keys(providedConfig).length > 0);
107
- if (!hasMaterializationTarget)
108
- continue;
109
- steps.push(configStep(seq, module));
110
- }
111
- return steps;
112
- }
113
- function planUninstall(input) {
114
- const modules = input.modules;
115
- if (modules === undefined || modules.length === 0) {
116
- throw new PlatformError("INVALID_REQUEST", "uninstall requires modules");
117
- }
118
- const core = modules.find((module) => module.installClass === "core");
119
- if (core !== undefined && input.uninstallScope !== "platform-instance") {
120
- throw new PlatformError("CORE_PACKAGE_REQUIRED", `core module ${core.moduleRef} cannot be individually uninstalled`);
121
- }
122
- const graph = buildDependencyGraph(modules);
123
- const byRef = new Map(modules.map((module) => [module.moduleRef, module]));
124
- const seq = createSequencer();
125
- const steps = [];
126
- for (const ref of [...graph.order].reverse()) {
127
- const module = byRef.get(ref);
128
- if (module === undefined)
129
- continue;
130
- if (module.lifecycle.includes("uninstall")) {
131
- steps.push(lifecycleStep(seq, module, "uninstall"));
132
- }
133
- steps.push(packageStep(seq, module, "remove", []));
134
- }
135
- return assemblePlan({
136
- intent: "uninstall",
137
- modules,
138
- targets: input.targets ?? [],
139
- config: undefined,
140
- steps,
141
- humanActions: [],
142
- now: input.now ?? new Date(),
143
- });
144
- }
@@ -1,28 +0,0 @@
1
- import type { DeploymentPlan, ModuleTarget, ResolvedModule } from "../contracts.ts";
2
- import type { DoctorReport } from "../doctor/doctor.ts";
3
- export declare const repairFactCodes: readonly ["CONFIG_MISSING", "LIFECYCLE_NOT_RUNNING", "VERIFY_FAILED", "EXTERNAL_RESOURCE_UNAVAILABLE", "ACTION_REQUIRED", "DEPENDENCY_UNRESOLVED"];
4
- export type RepairFactCode = (typeof repairFactCodes)[number];
5
- export interface RepairFact {
6
- moduleRef: string;
7
- code: RepairFactCode;
8
- message: string;
9
- }
10
- export interface RepairPlanInput {
11
- modules?: readonly ResolvedModule[];
12
- targets?: readonly ModuleTarget[];
13
- config?: Record<string, Record<string, string>>;
14
- facts?: readonly RepairFact[];
15
- now?: Date;
16
- }
17
- export interface RepairBlockedReason {
18
- moduleRef: string;
19
- code: string;
20
- message: string;
21
- }
22
- export interface RepairDiagnosis {
23
- facts: RepairFact[];
24
- blocked: RepairBlockedReason[];
25
- }
26
- export declare function repairFactsFromDoctor(report: DoctorReport): RepairDiagnosis;
27
- export declare function diagnoseRepair(reports: readonly DoctorReport[]): RepairDiagnosis;
28
- export declare function planRepair(input: RepairPlanInput): DeploymentPlan;
@@ -1,131 +0,0 @@
1
- import { PlatformError } from "../errors.js";
2
- import { assemblePlan } from "./assemble.js";
3
- import { configStep, createSequencer, externalResourceStep, humanStep, lifecycleStep, } from "./steps.js";
4
- export const repairFactCodes = [
5
- "CONFIG_MISSING",
6
- "LIFECYCLE_NOT_RUNNING",
7
- "VERIFY_FAILED",
8
- "EXTERNAL_RESOURCE_UNAVAILABLE",
9
- "ACTION_REQUIRED",
10
- "DEPENDENCY_UNRESOLVED",
11
- ];
12
- // Frozen error codes that carry an automatic repair mapping. Everything else
13
- // is left BLOCKED for human review rather than inventing a mutation.
14
- const ERROR_CODE_TO_FACT = {
15
- CONFIG_REQUIRED: "CONFIG_MISSING",
16
- DEPENDENCY_UNRESOLVED: "DEPENDENCY_UNRESOLVED",
17
- EXTERNAL_RESOURCE_UNAVAILABLE: "EXTERNAL_RESOURCE_UNAVAILABLE",
18
- VERIFY_FAILED: "VERIFY_FAILED",
19
- };
20
- export function repairFactsFromDoctor(report) {
21
- const facts = [];
22
- const blocked = [];
23
- if (report.nextAction.kind === "human-action") {
24
- facts.push({
25
- moduleRef: report.moduleRef,
26
- code: "ACTION_REQUIRED",
27
- message: report.nextAction.action,
28
- });
29
- return { facts, blocked };
30
- }
31
- if (report.status === "SUCCEEDED") {
32
- return { facts, blocked };
33
- }
34
- if (report.errors.length === 0) {
35
- blocked.push({
36
- moduleRef: report.moduleRef,
37
- code: report.status,
38
- message: `module ${report.moduleRef} is ${report.status.toLowerCase()} with no typed error`,
39
- });
40
- return { facts, blocked };
41
- }
42
- for (const error of report.errors) {
43
- const factCode = ERROR_CODE_TO_FACT[error.code];
44
- if (factCode === undefined) {
45
- blocked.push({
46
- moduleRef: report.moduleRef,
47
- code: error.code,
48
- message: error.message,
49
- });
50
- continue;
51
- }
52
- facts.push({
53
- moduleRef: report.moduleRef,
54
- code: factCode,
55
- message: error.message,
56
- });
57
- }
58
- return { facts, blocked };
59
- }
60
- export function diagnoseRepair(reports) {
61
- const facts = [];
62
- const blocked = [];
63
- for (const report of reports) {
64
- const diagnosis = repairFactsFromDoctor(report);
65
- facts.push(...diagnosis.facts);
66
- blocked.push(...diagnosis.blocked);
67
- }
68
- return { facts, blocked };
69
- }
70
- export function planRepair(input) {
71
- const modules = input.modules;
72
- if (modules === undefined) {
73
- throw new PlatformError("INVALID_REQUEST", "repair requires modules");
74
- }
75
- const facts = input.facts ?? [];
76
- const byRef = new Map(modules.map((module) => [module.moduleRef, module]));
77
- const seq = createSequencer();
78
- const steps = [];
79
- const humanActions = [];
80
- const seen = new Set();
81
- for (const fact of facts) {
82
- const module = byRef.get(fact.moduleRef);
83
- if (module === undefined)
84
- continue;
85
- const dedupeKey = `${fact.moduleRef}|${fact.code}`;
86
- if (seen.has(dedupeKey))
87
- continue;
88
- seen.add(dedupeKey);
89
- switch (fact.code) {
90
- case "CONFIG_MISSING":
91
- if (module.configSlots.length > 0) {
92
- steps.push(configStep(seq, module));
93
- }
94
- break;
95
- case "LIFECYCLE_NOT_RUNNING":
96
- if (module.lifecycle.includes("start")) {
97
- steps.push(lifecycleStep(seq, module, "start"));
98
- }
99
- break;
100
- case "EXTERNAL_RESOURCE_UNAVAILABLE":
101
- if (module.kind === "external-resource") {
102
- const step = externalResourceStep(seq, module);
103
- if (step !== undefined)
104
- steps.push(step);
105
- }
106
- break;
107
- case "ACTION_REQUIRED":
108
- steps.push(humanStep(seq, module, fact.message));
109
- humanActions.push({
110
- action: fact.message,
111
- description: `action required for ${module.moduleRef}`,
112
- });
113
- break;
114
- case "VERIFY_FAILED":
115
- // Verification re-runs after repair; no mutation is invented here.
116
- break;
117
- case "DEPENDENCY_UNRESOLVED":
118
- // Resolution requires a plan/human decision; no mutation is invented.
119
- break;
120
- }
121
- }
122
- return assemblePlan({
123
- intent: "repair",
124
- modules,
125
- targets: input.targets ?? [],
126
- config: input.config,
127
- steps,
128
- humanActions,
129
- now: input.now ?? new Date(),
130
- });
131
- }
@@ -1,7 +0,0 @@
1
- import type { DeploymentPlan } from "../contracts.ts";
2
- import { type PlanInput } from "./plan.ts";
3
- export interface StalenessResult {
4
- stale: boolean;
5
- reasons: string[];
6
- }
7
- export declare function checkPlanStale(plan: DeploymentPlan, current: PlanInput): StalenessResult;
@@ -1,23 +0,0 @@
1
- import { buildFingerprintSource } from "./fingerprint.js";
2
- import { planDeployment } from "./plan.js";
3
- const COMPARED_FIELDS = [
4
- "intent",
5
- "targets",
6
- "modules",
7
- "steps",
8
- "effects",
9
- "humanActions",
10
- "verification",
11
- ];
12
- export function checkPlanStale(plan, current) {
13
- const fresh = planDeployment(current);
14
- const before = buildFingerprintSource(plan);
15
- const after = buildFingerprintSource(fresh);
16
- const reasons = [];
17
- for (const field of COMPARED_FIELDS) {
18
- if (before[field] !== after[field]) {
19
- reasons.push(`${field} changed`);
20
- }
21
- }
22
- return { stale: reasons.length > 0, reasons };
23
- }
@@ -1,37 +0,0 @@
1
- import type { HumanAction } from "@tomflow/proflow-module-contract";
2
- import type { DeploymentStep, ResolvedModule } from "../contracts.ts";
3
- import type { DependencyGraph } from "../graph/graph.ts";
4
- export declare const CheckStrategy: {
5
- readonly packageInstalled: "package:installed";
6
- readonly packageAbsent: "package:absent";
7
- readonly configMaterialized: "config:materialized";
8
- readonly lifecycleRunning: "lifecycle:running";
9
- readonly lifecycleStopped: "lifecycle:stopped";
10
- readonly externalResourceConfigured: "external-resource:configured";
11
- readonly humanVerified: "human:verified";
12
- readonly verifyChecksPass: "verify:checks-pass";
13
- readonly migrateComplete: "migrate:complete";
14
- };
15
- export declare const ExecuteStrategy: {
16
- readonly packageInstall: "package:install";
17
- readonly packageUpgrade: "package:upgrade";
18
- readonly packageRemove: "package:remove";
19
- readonly configWrite: "config:write";
20
- readonly lifecycleStart: "lifecycle:start";
21
- readonly lifecycleStop: "lifecycle:stop";
22
- readonly lifecycleRestart: "lifecycle:restart";
23
- readonly lifecycleUninstall: "lifecycle:uninstall";
24
- readonly lifecycleMigrate: "lifecycle:migrate";
25
- readonly externalResourceConfigure: "external-resource:configure";
26
- };
27
- export interface StepSequencer {
28
- next(kind: string, moduleRef: string): string;
29
- }
30
- export declare function createSequencer(): StepSequencer;
31
- export declare function upstreamDependencies(graph: DependencyGraph): Map<string, string[]>;
32
- export declare function packageStep(seq: StepSequencer, module: ResolvedModule, verb: "install" | "upgrade" | "remove", dependencies: readonly string[]): DeploymentStep;
33
- export declare function configStep(seq: StepSequencer, module: ResolvedModule): DeploymentStep;
34
- export declare function externalResourceStep(seq: StepSequencer, module: ResolvedModule): DeploymentStep | undefined;
35
- export declare function humanStep(seq: StepSequencer, module: ResolvedModule, action: string): DeploymentStep;
36
- export declare function lifecycleStep(seq: StepSequencer, module: ResolvedModule, action: "start" | "stop" | "restart" | "migrate" | "uninstall"): DeploymentStep;
37
- export declare function humanActionsFromModules(modules: readonly ResolvedModule[]): HumanAction[];
@@ -1,165 +0,0 @@
1
- export const CheckStrategy = {
2
- packageInstalled: "package:installed",
3
- packageAbsent: "package:absent",
4
- configMaterialized: "config:materialized",
5
- lifecycleRunning: "lifecycle:running",
6
- lifecycleStopped: "lifecycle:stopped",
7
- externalResourceConfigured: "external-resource:configured",
8
- humanVerified: "human:verified",
9
- verifyChecksPass: "verify:checks-pass",
10
- migrateComplete: "migrate:complete",
11
- };
12
- export const ExecuteStrategy = {
13
- packageInstall: "package:install",
14
- packageUpgrade: "package:upgrade",
15
- packageRemove: "package:remove",
16
- configWrite: "config:write",
17
- lifecycleStart: "lifecycle:start",
18
- lifecycleStop: "lifecycle:stop",
19
- lifecycleRestart: "lifecycle:restart",
20
- lifecycleUninstall: "lifecycle:uninstall",
21
- lifecycleMigrate: "lifecycle:migrate",
22
- externalResourceConfigure: "external-resource:configure",
23
- };
24
- export function createSequencer() {
25
- let counter = 0;
26
- return {
27
- next(kind, moduleRef) {
28
- counter += 1;
29
- return `step-${String(counter).padStart(3, "0")}-${kind}-${moduleRef}`;
30
- },
31
- };
32
- }
33
- function compareRef(a, b) {
34
- return a < b ? -1 : a > b ? 1 : 0;
35
- }
36
- export function upstreamDependencies(graph) {
37
- const map = new Map();
38
- for (const edge of graph.edges) {
39
- const list = map.get(edge.from) ?? [];
40
- list.push(edge.to);
41
- map.set(edge.from, list);
42
- }
43
- for (const list of map.values())
44
- list.sort(compareRef);
45
- return map;
46
- }
47
- export function packageStep(seq, module, verb, dependencies) {
48
- const removing = verb === "remove";
49
- return {
50
- stepRef: seq.next("package", module.moduleRef),
51
- moduleRef: module.moduleRef,
52
- kind: "package",
53
- preconditions: removing
54
- ? []
55
- : dependencies.map((dependency) => `dependency ${dependency} installed and verified`),
56
- expectedEffect: removing
57
- ? `module package ${module.packageName}@${module.moduleVersion} removed`
58
- : `module package ${module.packageName}@${module.moduleVersion} ${verb === "install" ? "installed" : "upgraded"}`,
59
- checkStrategy: removing
60
- ? CheckStrategy.packageAbsent
61
- : CheckStrategy.packageInstalled,
62
- executeStrategy: removing
63
- ? ExecuteStrategy.packageRemove
64
- : verb === "install"
65
- ? ExecuteStrategy.packageInstall
66
- : ExecuteStrategy.packageUpgrade,
67
- postcondition: removing
68
- ? `package ${module.packageName} is absent from the Workspace installation`
69
- : `installed version ${module.moduleVersion} satisfies ${module.moduleRef}`,
70
- };
71
- }
72
- export function configStep(seq, module) {
73
- return {
74
- stepRef: seq.next("config", module.moduleRef),
75
- moduleRef: module.moduleRef,
76
- kind: "config",
77
- preconditions: [`module package ${module.packageName} installed`],
78
- expectedEffect: `configuration materialized for ${module.moduleRef}`,
79
- checkStrategy: CheckStrategy.configMaterialized,
80
- executeStrategy: ExecuteStrategy.configWrite,
81
- postcondition: `all required config slots materialized for ${module.moduleRef}`,
82
- };
83
- }
84
- export function externalResourceStep(seq, module) {
85
- if (!module.lifecycle.includes("start")) {
86
- // Status/verify-only external resources (e.g. chatgpt-carrier,
87
- // chrome-runtime, model-provider-api) have no activation primitive.
88
- // Their configuration is satisfied by config + human prerequisite +
89
- // verification steps, never by a forged `start` mutation.
90
- return undefined;
91
- }
92
- return {
93
- stepRef: seq.next("external-resource", module.moduleRef),
94
- moduleRef: module.moduleRef,
95
- kind: "external-resource",
96
- preconditions: [
97
- `module package ${module.packageName} installed`,
98
- `configuration materialized for ${module.moduleRef}`,
99
- ],
100
- expectedEffect: `external resource ${module.moduleRef} configured`,
101
- checkStrategy: CheckStrategy.externalResourceConfigured,
102
- executeStrategy: ExecuteStrategy.externalResourceConfigure,
103
- postcondition: `external resource ${module.moduleRef} configured and reachable`,
104
- };
105
- }
106
- export function humanStep(seq, module, action) {
107
- return {
108
- stepRef: seq.next("human", module.moduleRef),
109
- moduleRef: module.moduleRef,
110
- kind: "human",
111
- preconditions: [],
112
- expectedEffect: `human action completed: ${action}`,
113
- checkStrategy: CheckStrategy.humanVerified,
114
- postcondition: `human action "${action}" verified`,
115
- };
116
- }
117
- export function lifecycleStep(seq, module, action) {
118
- const executeStrategy = action === "start"
119
- ? ExecuteStrategy.lifecycleStart
120
- : action === "stop"
121
- ? ExecuteStrategy.lifecycleStop
122
- : action === "restart"
123
- ? ExecuteStrategy.lifecycleRestart
124
- : action === "uninstall"
125
- ? ExecuteStrategy.lifecycleUninstall
126
- : ExecuteStrategy.lifecycleMigrate;
127
- const checkStrategy = action === "migrate"
128
- ? CheckStrategy.migrateComplete
129
- : action === "stop" || action === "uninstall"
130
- ? CheckStrategy.lifecycleStopped
131
- : CheckStrategy.lifecycleRunning;
132
- const settled = action === "start" || action === "restart"
133
- ? "running"
134
- : action === "stop" || action === "uninstall"
135
- ? "stopped"
136
- : "migrated";
137
- return {
138
- stepRef: seq.next("lifecycle", module.moduleRef),
139
- moduleRef: module.moduleRef,
140
- kind: "lifecycle",
141
- preconditions: [],
142
- expectedEffect: `lifecycle ${action} completed for ${module.moduleRef}`,
143
- checkStrategy,
144
- executeStrategy,
145
- postcondition: `module ${module.moduleRef} is ${settled}`,
146
- };
147
- }
148
- export function humanActionsFromModules(modules) {
149
- const actions = [];
150
- const seen = new Set();
151
- for (const module of modules) {
152
- for (const requirement of module.requirements) {
153
- if (requirement.kind !== "human")
154
- continue;
155
- if (seen.has(requirement.action))
156
- continue;
157
- seen.add(requirement.action);
158
- actions.push({
159
- action: requirement.action,
160
- description: `human requirement for ${module.moduleRef}`,
161
- });
162
- }
163
- }
164
- return actions;
165
- }
@@ -1,13 +0,0 @@
1
- import { type ModuleDescriptor } from "@tomflow/proflow-module-contract";
2
- /**
3
- * A local target catalog resolved from a real target workspace on disk. Every
4
- * descriptor is loaded from that workspace's actual `deployment/descriptor`
5
- * artifacts (workspace packages win over declared installed dependencies). It
6
- * never performs registry/npm "world" discovery and never fabricates a
7
- * descriptor from a bare targetVersion string.
8
- */
9
- export interface TargetCatalog {
10
- root: string;
11
- descriptors: ModuleDescriptor[];
12
- }
13
- export declare function resolveTargetCatalog(targetWorkspace: string): Promise<TargetCatalog>;
@@ -1,48 +0,0 @@
1
- import { parseModuleDescriptor, } from "@tomflow/proflow-module-contract";
2
- import { AutoModuleCatalog } from "../discovery/discover.js";
3
- import { readPackageJson } from "../discovery/workspace.js";
4
- import { PlatformError } from "../errors.js";
5
- export async function resolveTargetCatalog(targetWorkspace) {
6
- const catalog = new AutoModuleCatalog(targetWorkspace);
7
- const sources = await catalog.sources();
8
- const descriptors = [];
9
- const seen = new Set();
10
- for (const source of sources) {
11
- const descriptor = await loadTargetDescriptor(catalog, source);
12
- if (seen.has(descriptor.moduleRef)) {
13
- throw new PlatformError("DUPLICATE_IDENTITY", `duplicate moduleRef "${descriptor.moduleRef}" in target workspace ${targetWorkspace}`);
14
- }
15
- seen.add(descriptor.moduleRef);
16
- descriptors.push(descriptor);
17
- }
18
- return { root: targetWorkspace, descriptors };
19
- }
20
- async function loadTargetDescriptor(catalog, source) {
21
- let raw;
22
- try {
23
- raw = await catalog.loadDescriptor(source);
24
- }
25
- catch (error) {
26
- if (error instanceof PlatformError)
27
- throw error;
28
- throw new PlatformError("DESCRIPTOR_INVALID", `failed to load target descriptor for ${source.packageName}: ${errorMessage(error)}`);
29
- }
30
- let descriptor;
31
- try {
32
- descriptor = parseModuleDescriptor(raw);
33
- }
34
- catch (error) {
35
- throw new PlatformError("DESCRIPTOR_INVALID", `invalid target descriptor for ${source.packageName}: ${errorMessage(error)}`);
36
- }
37
- if (source.type === "workspace" && source.path !== undefined) {
38
- const packageJson = await readPackageJson(source.path);
39
- if (packageJson.version !== undefined &&
40
- packageJson.version !== descriptor.moduleVersion) {
41
- throw new PlatformError("DESCRIPTOR_INVALID", `moduleVersion ${descriptor.moduleVersion} does not match package.json version ${packageJson.version} for ${descriptor.moduleRef}`);
42
- }
43
- }
44
- return descriptor;
45
- }
46
- function errorMessage(error) {
47
- return error instanceof Error ? error.message : String(error);
48
- }
@@ -1,18 +0,0 @@
1
- import { type ModuleDescriptor } from "@tomflow/proflow-module-contract";
2
- import type { DeploymentPlan } from "../contracts.ts";
3
- import type { PlanInput } from "./plan.ts";
4
- export interface UpgradeAssessment {
5
- compatible: boolean;
6
- breakingChanges: string[];
7
- templateVersionChanged: boolean;
8
- migrationDeclared: boolean;
9
- migrationRequired: boolean;
10
- }
11
- export declare function assessUpgrade(current: ModuleDescriptor, target: ModuleDescriptor): UpgradeAssessment;
12
- /**
13
- * Deterministic descriptor equality (key-order independent). Used to detect
14
- * an already-satisfied upgrade target so we never emit a pretend
15
- * `package:upgrade` mutation for an unchanged module.
16
- */
17
- export declare function descriptorsEqual(current: ModuleDescriptor, target: ModuleDescriptor): boolean;
18
- export declare function planUpgrade(input: PlanInput): DeploymentPlan;