@intentius/chant 0.18.28 → 0.18.30
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/dist/cli/handlers/components.d.ts.map +1 -1
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +2 -0
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +13 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/driver.d.ts +22 -1
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/run-progress.d.ts +94 -0
- package/dist/components/run-progress.d.ts.map +1 -0
- package/dist/lifecycle/status.d.ts +25 -0
- package/dist/lifecycle/status.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli/handlers/components.ts +13 -1
- package/src/cli/handlers/run.test.ts +54 -0
- package/src/cli/handlers/run.ts +9 -1
- package/src/cli/main.test.ts +14 -0
- package/src/cli/main.ts +7 -0
- package/src/cli/registry.ts +2 -0
- package/src/components/cli-support.test.ts +92 -1
- package/src/components/cli-support.ts +36 -2
- package/src/components/driver.test.ts +190 -0
- package/src/components/driver.ts +100 -33
- package/src/components/run-progress.ts +117 -0
- package/src/lifecycle/status.test.ts +23 -0
- package/src/lifecycle/status.ts +38 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/components.ts"],"names":[],"mappings":"AA6CA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAuErF;
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/components.ts"],"names":[],"mappings":"AA6CA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAuErF;AAqHD,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAuN9E;AAED,kEAAkE;AAClE,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAM/E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/run.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/run.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA2ClD,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,WAAW,EAAE,MAAM;;;;GAO5F;AA8BD,wBAAsB,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAgEpE;AAoFD,wBAAsB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAuCtE;AA0CD,wBAAsB,QAAQ,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA6CnE;AA2DD;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBtE;AAID,2LAA2L;AAC3L,wBAAsB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BtE;AAmCD;;;;;;;;;;;;GAYG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAchE;AA6ED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAsE1E;AAkOD;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAiFrE;AAuLD,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAMjE"}
|
package/dist/cli/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AAMA,OAAO,EAAmC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAkB9E;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":";AAMA,OAAO,EAAmC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAkB9E;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CA6LpD;AA2VD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB5E"}
|
package/dist/cli/registry.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ export interface ParsedArgs {
|
|
|
25
25
|
temporal?: boolean;
|
|
26
26
|
/** `chant run` — emit the structured OpRunResult as JSON on stdout. */
|
|
27
27
|
json?: boolean;
|
|
28
|
+
/** `chant run --components <name|all> --progress-json` — stream one NDJSON `RunProgressEvent` (../../components/run-progress.ts) per line to stdout while the run executes (local executor only), so a consumer can render live wave/component/phase/step progress instead of tailing raw logs. Purely additive: run semantics, ordering, and exit code are unchanged; omitted (undefined, not false) when the flag isn't passed. */
|
|
29
|
+
progressJson?: boolean;
|
|
28
30
|
live: boolean;
|
|
29
31
|
/** `chant migrate --from <name>` (default "github") */
|
|
30
32
|
migrateFrom?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/cli/registry.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/cli/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
import { type Archetype } from "./component.js";
|
|
25
25
|
import { type DriverComponent, type DriverRunResult } from "./driver.js";
|
|
26
26
|
import { type ComponentPipelineOptions } from "../lexicon.js";
|
|
27
|
+
import type { RunProgressEvent } from "./run-progress.js";
|
|
27
28
|
import type { CapabilityRegistry } from "./capability.js";
|
|
28
29
|
import { type ChantConfig } from "../config.js";
|
|
29
30
|
/** One component in `chant list --components` output. */
|
|
@@ -147,6 +148,18 @@ export interface RunComponentsOptions {
|
|
|
147
148
|
* ran elsewhere. Merged with, and overridden by, outputs this run produces.
|
|
148
149
|
*/
|
|
149
150
|
componentOutputs?: Record<string, Record<string, unknown>>;
|
|
151
|
+
/**
|
|
152
|
+
* Opt-in structured progress observer (`chant run --components <name|all>
|
|
153
|
+
* --progress-json`, see ./run-progress.ts). Threaded straight through to
|
|
154
|
+
* `runInterpretDriver` for `selector === "all"`; for a single-component
|
|
155
|
+
* selector (which bypasses `runInterpretDriver` — see the docstring above),
|
|
156
|
+
* this function emits the same `run-start`/`wave-start`/`component-start`/
|
|
157
|
+
* …/`run-done` envelope itself, treating the one component as a run with a
|
|
158
|
+
* single wave, so `--progress-json` produces a well-formed event stream
|
|
159
|
+
* regardless of selector. Left `undefined` by every caller that didn't pass
|
|
160
|
+
* `--progress-json`, in which case nothing changes.
|
|
161
|
+
*/
|
|
162
|
+
onProgress?: (event: RunProgressEvent) => void;
|
|
150
163
|
}
|
|
151
164
|
/** Result of `chant run --components <name|all>`. */
|
|
152
165
|
export interface RunComponentsResult {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-support.d.ts","sourceRoot":"","sources":["../../src/components/cli-support.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAQL,KAAK,eAAe,EAEpB,KAAK,eAAe,EACrB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAuC,KAAK,wBAAwB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cli-support.d.ts","sourceRoot":"","sources":["../../src/components/cli-support.ts"],"names":[],"mappings":"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"}
|
|
@@ -41,6 +41,8 @@
|
|
|
41
41
|
* `CapabilityRegistry` the caller supplies.
|
|
42
42
|
*/
|
|
43
43
|
import type { CapabilityRegistry, DeployContext } from "./capability.js";
|
|
44
|
+
import type { RunProgressEvent } from "./run-progress.js";
|
|
45
|
+
export type { RunProgressEvent } from "./run-progress.js";
|
|
44
46
|
/** A wiring reference or literal value, as it appears in a step's fields (schema `WiringValue`). */
|
|
45
47
|
export type WiringValue = string | {
|
|
46
48
|
stackOutput: {
|
|
@@ -181,8 +183,17 @@ export declare function resolveStepInput(input: Record<string, unknown>, phaseOu
|
|
|
181
183
|
* handling. Cross-component artifact outputs this component published (if
|
|
182
184
|
* any) are recorded into `componentOutputs` under its own name so downstream
|
|
183
185
|
* components can reference `@<name>.publish.*`.
|
|
186
|
+
*
|
|
187
|
+
* `onProgress`, when supplied, is forwarded to every `runPhase` call (both the
|
|
188
|
+
* forward `deploy` phases and, on failure, the component's own authored
|
|
189
|
+
* `rollback` phases) so a `--progress-json` consumer sees `phase-start`/
|
|
190
|
+
* `step`/`phase-done` events for whichever phases actually ran. The saga
|
|
191
|
+
* unwind step-by-step compensation (`rollbackExecuted` below) is not part of
|
|
192
|
+
* the `RunProgressEvent` contract and stays silent — it isn't a `deploy`
|
|
193
|
+
* phase, and its record statuses (`rolled-back`/`rollback-opted-out`) don't
|
|
194
|
+
* map onto the `step` event's `running`/`ok`/`failed` shape.
|
|
184
195
|
*/
|
|
185
|
-
export declare function runComponentDeploy(component: DriverComponent, ctx: DeployContext, registry: CapabilityRegistry, componentOutputs: Record<string, Record<string, unknown
|
|
196
|
+
export declare function runComponentDeploy(component: DriverComponent, ctx: DeployContext, registry: CapabilityRegistry, componentOutputs: Record<string, Record<string, unknown>>, onProgress?: (event: RunProgressEvent) => void): Promise<DriverComponentResult>;
|
|
186
197
|
export interface InterpretRunOptions {
|
|
187
198
|
/** Target environment name, threaded into every capability's `DeployContext`. */
|
|
188
199
|
env: string;
|
|
@@ -190,6 +201,16 @@ export interface InterpretRunOptions {
|
|
|
190
201
|
vars?: Record<string, unknown>;
|
|
191
202
|
/** Pre-seeded cross-component/cross-stack outputs (e.g. from a prior run, or a caller resolving `stackOutput` externally). Merged with outputs this run produces. */
|
|
192
203
|
componentOutputs?: Record<string, Record<string, unknown>>;
|
|
204
|
+
/**
|
|
205
|
+
* Opt-in structured progress observer (`chant run --components all
|
|
206
|
+
* --progress-json`, see ./run-progress.ts). Called with `run-start`/
|
|
207
|
+
* `wave-start`/`component-start`/…/`run-done` events as the run executes;
|
|
208
|
+
* never consulted for control flow, so leaving it `undefined` (the default
|
|
209
|
+
* for every caller that didn't pass `--progress-json`) makes every
|
|
210
|
+
* `onProgress?.(...)` call below a no-op and this function's behavior is
|
|
211
|
+
* byte-for-byte the same as before this option existed.
|
|
212
|
+
*/
|
|
213
|
+
onProgress?: (event: RunProgressEvent) => void;
|
|
193
214
|
}
|
|
194
215
|
/**
|
|
195
216
|
* Run a set of components to completion on the local in-process executor:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/components/driver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/components/driver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured progress events for `chant run --components <sel> --progress-json`
|
|
3
|
+
* (behold roadmap M3: a consumer that renders live wave/phase/step progress
|
|
4
|
+
* instead of tailing raw logs).
|
|
5
|
+
*
|
|
6
|
+
* This is purely additive observation over the interpret driver's existing
|
|
7
|
+
* wave -> component -> phase -> step execution loop (./driver.ts): an
|
|
8
|
+
* optional `onProgress` callback, threaded through
|
|
9
|
+
* `runInterpretDriver`/`runComponentDeploy`/`runPhase` (and the CLI's
|
|
10
|
+
* single-component path, ./cli-support.ts's `runComponents`), that never
|
|
11
|
+
* changes run ordering, gating, `onFailure`, rollback, or exit codes — it
|
|
12
|
+
* only reports what already happened, as it happens. See ./driver.ts's
|
|
13
|
+
* module doc for what actually executes; streaming progress on the *durable*
|
|
14
|
+
* (Temporal) path is a separate, later concern (Temporal already exposes
|
|
15
|
+
* durable run state via `chant run status`/`log`).
|
|
16
|
+
*
|
|
17
|
+
* `RunProgressEvent` is a discriminated union on `type`, one JSON object per
|
|
18
|
+
* NDJSON line (see `ndjsonProgressSink` below and
|
|
19
|
+
* ../cli/handlers/run.ts's `--progress-json` wiring).
|
|
20
|
+
*/
|
|
21
|
+
/** Terminal status for a wave/component/phase/run — mirrors DriverStepRecord's ok/fail split, collapsed to the two outcomes a consumer renders progress against. */
|
|
22
|
+
export type RunProgressStatus = "ok" | "failed";
|
|
23
|
+
/** The run is about to start. `waves` are the parallel-safe waves the run will attempt, in order (see resolveComponentGraph) — 1-based wave numbers in every other event index into this array. */
|
|
24
|
+
export interface RunStartEvent {
|
|
25
|
+
type: "run-start";
|
|
26
|
+
waves: string[][];
|
|
27
|
+
}
|
|
28
|
+
/** A wave is about to start; its components may run concurrently (independent components share a wave). */
|
|
29
|
+
export interface WaveStartEvent {
|
|
30
|
+
type: "wave-start";
|
|
31
|
+
/** 1-based wave number. */
|
|
32
|
+
wave: number;
|
|
33
|
+
components: string[];
|
|
34
|
+
}
|
|
35
|
+
/** A component within a wave is about to start its `deploy` composition. */
|
|
36
|
+
export interface ComponentStartEvent {
|
|
37
|
+
type: "component-start";
|
|
38
|
+
wave: number;
|
|
39
|
+
component: string;
|
|
40
|
+
}
|
|
41
|
+
/** A named phase of a component's composition is about to run its steps. Emitted for nested (fan-out) phases too, keyed by the nested phase's own name. */
|
|
42
|
+
export interface PhaseStartEvent {
|
|
43
|
+
type: "phase-start";
|
|
44
|
+
component: string;
|
|
45
|
+
phase: string;
|
|
46
|
+
}
|
|
47
|
+
/** A single capability step within a phase — one event when it starts, one when it settles. */
|
|
48
|
+
export interface StepEvent {
|
|
49
|
+
type: "step";
|
|
50
|
+
component: string;
|
|
51
|
+
phase: string;
|
|
52
|
+
step: string;
|
|
53
|
+
status: "running" | "ok" | "failed";
|
|
54
|
+
/** Present only alongside `status: "failed"`, when the capability threw. */
|
|
55
|
+
error?: string;
|
|
56
|
+
}
|
|
57
|
+
/** A phase finished — `ok` if every step in it succeeded, `failed` if any step failed (the phase's remaining steps were skipped, per the driver's fail-fast-within-a-phase semantics). */
|
|
58
|
+
export interface PhaseDoneEvent {
|
|
59
|
+
type: "phase-done";
|
|
60
|
+
component: string;
|
|
61
|
+
phase: string;
|
|
62
|
+
status: RunProgressStatus;
|
|
63
|
+
}
|
|
64
|
+
/** A component's `deploy` composition finished (after any saga rollback + component-level `rollback` phases the driver ran on failure). */
|
|
65
|
+
export interface ComponentDoneEvent {
|
|
66
|
+
type: "component-done";
|
|
67
|
+
wave: number;
|
|
68
|
+
component: string;
|
|
69
|
+
status: RunProgressStatus;
|
|
70
|
+
}
|
|
71
|
+
/** A wave finished — `failed` if any component in it failed, which also stops the run before any later wave starts. */
|
|
72
|
+
export interface WaveDoneEvent {
|
|
73
|
+
type: "wave-done";
|
|
74
|
+
wave: number;
|
|
75
|
+
status: RunProgressStatus;
|
|
76
|
+
}
|
|
77
|
+
/** The run finished. Mirrors the driver's own terminal `DriverRunResult.ok` / exit code. */
|
|
78
|
+
export interface RunDoneEvent {
|
|
79
|
+
type: "run-done";
|
|
80
|
+
status: RunProgressStatus;
|
|
81
|
+
}
|
|
82
|
+
export type RunProgressEvent = RunStartEvent | WaveStartEvent | ComponentStartEvent | PhaseStartEvent | StepEvent | PhaseDoneEvent | ComponentDoneEvent | WaveDoneEvent | RunDoneEvent;
|
|
83
|
+
/** A sink that receives progress events as they occur. The driver only ever calls this — it never writes to a stream directly, so it stays testable without stdout. */
|
|
84
|
+
export type RunProgressSink = (event: RunProgressEvent) => void;
|
|
85
|
+
/**
|
|
86
|
+
* Build a sink that writes `JSON.stringify(event) + "\n"` to `write` (default:
|
|
87
|
+
* `process.stdout.write`), one line per event, as they happen — the
|
|
88
|
+
* `--progress-json` CLI wiring's sink (../cli/handlers/run.ts). Kept separate
|
|
89
|
+
* from `driver-output.ts`'s end-of-run renderers: this emits *during* the
|
|
90
|
+
* run, one line at a time; `renderDriverJson`/`renderDriverHuman` render the
|
|
91
|
+
* completed `DriverRunResult` once, after the run finishes.
|
|
92
|
+
*/
|
|
93
|
+
export declare function ndjsonProgressSink(write?: (chunk: string) => void): RunProgressSink;
|
|
94
|
+
//# sourceMappingURL=run-progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-progress.d.ts","sourceRoot":"","sources":["../../src/components/run-progress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,oKAAoK;AACpK,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,QAAQ,CAAC;AAEhD,mMAAmM;AACnM,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC;CACnB;AAED,2GAA2G;AAC3G,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,4EAA4E;AAC5E,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,2JAA2J;AAC3J,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,+FAA+F;AAC/F,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,IAAI,GAAG,QAAQ,CAAC;IACpC,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,0LAA0L;AAC1L,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,YAAY,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,2IAA2I;AAC3I,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,gBAAgB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,uHAAuH;AACvH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,4FAA4F;AAC5F,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED,MAAM,MAAM,gBAAgB,GACxB,aAAa,GACb,cAAc,GACd,mBAAmB,GACnB,eAAe,GACf,SAAS,GACT,cAAc,GACd,kBAAkB,GAClB,aAAa,GACb,YAAY,CAAC;AAEjB,uKAAuK;AACvK,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAEhE;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,GAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAA0C,GAAG,eAAe,CAExH"}
|
|
@@ -58,6 +58,28 @@ export interface ComponentStatusRow {
|
|
|
58
58
|
reconciliation: "reconciled" | "unrecorded" | "stale" | "drifted" | "unknown";
|
|
59
59
|
/** Human-readable detail backing the verdict. */
|
|
60
60
|
detail: string;
|
|
61
|
+
/**
|
|
62
|
+
* Machine-readable "observed live", when live evidence was gathered (`--live`).
|
|
63
|
+
* A consumer joining this row onto a graph node should read this rather than
|
|
64
|
+
* string-matching `detail`. Absent when `--live` was not requested.
|
|
65
|
+
*/
|
|
66
|
+
live?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* The owning deploy unit's raw status, when a lexicon reported it (AWS: the
|
|
69
|
+
* component's own CFN stack via `describeStackStatus`). Lets a renderer paint a
|
|
70
|
+
* richer palette than the reconciliation verdict — `healthy` green,
|
|
71
|
+
* present-but-not-healthy amber (mid-deploy) / red (rollback/failed).
|
|
72
|
+
*/
|
|
73
|
+
stack?: LiveStackInfo;
|
|
74
|
+
}
|
|
75
|
+
/** A component's owning deploy unit and its provider-native status. */
|
|
76
|
+
export interface LiveStackInfo {
|
|
77
|
+
/** The deploy-unit name (e.g. the CloudFormation stack name). */
|
|
78
|
+
name: string;
|
|
79
|
+
/** Provider-native status string, e.g. "CREATE_COMPLETE". */
|
|
80
|
+
status?: string;
|
|
81
|
+
/** True when `status` is a terminal success state. */
|
|
82
|
+
healthy?: boolean;
|
|
61
83
|
}
|
|
62
84
|
export interface ComponentStatusResult {
|
|
63
85
|
env: string;
|
|
@@ -80,6 +102,9 @@ export interface LiveComponentEvidence {
|
|
|
80
102
|
action?: ChangeAction;
|
|
81
103
|
/** Ownership verdict, when known. */
|
|
82
104
|
ownership?: "owned" | "foreign" | "unknown";
|
|
105
|
+
/** The owning deploy unit's raw status, when observed (AWS: the component's own
|
|
106
|
+
* CFN stack). Surfaced onto `ComponentStatusRow.stack` for a richer palette. */
|
|
107
|
+
stack?: LiveStackInfo;
|
|
83
108
|
}
|
|
84
109
|
/**
|
|
85
110
|
* Overlay per-component stack-presence evidence onto change-set evidence.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lifecycle/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE5E,+FAA+F;AAC/F,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,+IAA+I;IAC/I,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,gDAAgD;IAChD,cAAc,EAAE,YAAY,GAAG,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IAC9E,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lifecycle/status.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -172,6 +172,8 @@ interface StatusJsonRow {
|
|
|
172
172
|
} | null;
|
|
173
173
|
reconciliation: string;
|
|
174
174
|
detail: string;
|
|
175
|
+
live?: boolean;
|
|
176
|
+
stack?: { name: string; status?: string; healthy?: boolean };
|
|
175
177
|
}
|
|
176
178
|
|
|
177
179
|
/**
|
|
@@ -237,7 +239,15 @@ async function observeComponentStacks(
|
|
|
237
239
|
const determinate = observed.filter((o): o is NonNullable<typeof o> => o !== null);
|
|
238
240
|
if (determinate.length === 0) continue;
|
|
239
241
|
const present = determinate.every((o) => o.present);
|
|
240
|
-
|
|
242
|
+
// Surface the (first present, else first) stack's raw status for a richer
|
|
243
|
+
// palette than the reconciliation verdict. One cfn-deploy stack per component
|
|
244
|
+
// is the norm; a multi-stack component reports its representative unit.
|
|
245
|
+
const repr = determinate.find((o) => o.present) ?? determinate[0];
|
|
246
|
+
evidence.set(name, {
|
|
247
|
+
live: present,
|
|
248
|
+
ownership: present ? "owned" : undefined,
|
|
249
|
+
stack: { name: repr.stack, status: repr.status, healthy: repr.healthy },
|
|
250
|
+
});
|
|
241
251
|
}
|
|
242
252
|
return evidence;
|
|
243
253
|
}
|
|
@@ -396,6 +406,8 @@ export async function runComponentsStatus(ctx: CommandContext): Promise<number>
|
|
|
396
406
|
: null,
|
|
397
407
|
reconciliation: row.reconciliation,
|
|
398
408
|
detail: row.detail,
|
|
409
|
+
...(row.live !== undefined ? { live: row.live } : {}),
|
|
410
|
+
...(row.stack ? { stack: row.stack } : {}),
|
|
399
411
|
});
|
|
400
412
|
}
|
|
401
413
|
}
|
|
@@ -945,6 +945,60 @@ describe("runOpComponents", () => {
|
|
|
945
945
|
vi.restoreAllMocks();
|
|
946
946
|
});
|
|
947
947
|
|
|
948
|
+
// ── --progress-json (M3, behold roadmap) ──────────────────────────────────
|
|
949
|
+
|
|
950
|
+
test("--progress-json streams NDJSON progress events to stdout as runComponents emits them", async () => {
|
|
951
|
+
runComponentsMock.mockImplementation(
|
|
952
|
+
async (_path: string, _selector: string, options: { onProgress?: (e: unknown) => void }) => {
|
|
953
|
+
options.onProgress?.({ type: "run-start", waves: [["svc"]] });
|
|
954
|
+
options.onProgress?.({ type: "run-done", status: "ok" });
|
|
955
|
+
return {
|
|
956
|
+
success: true,
|
|
957
|
+
selected: ["svc"],
|
|
958
|
+
run: { order: ["svc"], waves: [["svc"]], results: [{ component: "svc", ok: true, records: [] }], ok: true },
|
|
959
|
+
};
|
|
960
|
+
},
|
|
961
|
+
);
|
|
962
|
+
const stdoutWrite = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
|
|
963
|
+
vi.spyOn(process.stderr, "write").mockImplementation(() => true);
|
|
964
|
+
|
|
965
|
+
const exit = await runOpComponents({
|
|
966
|
+
args: makeArgs({ path: "svc", progressJson: true, temporal: false }),
|
|
967
|
+
plugins: [],
|
|
968
|
+
serializers: [],
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
expect(exit).toBe(0);
|
|
972
|
+
const lines = stdoutWrite.mock.calls.map((c) => String(c[0])).filter((s) => s.trim().length > 0);
|
|
973
|
+
expect(lines.map((l) => JSON.parse(l))).toEqual([
|
|
974
|
+
{ type: "run-start", waves: [["svc"]] },
|
|
975
|
+
{ type: "run-done", status: "ok" },
|
|
976
|
+
]);
|
|
977
|
+
// Every line is a single, complete JSON object — real NDJSON, not one big blob.
|
|
978
|
+
for (const line of lines) expect(() => JSON.parse(line)).not.toThrow();
|
|
979
|
+
vi.restoreAllMocks();
|
|
980
|
+
});
|
|
981
|
+
|
|
982
|
+
test("without --progress-json, runComponents receives onProgress: undefined and nothing streams", async () => {
|
|
983
|
+
runComponentsMock.mockResolvedValue({
|
|
984
|
+
success: true,
|
|
985
|
+
selected: ["svc"],
|
|
986
|
+
run: { order: ["svc"], waves: [["svc"]], results: [{ component: "svc", ok: true, records: [] }], ok: true },
|
|
987
|
+
});
|
|
988
|
+
const stdoutWrite = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
|
|
989
|
+
vi.spyOn(process.stderr, "write").mockImplementation(() => true);
|
|
990
|
+
|
|
991
|
+
await runOpComponents({ args: makeArgs({ path: "svc", temporal: false }), plugins: [], serializers: [] });
|
|
992
|
+
|
|
993
|
+
expect(runComponentsMock).toHaveBeenCalledWith(expect.any(String), "svc", {
|
|
994
|
+
env: undefined,
|
|
995
|
+
componentOutputs: {},
|
|
996
|
+
onProgress: undefined,
|
|
997
|
+
});
|
|
998
|
+
expect(stdoutWrite).not.toHaveBeenCalled();
|
|
999
|
+
vi.restoreAllMocks();
|
|
1000
|
+
});
|
|
1001
|
+
|
|
948
1002
|
test("all: dispatches the 'all' selector and renders every component", async () => {
|
|
949
1003
|
runComponentsMock.mockResolvedValue({
|
|
950
1004
|
success: true,
|
package/src/cli/handlers/run.ts
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
import { generateReport, writeReport } from "./run-report";
|
|
22
22
|
import { runComponents, resolveComponentTargets, findComponentGate, listComponents } from "../../components/cli-support";
|
|
23
23
|
import { renderDriverHuman, renderDriverJson } from "../../components/driver-output";
|
|
24
|
+
import { ndjsonProgressSink } from "../../components/run-progress";
|
|
24
25
|
import { loadComponentTemporalCodegen } from "../../components/temporal-codegen-loader";
|
|
25
26
|
import { applyConfigDefaults } from "../../components/config-defaults";
|
|
26
27
|
import { maybeRecordAutoRelease, extractRunDigestFromPhaseOutputs } from "../../components/auto-release";
|
|
@@ -686,7 +687,14 @@ export async function runOpComponents(ctx: CommandContext): Promise<number> {
|
|
|
686
687
|
return 1;
|
|
687
688
|
}
|
|
688
689
|
}
|
|
689
|
-
|
|
690
|
+
// `--progress-json` (#M3, behold roadmap): stream one NDJSON RunProgressEvent
|
|
691
|
+
// per line to stdout while the run executes, so a consumer (e.g. behold) can
|
|
692
|
+
// render live wave/component/phase/step progress instead of tailing raw
|
|
693
|
+
// logs. Purely additive: when the flag is absent, `onProgress` stays
|
|
694
|
+
// `undefined` and every `onProgress?.(...)` call in the driver is a no-op —
|
|
695
|
+
// behavior is byte-for-byte unchanged from before this flag existed.
|
|
696
|
+
const onProgress = ctx.args.progressJson ? ndjsonProgressSink() : undefined;
|
|
697
|
+
const result = await runComponents(resolve("."), selector, { env: ctx.args.env, componentOutputs: seededOutputs, onProgress });
|
|
690
698
|
|
|
691
699
|
// Dump the accumulated outputs for a downstream job to seed from. Written
|
|
692
700
|
// even on failure (partial outputs) so a resumed run still has what completed.
|
package/src/cli/main.test.ts
CHANGED
|
@@ -234,6 +234,20 @@ describe("parseArgs", () => {
|
|
|
234
234
|
const result = parseArgs(["run", "--components", "search-service"]);
|
|
235
235
|
expect(result.noReleaseRecord).toBeUndefined();
|
|
236
236
|
});
|
|
237
|
+
|
|
238
|
+
// ── --progress-json (M3, behold roadmap) ─────────────────────────────────
|
|
239
|
+
|
|
240
|
+
test("parses --progress-json for run --components", () => {
|
|
241
|
+
const result = parseArgs(["run", "--components", "search-service", "--env", "staging", "--progress-json"]);
|
|
242
|
+
expect(result.components).toBe(true);
|
|
243
|
+
expect(result.env).toBe("staging");
|
|
244
|
+
expect(result.progressJson).toBe(true);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
test("--progress-json is undefined (not false) when omitted", () => {
|
|
248
|
+
const result = parseArgs(["run", "--components", "search-service"]);
|
|
249
|
+
expect(result.progressJson).toBeUndefined();
|
|
250
|
+
});
|
|
237
251
|
});
|
|
238
252
|
|
|
239
253
|
// ── resolveCommand tests ──────────────────────────────────────────
|
package/src/cli/main.ts
CHANGED
|
@@ -172,6 +172,8 @@ export function parseArgs(args: string[]): ParsedArgs {
|
|
|
172
172
|
result.temporal = true;
|
|
173
173
|
} else if (arg === "--json") {
|
|
174
174
|
result.json = true;
|
|
175
|
+
} else if (arg === "--progress-json") {
|
|
176
|
+
result.progressJson = true;
|
|
175
177
|
} else if (arg === "--update-snapshot") {
|
|
176
178
|
result.updateSnapshot = true;
|
|
177
179
|
} else if (arg === "--run-examples") {
|
|
@@ -262,6 +264,11 @@ Ops:
|
|
|
262
264
|
On success, auto-emits a release-ledger record per
|
|
263
265
|
component that published a digest (default: on;
|
|
264
266
|
--no-release-record to opt out; #597)
|
|
267
|
+
--progress-json: stream one NDJSON RunProgressEvent
|
|
268
|
+
per line to stdout while the run executes, for a
|
|
269
|
+
consumer to render live wave/component/phase/step
|
|
270
|
+
progress instead of tailing raw logs (additive; run
|
|
271
|
+
semantics/exit code unchanged)
|
|
265
272
|
|
|
266
273
|
graph Show Op dependency graph (--stacks for cross-stack order,
|
|
267
274
|
--format ir|mermaid|dot|layout for the lint-gated graph IR,
|
package/src/cli/registry.ts
CHANGED
|
@@ -26,6 +26,8 @@ export interface ParsedArgs {
|
|
|
26
26
|
temporal?: boolean;
|
|
27
27
|
/** `chant run` — emit the structured OpRunResult as JSON on stdout. */
|
|
28
28
|
json?: boolean;
|
|
29
|
+
/** `chant run --components <name|all> --progress-json` — stream one NDJSON `RunProgressEvent` (../../components/run-progress.ts) per line to stdout while the run executes (local executor only), so a consumer can render live wave/component/phase/step progress instead of tailing raw logs. Purely additive: run semantics, ordering, and exit code are unchanged; omitted (undefined, not false) when the flag isn't passed. */
|
|
30
|
+
progressJson?: boolean;
|
|
29
31
|
live: boolean;
|
|
30
32
|
/** `chant migrate --from <name>` (default "github") */
|
|
31
33
|
migrateFrom?: string;
|
|
@@ -16,7 +16,7 @@ import Ajv2020 from "ajv/dist/2020";
|
|
|
16
16
|
import componentSchema from "./component.schema.json";
|
|
17
17
|
import { listComponents, describeComponent, computeComponentGraph, runComponents, findComponentGate } from "./cli-support";
|
|
18
18
|
import { CapabilityRegistry, type DeployContext } from "./capability";
|
|
19
|
-
import type { DriverComponent } from "./driver";
|
|
19
|
+
import type { DriverComponent, RunProgressEvent } from "./driver";
|
|
20
20
|
|
|
21
21
|
describe("listComponents", () => {
|
|
22
22
|
let testDir: string;
|
|
@@ -577,3 +577,94 @@ describe("runComponents", () => {
|
|
|
577
577
|
expect(capability.calls[0]?.input).toMatchObject({ format: "cyclonedx" });
|
|
578
578
|
});
|
|
579
579
|
});
|
|
580
|
+
|
|
581
|
+
describe("runComponents — onProgress (--progress-json wiring, M3)", () => {
|
|
582
|
+
let testDir: string;
|
|
583
|
+
|
|
584
|
+
beforeEach(async () => {
|
|
585
|
+
testDir = join(tmpdir(), `chant-run-components-progress-test-${Date.now()}-${Math.random()}`);
|
|
586
|
+
await mkdir(testDir, { recursive: true });
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
afterEach(async () => {
|
|
590
|
+
await rm(testDir, { recursive: true, force: true });
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
test("selector 'all': onProgress sees the same run-start/wave-*/component-*/run-done envelope runInterpretDriver emits", async () => {
|
|
594
|
+
await writeFile(
|
|
595
|
+
join(testDir, "alb.component.ts"),
|
|
596
|
+
`export const alb = { name: "shared-alb", dependsOn: [], deploy: [{ phase: "Apply", steps: [{ kind: "deploy-thing" }] }] };`,
|
|
597
|
+
);
|
|
598
|
+
await writeFile(
|
|
599
|
+
join(testDir, "svc.component.ts"),
|
|
600
|
+
`export const svc = { name: "search-service", dependsOn: ["shared-alb"], deploy: [{ phase: "Apply", steps: [{ kind: "deploy-thing" }] }] };`,
|
|
601
|
+
);
|
|
602
|
+
|
|
603
|
+
const registry = fakeRegistry();
|
|
604
|
+
const events: RunProgressEvent[] = [];
|
|
605
|
+
const result = await runComponents(testDir, "all", { registry, onProgress: (e) => events.push(e) });
|
|
606
|
+
|
|
607
|
+
expect(result.success).toBe(true);
|
|
608
|
+
expect(events[0]).toEqual({ type: "run-start", waves: [["shared-alb"], ["search-service"]] });
|
|
609
|
+
expect(events.at(-1)).toEqual({ type: "run-done", status: "ok" });
|
|
610
|
+
expect(events.filter((e) => e.type === "component-start")).toEqual([
|
|
611
|
+
{ type: "component-start", wave: 1, component: "shared-alb" },
|
|
612
|
+
{ type: "component-start", wave: 2, component: "search-service" },
|
|
613
|
+
]);
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
test("single-component selector: onProgress still gets a well-formed single-wave envelope (bypasses runInterpretDriver)", async () => {
|
|
617
|
+
await writeFile(
|
|
618
|
+
join(testDir, "svc.component.ts"),
|
|
619
|
+
`export const svc = { name: "svc", dependsOn: [], deploy: [{ phase: "Apply", steps: [{ kind: "deploy-thing" }] }] };`,
|
|
620
|
+
);
|
|
621
|
+
|
|
622
|
+
const registry = fakeRegistry();
|
|
623
|
+
const events: RunProgressEvent[] = [];
|
|
624
|
+
const result = await runComponents(testDir, "svc", { registry, onProgress: (e) => events.push(e) });
|
|
625
|
+
|
|
626
|
+
expect(result.success).toBe(true);
|
|
627
|
+
expect(events.map((e) => e.type)).toEqual([
|
|
628
|
+
"run-start",
|
|
629
|
+
"wave-start",
|
|
630
|
+
"component-start",
|
|
631
|
+
"phase-start",
|
|
632
|
+
"step",
|
|
633
|
+
"step",
|
|
634
|
+
"phase-done",
|
|
635
|
+
"component-done",
|
|
636
|
+
"wave-done",
|
|
637
|
+
"run-done",
|
|
638
|
+
]);
|
|
639
|
+
expect(events[0]).toEqual({ type: "run-start", waves: [["svc"]] });
|
|
640
|
+
expect(events[2]).toEqual({ type: "component-start", wave: 1, component: "svc" });
|
|
641
|
+
expect(events.at(-1)).toEqual({ type: "run-done", status: "ok" });
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
test("single-component selector: a failing step still yields component-done/wave-done/run-done status:\"failed\"", async () => {
|
|
645
|
+
await writeFile(
|
|
646
|
+
join(testDir, "svc.component.ts"),
|
|
647
|
+
`export const svc = { name: "svc", dependsOn: [], deploy: [{ phase: "Apply", steps: [{ kind: "deploy-thing" }] }] };`,
|
|
648
|
+
);
|
|
649
|
+
|
|
650
|
+
const registry = fakeRegistry({ failRun: true });
|
|
651
|
+
const events: RunProgressEvent[] = [];
|
|
652
|
+
const result = await runComponents(testDir, "svc", { registry, onProgress: (e) => events.push(e) });
|
|
653
|
+
|
|
654
|
+
expect(result.success).toBe(false);
|
|
655
|
+
expect(events.at(-3)).toEqual({ type: "component-done", wave: 1, component: "svc", status: "failed" });
|
|
656
|
+
expect(events.at(-2)).toEqual({ type: "wave-done", wave: 1, status: "failed" });
|
|
657
|
+
expect(events.at(-1)).toEqual({ type: "run-done", status: "failed" });
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
test("no onProgress passed → no behavior change (result identical, and it's simply never called)", async () => {
|
|
661
|
+
await writeFile(
|
|
662
|
+
join(testDir, "svc.component.ts"),
|
|
663
|
+
`export const svc = { name: "svc", dependsOn: [], deploy: [{ phase: "Apply", steps: [{ kind: "deploy-thing" }] }] };`,
|
|
664
|
+
);
|
|
665
|
+
|
|
666
|
+
const result = await runComponents(testDir, "svc", { registry: fakeRegistry() });
|
|
667
|
+
expect(result.success).toBe(true);
|
|
668
|
+
expect(result.run?.ok).toBe(true);
|
|
669
|
+
});
|
|
670
|
+
});
|