@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.
- package/README.md +48 -43
- package/dist/deployment/adapter.d.ts +5 -5
- package/dist/deployment/adapter.js +2 -1
- package/dist/deployment/descriptor.d.ts +2 -3
- package/dist/deployment/descriptor.js +2 -3
- package/dist/src/binding/production-bindings.d.ts +17 -15
- package/dist/src/binding/production-bindings.js +18 -59
- package/dist/src/cli.d.ts +7 -9
- package/dist/src/cli.js +329 -1237
- package/dist/src/contracts.d.ts +4 -97
- package/dist/src/discovery/discover.js +0 -1
- package/dist/src/docs/aggregate.d.ts +18 -0
- package/dist/src/docs/aggregate.js +44 -0
- package/dist/src/docs/docs.d.ts +0 -31
- package/dist/src/docs/docs.js +0 -61
- package/dist/src/docs/index.d.ts +2 -1
- package/dist/src/docs/index.js +1 -1
- package/dist/src/errors.d.ts +1 -1
- package/dist/src/errors.js +0 -18
- package/dist/src/graph/graph.d.ts +1 -4
- package/dist/src/graph/graph.js +1 -13
- package/dist/src/graph/index.d.ts +2 -2
- package/dist/src/graph/index.js +1 -1
- package/dist/src/index.d.ts +4 -24
- package/dist/src/index.js +2 -16
- package/dist/src/install/package-manager.d.ts +21 -0
- package/dist/src/install/package-manager.js +153 -0
- package/dist/src/lifecycle/dispatch.d.ts +0 -30
- package/dist/src/lifecycle/dispatch.js +0 -120
- package/dist/src/lifecycle/index.d.ts +4 -3
- package/dist/src/lifecycle/index.js +2 -2
- package/dist/src/lifecycle/thin.d.ts +11 -0
- package/dist/src/lifecycle/thin.js +68 -0
- package/dist/src/paths.d.ts +0 -14
- package/dist/src/paths.js +0 -39
- package/dist/src/persistence/config.d.ts +0 -6
- package/dist/src/persistence/config.js +0 -14
- package/dist/src/persistence/guards.d.ts +0 -6
- package/dist/src/persistence/guards.js +0 -114
- package/dist/src/persistence/index.d.ts +4 -6
- package/dist/src/persistence/index.js +2 -5
- package/dist/src/persistence/workspace-metadata.d.ts +7 -0
- package/dist/src/persistence/workspace-metadata.js +39 -0
- package/dist/src/registry/index.d.ts +1 -1
- package/dist/src/registry/index.js +1 -1
- package/dist/src/registry/npm-registry.d.ts +0 -14
- package/dist/src/registry/npm-registry.js +1 -132
- package/package.json +2 -6
- package/proflow.module.json +2 -3
- package/CHANGELOG.md +0 -79
- package/dist/src/apply/apply.d.ts +0 -26
- package/dist/src/apply/apply.js +0 -314
- package/dist/src/apply/cleanup.d.ts +0 -12
- package/dist/src/apply/cleanup.js +0 -37
- package/dist/src/apply/current.d.ts +0 -5
- package/dist/src/apply/current.js +0 -95
- package/dist/src/apply/driver.d.ts +0 -28
- package/dist/src/apply/driver.js +0 -239
- package/dist/src/apply/execute.d.ts +0 -36
- package/dist/src/apply/execute.js +0 -152
- package/dist/src/apply/index.d.ts +0 -8
- package/dist/src/apply/index.js +0 -4
- package/dist/src/apply/reality.d.ts +0 -20
- package/dist/src/apply/reality.js +0 -105
- package/dist/src/binding/global-binding.d.ts +0 -69
- package/dist/src/binding/global-binding.js +0 -349
- package/dist/src/doctor/doctor.d.ts +0 -41
- package/dist/src/doctor/doctor.js +0 -80
- package/dist/src/doctor/index.d.ts +0 -2
- package/dist/src/doctor/index.js +0 -1
- package/dist/src/install/bootstrap.d.ts +0 -10
- package/dist/src/install/bootstrap.js +0 -79
- package/dist/src/install/environment.d.ts +0 -30
- package/dist/src/install/environment.js +0 -230
- package/dist/src/install/index.d.ts +0 -6
- package/dist/src/install/index.js +0 -3
- package/dist/src/install/install.d.ts +0 -19
- package/dist/src/install/install.js +0 -172
- package/dist/src/lifecycle/service-process.d.ts +0 -11
- package/dist/src/lifecycle/service-process.js +0 -356
- package/dist/src/manifest/index.d.ts +0 -2
- package/dist/src/manifest/index.js +0 -1
- package/dist/src/manifest/manifest.d.ts +0 -61
- package/dist/src/manifest/manifest.js +0 -167
- package/dist/src/observer/deployment-summary.d.ts +0 -31
- package/dist/src/observer/deployment-summary.js +0 -34
- package/dist/src/persistence/atomic.d.ts +0 -2
- package/dist/src/persistence/atomic.js +0 -16
- package/dist/src/persistence/effective-config.d.ts +0 -3
- package/dist/src/persistence/effective-config.js +0 -20
- package/dist/src/persistence/generated.d.ts +0 -2
- package/dist/src/persistence/generated.js +0 -4
- package/dist/src/persistence/plans.d.ts +0 -5
- package/dist/src/persistence/plans.js +0 -34
- package/dist/src/persistence/state.d.ts +0 -7
- package/dist/src/persistence/state.js +0 -34
- package/dist/src/persistence/verification.d.ts +0 -5
- package/dist/src/persistence/verification.js +0 -47
- package/dist/src/planner/assemble.d.ts +0 -16
- package/dist/src/planner/assemble.js +0 -107
- package/dist/src/planner/check.d.ts +0 -20
- package/dist/src/planner/check.js +0 -107
- package/dist/src/planner/fingerprint.d.ts +0 -12
- package/dist/src/planner/fingerprint.js +0 -164
- package/dist/src/planner/index.d.ts +0 -13
- package/dist/src/planner/index.js +0 -7
- package/dist/src/planner/plan.d.ts +0 -15
- package/dist/src/planner/plan.js +0 -144
- package/dist/src/planner/repair.d.ts +0 -28
- package/dist/src/planner/repair.js +0 -131
- package/dist/src/planner/stale.d.ts +0 -7
- package/dist/src/planner/stale.js +0 -23
- package/dist/src/planner/steps.d.ts +0 -37
- package/dist/src/planner/steps.js +0 -165
- package/dist/src/planner/target-catalog.d.ts +0 -13
- package/dist/src/planner/target-catalog.js +0 -48
- package/dist/src/planner/upgrade.d.ts +0 -18
- package/dist/src/planner/upgrade.js +0 -114
- package/dist/src/preflight/config.d.ts +0 -11
- package/dist/src/preflight/config.js +0 -88
- package/dist/src/preflight/findings.d.ts +0 -26
- package/dist/src/preflight/findings.js +0 -1
- package/dist/src/preflight/index.d.ts +0 -7
- package/dist/src/preflight/index.js +0 -3
- package/dist/src/preflight/preflight.d.ts +0 -10
- package/dist/src/preflight/preflight.js +0 -190
- package/dist/src/preflight/requirements.d.ts +0 -11
- package/dist/src/preflight/requirements.js +0 -231
- package/dist/src/ready/index.d.ts +0 -2
- package/dist/src/ready/index.js +0 -1
- package/dist/src/ready/ready.d.ts +0 -40
- package/dist/src/ready/ready.js +0 -201
- package/dist/src/security/index.d.ts +0 -3
- package/dist/src/security/index.js +0 -2
- package/dist/src/security/lock.d.ts +0 -9
- package/dist/src/security/lock.js +0 -127
- package/dist/src/security/redact.d.ts +0 -6
- package/dist/src/security/redact.js +0 -48
- package/dist/src/verification/index.d.ts +0 -2
- package/dist/src/verification/index.js +0 -1
- package/dist/src/verification/verify.d.ts +0 -33
- package/dist/src/verification/verify.js +0 -114
|
@@ -7,14 +7,6 @@ export interface LifecycleDispatchResult {
|
|
|
7
7
|
result: ModuleOperationResult;
|
|
8
8
|
observedEffects: string[];
|
|
9
9
|
}
|
|
10
|
-
export type LifecycleRunStatus = "EXECUTED" | "SKIP_UNSUPPORTED";
|
|
11
|
-
export interface LifecycleRunResult {
|
|
12
|
-
moduleRef: string;
|
|
13
|
-
primitive: LifecyclePrimitive;
|
|
14
|
-
status: LifecycleRunStatus;
|
|
15
|
-
result: ModuleOperationResult | undefined;
|
|
16
|
-
observedEffects: string[];
|
|
17
|
-
}
|
|
18
10
|
/**
|
|
19
11
|
* Dispatches a single lifecycle primitive against one module through its
|
|
20
12
|
* public deployment adapter. The descriptor is the source of truth for what is
|
|
@@ -23,25 +15,3 @@ export interface LifecycleRunResult {
|
|
|
23
15
|
* runtime-validated against the Module Operation Result schema.
|
|
24
16
|
*/
|
|
25
17
|
export declare function dispatchLifecycle(catalog: ModuleCatalog, module: ResolvedModule, primitive: LifecyclePrimitive): Promise<LifecycleDispatchResult>;
|
|
26
|
-
/**
|
|
27
|
-
* Starts a module set in forward dependency topological order, dispatching the
|
|
28
|
-
* `start` primitive only to modules that declare it.
|
|
29
|
-
*/
|
|
30
|
-
export declare function startModules(catalog: ModuleCatalog, modules: readonly ResolvedModule[]): Promise<LifecycleRunResult[]>;
|
|
31
|
-
/**
|
|
32
|
-
* Stops a module set in reverse dependency topological order, dispatching the
|
|
33
|
-
* `stop` primitive only to modules that declare it.
|
|
34
|
-
*/
|
|
35
|
-
export declare function stopModules(catalog: ModuleCatalog, modules: readonly ResolvedModule[]): Promise<LifecycleRunResult[]>;
|
|
36
|
-
/**
|
|
37
|
-
* Restarts a module set in forward dependency topological order, dispatching
|
|
38
|
-
* `restart` only to modules that explicitly declare it. Dependencies are
|
|
39
|
-
* settled before the modules that consume them.
|
|
40
|
-
*/
|
|
41
|
-
export declare function restartModules(catalog: ModuleCatalog, modules: readonly ResolvedModule[]): Promise<LifecycleRunResult[]>;
|
|
42
|
-
/**
|
|
43
|
-
* Queries current reality by dispatching the `status` primitive to every
|
|
44
|
-
* module that declares it. Status is always read live from the adapter; no
|
|
45
|
-
* persisted or cached value is substituted for current reality.
|
|
46
|
-
*/
|
|
47
|
-
export declare function statusModules(catalog: ModuleCatalog, modules: readonly ResolvedModule[]): Promise<LifecycleRunResult[]>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { moduleOperationResultSchema, } from "@tomflow/proflow-module-contract";
|
|
2
2
|
import { PlatformError } from "../errors.js";
|
|
3
|
-
import { buildDependencyGraph } from "../graph/graph.js";
|
|
4
3
|
function isRecord(value) {
|
|
5
4
|
return typeof value === "object" && value !== null;
|
|
6
5
|
}
|
|
@@ -11,9 +10,6 @@ function isWrappedResult(value) {
|
|
|
11
10
|
return isRecord(value) && "result" in value;
|
|
12
11
|
}
|
|
13
12
|
function moduleSource(module) {
|
|
14
|
-
if (module.source.type === "registry") {
|
|
15
|
-
throw new PlatformError("DESCRIPTOR_INVALID", `registry bootstrap target ${module.packageName} has no local lifecycle adapter`);
|
|
16
|
-
}
|
|
17
13
|
const source = {
|
|
18
14
|
type: module.source.type,
|
|
19
15
|
packageName: module.packageName,
|
|
@@ -75,119 +71,3 @@ export async function dispatchLifecycle(catalog, module, primitive) {
|
|
|
75
71
|
observedEffects,
|
|
76
72
|
};
|
|
77
73
|
}
|
|
78
|
-
async function runOne(catalog, module, primitive) {
|
|
79
|
-
if (!module.lifecycle.includes(primitive)) {
|
|
80
|
-
return {
|
|
81
|
-
moduleRef: module.moduleRef,
|
|
82
|
-
primitive,
|
|
83
|
-
status: "SKIP_UNSUPPORTED",
|
|
84
|
-
result: undefined,
|
|
85
|
-
observedEffects: [],
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
const dispatched = await dispatchLifecycle(catalog, module, primitive);
|
|
89
|
-
return {
|
|
90
|
-
moduleRef: dispatched.moduleRef,
|
|
91
|
-
primitive,
|
|
92
|
-
status: "EXECUTED",
|
|
93
|
-
result: dispatched.result,
|
|
94
|
-
observedEffects: dispatched.observedEffects,
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
async function runInOrder(catalog, modules, order, primitive) {
|
|
98
|
-
const byRef = new Map(modules.map((module) => [module.moduleRef, module]));
|
|
99
|
-
const results = [];
|
|
100
|
-
for (const moduleRef of order) {
|
|
101
|
-
const module = byRef.get(moduleRef);
|
|
102
|
-
if (module === undefined)
|
|
103
|
-
continue;
|
|
104
|
-
results.push(await runOne(catalog, module, primitive));
|
|
105
|
-
}
|
|
106
|
-
return results;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Starts a module set in forward dependency topological order, dispatching the
|
|
110
|
-
* `start` primitive only to modules that declare it.
|
|
111
|
-
*/
|
|
112
|
-
export async function startModules(catalog, modules) {
|
|
113
|
-
const graph = buildDependencyGraph(modules);
|
|
114
|
-
const byRef = new Map(modules.map((module) => [module.moduleRef, module]));
|
|
115
|
-
const resultByRef = new Map();
|
|
116
|
-
const results = [];
|
|
117
|
-
for (const moduleRef of graph.order) {
|
|
118
|
-
const module = byRef.get(moduleRef);
|
|
119
|
-
if (module === undefined)
|
|
120
|
-
continue;
|
|
121
|
-
if (!module.lifecycle.includes("start")) {
|
|
122
|
-
const skipped = await runOne(catalog, module, "start");
|
|
123
|
-
results.push(skipped);
|
|
124
|
-
resultByRef.set(moduleRef, skipped);
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
const blockingDependency = graph.edges
|
|
128
|
-
.filter((edge) => edge.from === moduleRef)
|
|
129
|
-
.map((edge) => edge.to)
|
|
130
|
-
.find((dependencyRef) => {
|
|
131
|
-
const dependencyModule = byRef.get(dependencyRef);
|
|
132
|
-
if (!dependencyModule?.lifecycle.includes("start"))
|
|
133
|
-
return false;
|
|
134
|
-
const dependencyResult = resultByRef.get(dependencyRef);
|
|
135
|
-
return dependencyResult?.result?.status !== "SUCCEEDED";
|
|
136
|
-
});
|
|
137
|
-
if (blockingDependency !== undefined) {
|
|
138
|
-
const blocked = {
|
|
139
|
-
moduleRef,
|
|
140
|
-
primitive: "start",
|
|
141
|
-
status: "EXECUTED",
|
|
142
|
-
result: {
|
|
143
|
-
contract: "deployment.result.v1",
|
|
144
|
-
ok: false,
|
|
145
|
-
status: "BLOCKED",
|
|
146
|
-
moduleRef: module.moduleRef,
|
|
147
|
-
moduleVersion: module.moduleVersion,
|
|
148
|
-
error: {
|
|
149
|
-
code: "COMMAND_FAILED",
|
|
150
|
-
message: `dependency ${blockingDependency} did not start successfully; ${moduleRef} was not started`,
|
|
151
|
-
retryable: true,
|
|
152
|
-
},
|
|
153
|
-
},
|
|
154
|
-
observedEffects: [],
|
|
155
|
-
};
|
|
156
|
-
results.push(blocked);
|
|
157
|
-
resultByRef.set(moduleRef, blocked);
|
|
158
|
-
continue;
|
|
159
|
-
}
|
|
160
|
-
const result = await runOne(catalog, module, "start");
|
|
161
|
-
results.push(result);
|
|
162
|
-
resultByRef.set(moduleRef, result);
|
|
163
|
-
}
|
|
164
|
-
return results;
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Stops a module set in reverse dependency topological order, dispatching the
|
|
168
|
-
* `stop` primitive only to modules that declare it.
|
|
169
|
-
*/
|
|
170
|
-
export async function stopModules(catalog, modules) {
|
|
171
|
-
const order = [...buildDependencyGraph(modules).order].reverse();
|
|
172
|
-
return runInOrder(catalog, modules, order, "stop");
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Restarts a module set in forward dependency topological order, dispatching
|
|
176
|
-
* `restart` only to modules that explicitly declare it. Dependencies are
|
|
177
|
-
* settled before the modules that consume them.
|
|
178
|
-
*/
|
|
179
|
-
export async function restartModules(catalog, modules) {
|
|
180
|
-
return runInOrder(catalog, modules, buildDependencyGraph(modules).order, "restart");
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Queries current reality by dispatching the `status` primitive to every
|
|
184
|
-
* module that declares it. Status is always read live from the adapter; no
|
|
185
|
-
* persisted or cached value is substituted for current reality.
|
|
186
|
-
*/
|
|
187
|
-
export async function statusModules(catalog, modules) {
|
|
188
|
-
const results = [];
|
|
189
|
-
for (const module of modules) {
|
|
190
|
-
results.push(await runOne(catalog, module, "status"));
|
|
191
|
-
}
|
|
192
|
-
return results;
|
|
193
|
-
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export type { LifecycleDispatchResult
|
|
2
|
-
export { dispatchLifecycle
|
|
3
|
-
export {
|
|
1
|
+
export type { LifecycleDispatchResult } from "./dispatch.ts";
|
|
2
|
+
export { dispatchLifecycle } from "./dispatch.ts";
|
|
3
|
+
export type { ThinLifecycleResult } from "./thin.ts";
|
|
4
|
+
export { observeStatuses, preflightAndStartModules, stopModulesThin, } from "./thin.ts";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { dispatchLifecycle
|
|
2
|
-
export {
|
|
1
|
+
export { dispatchLifecycle } from "./dispatch.js";
|
|
2
|
+
export { observeStatuses, preflightAndStartModules, stopModulesThin, } from "./thin.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ResolvedModule } from "../contracts.ts";
|
|
2
|
+
import type { ModuleCatalog } from "../modules.ts";
|
|
3
|
+
import { type LifecycleDispatchResult } from "./dispatch.ts";
|
|
4
|
+
export interface ThinLifecycleResult {
|
|
5
|
+
phase: "preflight" | "start" | "stop";
|
|
6
|
+
results: LifecycleDispatchResult[];
|
|
7
|
+
completed: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function observeStatuses(catalog: ModuleCatalog, modules: readonly ResolvedModule[]): Promise<LifecycleDispatchResult[]>;
|
|
10
|
+
export declare function preflightAndStartModules(catalog: ModuleCatalog, modules: readonly ResolvedModule[]): Promise<ThinLifecycleResult>;
|
|
11
|
+
export declare function stopModulesThin(catalog: ModuleCatalog, modules: readonly ResolvedModule[]): Promise<ThinLifecycleResult>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { buildDependencyGraph } from "../graph/graph.js";
|
|
2
|
+
import { dispatchLifecycle } from "./dispatch.js";
|
|
3
|
+
function succeeded(result) {
|
|
4
|
+
return result.status === "SUCCEEDED";
|
|
5
|
+
}
|
|
6
|
+
async function dispatchIfSupported(catalog, module, primitive) {
|
|
7
|
+
if (!module.lifecycle.includes(primitive))
|
|
8
|
+
return undefined;
|
|
9
|
+
return dispatchLifecycle(catalog, module, primitive);
|
|
10
|
+
}
|
|
11
|
+
export async function observeStatuses(catalog, modules) {
|
|
12
|
+
const results = [];
|
|
13
|
+
for (const module of [...modules].sort((a, b) => a.moduleRef.localeCompare(b.moduleRef))) {
|
|
14
|
+
if (!module.lifecycle.includes("status"))
|
|
15
|
+
continue;
|
|
16
|
+
results.push(await dispatchLifecycle(catalog, module, "status"));
|
|
17
|
+
}
|
|
18
|
+
return results;
|
|
19
|
+
}
|
|
20
|
+
export async function preflightAndStartModules(catalog, modules) {
|
|
21
|
+
const graph = buildDependencyGraph(modules);
|
|
22
|
+
const byRef = new Map(modules.map((module) => [module.moduleRef, module]));
|
|
23
|
+
const preflight = [];
|
|
24
|
+
for (const moduleRef of graph.order) {
|
|
25
|
+
const module = byRef.get(moduleRef);
|
|
26
|
+
if (module === undefined)
|
|
27
|
+
continue;
|
|
28
|
+
const result = await dispatchIfSupported(catalog, module, "preflight");
|
|
29
|
+
if (result === undefined)
|
|
30
|
+
continue;
|
|
31
|
+
preflight.push(result);
|
|
32
|
+
if (!succeeded(result.result)) {
|
|
33
|
+
return { phase: "preflight", results: preflight, completed: false };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const started = [];
|
|
37
|
+
for (const moduleRef of graph.order) {
|
|
38
|
+
const module = byRef.get(moduleRef);
|
|
39
|
+
if (module === undefined)
|
|
40
|
+
continue;
|
|
41
|
+
const result = await dispatchIfSupported(catalog, module, "start");
|
|
42
|
+
if (result === undefined)
|
|
43
|
+
continue;
|
|
44
|
+
started.push(result);
|
|
45
|
+
if (!succeeded(result.result)) {
|
|
46
|
+
return { phase: "start", results: started, completed: false };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return { phase: "start", results: started, completed: true };
|
|
50
|
+
}
|
|
51
|
+
export async function stopModulesThin(catalog, modules) {
|
|
52
|
+
const order = [...buildDependencyGraph(modules).order].reverse();
|
|
53
|
+
const byRef = new Map(modules.map((module) => [module.moduleRef, module]));
|
|
54
|
+
const stopped = [];
|
|
55
|
+
for (const moduleRef of order) {
|
|
56
|
+
const module = byRef.get(moduleRef);
|
|
57
|
+
if (module === undefined)
|
|
58
|
+
continue;
|
|
59
|
+
const result = await dispatchIfSupported(catalog, module, "stop");
|
|
60
|
+
if (result === undefined)
|
|
61
|
+
continue;
|
|
62
|
+
stopped.push(result);
|
|
63
|
+
if (!succeeded(result.result)) {
|
|
64
|
+
return { phase: "stop", results: stopped, completed: false };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return { phase: "stop", results: stopped, completed: true };
|
|
68
|
+
}
|
package/dist/src/paths.d.ts
CHANGED
|
@@ -2,20 +2,6 @@ export interface WorkspacePaths {
|
|
|
2
2
|
root: string;
|
|
3
3
|
proflow: string;
|
|
4
4
|
config: string;
|
|
5
|
-
data: string;
|
|
6
|
-
logs: string;
|
|
7
|
-
logsDeployment: string;
|
|
8
|
-
runtime: string;
|
|
9
|
-
cache: string;
|
|
10
|
-
tmp: string;
|
|
11
|
-
deployment: string;
|
|
12
|
-
stateJson: string;
|
|
13
|
-
plans: string;
|
|
14
|
-
verification: string;
|
|
15
|
-
generated: string;
|
|
16
|
-
installMd: string;
|
|
17
5
|
}
|
|
18
6
|
export declare function workspacePaths(root: string): WorkspacePaths;
|
|
19
|
-
export declare function ensureLayout(paths: WorkspacePaths): Promise<void>;
|
|
20
7
|
export declare function atomicWrite(file: string, content: string): Promise<void>;
|
|
21
|
-
export declare function readJson<T>(file: string): Promise<T | undefined>;
|
package/dist/src/paths.js
CHANGED
|
@@ -3,54 +3,15 @@ import { mkdir, rename, writeFile } from "node:fs/promises";
|
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
export function workspacePaths(root) {
|
|
5
5
|
const proflow = join(root, ".proflow");
|
|
6
|
-
const deployment = join(proflow, "deployment");
|
|
7
6
|
return {
|
|
8
7
|
root,
|
|
9
8
|
proflow,
|
|
10
9
|
config: join(proflow, "config"),
|
|
11
|
-
data: join(proflow, "data"),
|
|
12
|
-
logs: join(proflow, "logs"),
|
|
13
|
-
logsDeployment: join(proflow, "logs", "deployment"),
|
|
14
|
-
runtime: join(proflow, "runtime"),
|
|
15
|
-
cache: join(proflow, "cache"),
|
|
16
|
-
tmp: join(proflow, "tmp"),
|
|
17
|
-
deployment,
|
|
18
|
-
stateJson: join(deployment, "state.json"),
|
|
19
|
-
plans: join(deployment, "plans"),
|
|
20
|
-
verification: join(deployment, "verification"),
|
|
21
|
-
generated: join(deployment, "generated"),
|
|
22
|
-
installMd: join(deployment, "generated", "INSTALL.md"),
|
|
23
10
|
};
|
|
24
11
|
}
|
|
25
|
-
export async function ensureLayout(paths) {
|
|
26
|
-
for (const dir of [
|
|
27
|
-
paths.config,
|
|
28
|
-
paths.data,
|
|
29
|
-
paths.logsDeployment,
|
|
30
|
-
paths.runtime,
|
|
31
|
-
paths.cache,
|
|
32
|
-
paths.tmp,
|
|
33
|
-
paths.plans,
|
|
34
|
-
paths.verification,
|
|
35
|
-
paths.generated,
|
|
36
|
-
]) {
|
|
37
|
-
await mkdir(dir, { recursive: true });
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
// Atomic write: bounded write to a temp sibling then rename into place.
|
|
41
12
|
export async function atomicWrite(file, content) {
|
|
42
13
|
await mkdir(dirname(file), { recursive: true });
|
|
43
14
|
const tmp = `${file}.tmp-${randomBytes(6).toString("hex")}`;
|
|
44
15
|
await writeFile(tmp, content, "utf8");
|
|
45
16
|
await rename(tmp, file);
|
|
46
17
|
}
|
|
47
|
-
export async function readJson(file) {
|
|
48
|
-
try {
|
|
49
|
-
const { readFile } = await import("node:fs/promises");
|
|
50
|
-
const raw = await readFile(file, "utf8");
|
|
51
|
-
return JSON.parse(raw);
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
@@ -3,10 +3,4 @@ export interface MaterializedConfig {
|
|
|
3
3
|
publicValues: Record<string, string>;
|
|
4
4
|
secretValues: Record<string, string>;
|
|
5
5
|
}
|
|
6
|
-
export interface ModuleConfig {
|
|
7
|
-
moduleRef: string;
|
|
8
|
-
values: Record<string, string>;
|
|
9
|
-
secretRefs: readonly string[];
|
|
10
|
-
}
|
|
11
|
-
export declare function materializeConfig(paths: WorkspacePaths, config: ModuleConfig): Promise<void>;
|
|
12
6
|
export declare function loadConfig(paths: WorkspacePaths, moduleRef: string): Promise<MaterializedConfig | undefined>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { PlatformError } from "../errors.js";
|
|
4
|
-
import { writeJsonAtomic } from "./atomic.js";
|
|
5
4
|
import { assertSafeFileName } from "./guards.js";
|
|
6
5
|
function configFilePath(paths, moduleRef) {
|
|
7
6
|
assertSafeFileName(moduleRef, "moduleRef");
|
|
@@ -43,19 +42,6 @@ async function readConfigValues(file, moduleRef, kind) {
|
|
|
43
42
|
throw new PlatformError("CONFIG_INVALID", `${kind} config for ${moduleRef} is invalid JSON/config: ${error instanceof Error ? error.message : String(error)}`);
|
|
44
43
|
}
|
|
45
44
|
}
|
|
46
|
-
// secretRef config values are opaque reference identities (e.g.
|
|
47
|
-
// `secret://model-provider/default`), not raw secrets, so they materialize to
|
|
48
|
-
// the public config file verbatim. A raw secret would go to the separate 0o600
|
|
49
|
-
// secrets file — but v1 planning produces no raw secrets, so it stays empty and
|
|
50
|
-
// must never hold a secretRef reference.
|
|
51
|
-
export async function materializeConfig(paths, config) {
|
|
52
|
-
const publicValues = {};
|
|
53
|
-
for (const [key, value] of Object.entries(config.values)) {
|
|
54
|
-
publicValues[key] = value;
|
|
55
|
-
}
|
|
56
|
-
await writeJsonAtomic(configFilePath(paths, config.moduleRef), publicValues, 0o644);
|
|
57
|
-
await writeJsonAtomic(secretsFilePath(paths, config.moduleRef), {}, 0o600);
|
|
58
|
-
}
|
|
59
45
|
export async function loadConfig(paths, moduleRef) {
|
|
60
46
|
const publicValues = await readConfigValues(configFilePath(paths, moduleRef), moduleRef, "public");
|
|
61
47
|
const secretValues = await readConfigValues(secretsFilePath(paths, moduleRef), moduleRef, "secret");
|
|
@@ -1,7 +1 @@
|
|
|
1
|
-
import type { DeploymentPlan, DeploymentState, LockRecord, VerificationRecord } from "../contracts.ts";
|
|
2
|
-
export declare const DEPLOYMENT_STATE_CONTRACT = "proflow.deployment-state.v1";
|
|
3
1
|
export declare function assertSafeFileName(name: string, kind: string): void;
|
|
4
|
-
export declare function isDeploymentState(value: unknown): value is DeploymentState;
|
|
5
|
-
export declare function isVerificationRecord(value: unknown): value is VerificationRecord;
|
|
6
|
-
export declare function isDeploymentPlan(value: unknown): value is DeploymentPlan;
|
|
7
|
-
export declare function isLockRecord(value: unknown): value is LockRecord;
|
|
@@ -1,121 +1,7 @@
|
|
|
1
1
|
import { PlatformError } from "../errors.js";
|
|
2
|
-
export const DEPLOYMENT_STATE_CONTRACT = "proflow.deployment-state.v1";
|
|
3
2
|
const SAFE_FILE_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
4
3
|
export function assertSafeFileName(name, kind) {
|
|
5
4
|
if (!SAFE_FILE_NAME.test(name)) {
|
|
6
5
|
throw new PlatformError("INVALID_REQUEST", `invalid ${kind} name: ${name}`);
|
|
7
6
|
}
|
|
8
7
|
}
|
|
9
|
-
function isRecord(value) {
|
|
10
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11
|
-
}
|
|
12
|
-
function isString(value) {
|
|
13
|
-
return typeof value === "string";
|
|
14
|
-
}
|
|
15
|
-
function isStringArray(value) {
|
|
16
|
-
return Array.isArray(value) && value.every(isString);
|
|
17
|
-
}
|
|
18
|
-
function isDeploymentIntent(value) {
|
|
19
|
-
return (value === "install" ||
|
|
20
|
-
value === "configure" ||
|
|
21
|
-
value === "upgrade" ||
|
|
22
|
-
value === "uninstall" ||
|
|
23
|
-
value === "repair");
|
|
24
|
-
}
|
|
25
|
-
function isSelectedModuleFact(value) {
|
|
26
|
-
return (isRecord(value) &&
|
|
27
|
-
isString(value.moduleRef) &&
|
|
28
|
-
isString(value.moduleVersion));
|
|
29
|
-
}
|
|
30
|
-
function isLastAppliedPlan(value) {
|
|
31
|
-
return (isRecord(value) &&
|
|
32
|
-
isString(value.planRef) &&
|
|
33
|
-
isDeploymentIntent(value.intent) &&
|
|
34
|
-
isString(value.appliedAt));
|
|
35
|
-
}
|
|
36
|
-
function isVerificationIndexEntry(value) {
|
|
37
|
-
return (isRecord(value) && isString(value.moduleRef) && isString(value.latestRef));
|
|
38
|
-
}
|
|
39
|
-
function isPendingAction(value) {
|
|
40
|
-
return (isRecord(value) &&
|
|
41
|
-
isString(value.planRef) &&
|
|
42
|
-
isString(value.stepRef) &&
|
|
43
|
-
isString(value.moduleRef) &&
|
|
44
|
-
isString(value.action) &&
|
|
45
|
-
(value.description === undefined || isString(value.description)) &&
|
|
46
|
-
isString(value.createdAt));
|
|
47
|
-
}
|
|
48
|
-
export function isDeploymentState(value) {
|
|
49
|
-
if (!isRecord(value))
|
|
50
|
-
return false;
|
|
51
|
-
if (value.contract !== DEPLOYMENT_STATE_CONTRACT)
|
|
52
|
-
return false;
|
|
53
|
-
if (!Array.isArray(value.selectedModules))
|
|
54
|
-
return false;
|
|
55
|
-
if (!value.selectedModules.every(isSelectedModuleFact))
|
|
56
|
-
return false;
|
|
57
|
-
if (!Array.isArray(value.lastAppliedPlans))
|
|
58
|
-
return false;
|
|
59
|
-
if (!value.lastAppliedPlans.every(isLastAppliedPlan))
|
|
60
|
-
return false;
|
|
61
|
-
if (!Array.isArray(value.verificationIndex))
|
|
62
|
-
return false;
|
|
63
|
-
if (!value.verificationIndex.every(isVerificationIndexEntry))
|
|
64
|
-
return false;
|
|
65
|
-
if (!Array.isArray(value.pendingActions))
|
|
66
|
-
return false;
|
|
67
|
-
if (!value.pendingActions.every(isPendingAction))
|
|
68
|
-
return false;
|
|
69
|
-
return isString(value.updatedAt);
|
|
70
|
-
}
|
|
71
|
-
export function isVerificationRecord(value) {
|
|
72
|
-
if (!isRecord(value))
|
|
73
|
-
return false;
|
|
74
|
-
if (!isString(value.verificationRef))
|
|
75
|
-
return false;
|
|
76
|
-
if (!isString(value.moduleRef))
|
|
77
|
-
return false;
|
|
78
|
-
if (!isString(value.moduleVersion))
|
|
79
|
-
return false;
|
|
80
|
-
if (value.resourceIdentity !== undefined && !isString(value.resourceIdentity))
|
|
81
|
-
return false;
|
|
82
|
-
if (value.resourceVersion !== undefined && !isString(value.resourceVersion))
|
|
83
|
-
return false;
|
|
84
|
-
if (value.result !== "PASS" && value.result !== "FAIL")
|
|
85
|
-
return false;
|
|
86
|
-
if (!isString(value.summary))
|
|
87
|
-
return false;
|
|
88
|
-
if (!isStringArray(value.evidenceRefs))
|
|
89
|
-
return false;
|
|
90
|
-
return isString(value.verifiedAt);
|
|
91
|
-
}
|
|
92
|
-
export function isDeploymentPlan(value) {
|
|
93
|
-
if (!isRecord(value))
|
|
94
|
-
return false;
|
|
95
|
-
if (!isString(value.planRef))
|
|
96
|
-
return false;
|
|
97
|
-
if (!isDeploymentIntent(value.intent))
|
|
98
|
-
return false;
|
|
99
|
-
if (!Array.isArray(value.moduleTargets))
|
|
100
|
-
return false;
|
|
101
|
-
if (!Array.isArray(value.resolvedModules))
|
|
102
|
-
return false;
|
|
103
|
-
if (!Array.isArray(value.steps))
|
|
104
|
-
return false;
|
|
105
|
-
if (!Array.isArray(value.effects))
|
|
106
|
-
return false;
|
|
107
|
-
if (!Array.isArray(value.humanActions))
|
|
108
|
-
return false;
|
|
109
|
-
if (!Array.isArray(value.verification))
|
|
110
|
-
return false;
|
|
111
|
-
if (!isString(value.fingerprint))
|
|
112
|
-
return false;
|
|
113
|
-
return isString(value.createdAt);
|
|
114
|
-
}
|
|
115
|
-
export function isLockRecord(value) {
|
|
116
|
-
return (isRecord(value) &&
|
|
117
|
-
typeof value.pid === "number" &&
|
|
118
|
-
isString(value.createdAt) &&
|
|
119
|
-
isString(value.planRef) &&
|
|
120
|
-
isString(value.workspaceFingerprint));
|
|
121
|
-
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
export type { MaterializedConfig
|
|
2
|
-
export { loadConfig
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export { emptyDeploymentState, loadDeploymentState, saveDeploymentState, } from "./state.ts";
|
|
6
|
-
export { appendVerification, loadLatestVerification, loadVerificationHistory, } from "./verification.ts";
|
|
1
|
+
export type { MaterializedConfig } from "./config.ts";
|
|
2
|
+
export { loadConfig } from "./config.ts";
|
|
3
|
+
export type { WorkspaceMetadata } from "./workspace-metadata.ts";
|
|
4
|
+
export { ensureWorkspaceMetadata } from "./workspace-metadata.ts";
|
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
export { loadConfig
|
|
2
|
-
export {
|
|
3
|
-
export { listPlans, loadPlan, savePlan } from "./plans.js";
|
|
4
|
-
export { emptyDeploymentState, loadDeploymentState, saveDeploymentState, } from "./state.js";
|
|
5
|
-
export { appendVerification, loadLatestVerification, loadVerificationHistory, } from "./verification.js";
|
|
1
|
+
export { loadConfig } from "./config.js";
|
|
2
|
+
export { ensureWorkspaceMetadata } from "./workspace-metadata.js";
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { readFile, realpath } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { PlatformError } from "../errors.js";
|
|
5
|
+
import { atomicWrite } from "../paths.js";
|
|
6
|
+
export async function ensureWorkspaceMetadata(workspaceRoot) {
|
|
7
|
+
const canonicalRoot = await realpath(workspaceRoot);
|
|
8
|
+
const path = join(canonicalRoot, ".proflow", "workspace.json");
|
|
9
|
+
try {
|
|
10
|
+
const parsed = JSON.parse(await readFile(path, "utf8"));
|
|
11
|
+
if (typeof parsed !== "object" ||
|
|
12
|
+
parsed === null ||
|
|
13
|
+
Array.isArray(parsed) ||
|
|
14
|
+
Reflect.get(parsed, "contract") !== "proflow.workspace.v1" ||
|
|
15
|
+
typeof Reflect.get(parsed, "workspaceInstanceId") !== "string" ||
|
|
16
|
+
Reflect.get(parsed, "workspaceRoot") !== canonicalRoot ||
|
|
17
|
+
typeof Reflect.get(parsed, "createdAt") !== "string") {
|
|
18
|
+
throw new PlatformError("WORKSPACE_INSTANCE_INVALID", "existing .proflow/workspace.json does not match this Workspace");
|
|
19
|
+
}
|
|
20
|
+
return parsed;
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (error instanceof PlatformError)
|
|
24
|
+
throw error;
|
|
25
|
+
if (typeof error !== "object" ||
|
|
26
|
+
error === null ||
|
|
27
|
+
Reflect.get(error, "code") !== "ENOENT") {
|
|
28
|
+
throw new PlatformError("WORKSPACE_INSTANCE_INVALID", `cannot read Workspace metadata: ${error instanceof Error ? error.message : String(error)}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const metadata = {
|
|
32
|
+
contract: "proflow.workspace.v1",
|
|
33
|
+
workspaceInstanceId: randomUUID(),
|
|
34
|
+
workspaceRoot: canonicalRoot,
|
|
35
|
+
createdAt: new Date().toISOString(),
|
|
36
|
+
};
|
|
37
|
+
await atomicWrite(path, `${JSON.stringify(metadata, null, 2)}\n`);
|
|
38
|
+
return metadata;
|
|
39
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export type { NpmCommandResult, NpmCommandRunner, RegistryDiscoveryResult, RegistryModuleCandidate, RegistryRejectedPackage, } from "./npm-registry.ts";
|
|
2
|
-
export {
|
|
2
|
+
export { discoverRegistryModules, PRO_FLOW_PACKAGE_PREFIX, PRO_FLOW_SCOPE, resolveScopeRegistry, systemNpmRunner, } from "./npm-registry.ts";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { discoverRegistryModules, PRO_FLOW_PACKAGE_PREFIX, PRO_FLOW_SCOPE, resolveScopeRegistry, systemNpmRunner, } from "./npm-registry.js";
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type ModuleDescriptor, type ModuleInstallClass } from "@tomflow/proflow-module-contract";
|
|
2
1
|
export declare const PRO_FLOW_SCOPE = "@tomflow";
|
|
3
2
|
export declare const PRO_FLOW_PACKAGE_PREFIX = "@tomflow/proflow-";
|
|
4
3
|
export interface NpmCommandResult {
|
|
@@ -12,10 +11,8 @@ export interface RegistryModuleCandidate {
|
|
|
12
11
|
packageName: string;
|
|
13
12
|
moduleVersion: string;
|
|
14
13
|
description?: string;
|
|
15
|
-
installClass: ModuleInstallClass;
|
|
16
14
|
descriptor: string;
|
|
17
15
|
manifest: "./proflow.module.json";
|
|
18
|
-
installRequires: string[];
|
|
19
16
|
nodeVersionRange?: string;
|
|
20
17
|
registry: string;
|
|
21
18
|
}
|
|
@@ -38,14 +35,3 @@ export declare function discoverRegistryModules(options: {
|
|
|
38
35
|
runner?: NpmCommandRunner;
|
|
39
36
|
nodeVersion?: string;
|
|
40
37
|
}): Promise<RegistryDiscoveryResult>;
|
|
41
|
-
export declare function loadRegistryModuleDescriptor(options: {
|
|
42
|
-
workspaceRoot: string;
|
|
43
|
-
candidate: RegistryModuleCandidate;
|
|
44
|
-
runner?: NpmCommandRunner;
|
|
45
|
-
}): Promise<ModuleDescriptor>;
|
|
46
|
-
export declare function discoverRegistryInstallClosure(options: {
|
|
47
|
-
workspaceRoot: string;
|
|
48
|
-
packageName: string;
|
|
49
|
-
runner?: NpmCommandRunner;
|
|
50
|
-
nodeVersion?: string;
|
|
51
|
-
}): Promise<RegistryDiscoveryResult>;
|