@agentic-workflow-kit/orchestrator 0.1.0

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 (86) hide show
  1. package/LICENSE +21 -0
  2. package/dist/analysis/runAnalyzer.d.ts +22 -0
  3. package/dist/analysis/runAnalyzer.d.ts.map +1 -0
  4. package/dist/analysis/runAnalyzer.js +177 -0
  5. package/dist/artifacts/FileArtifactStore.d.ts +9 -0
  6. package/dist/artifacts/FileArtifactStore.d.ts.map +1 -0
  7. package/dist/artifacts/FileArtifactStore.js +21 -0
  8. package/dist/cli/args.d.ts +5 -0
  9. package/dist/cli/args.d.ts.map +1 -0
  10. package/dist/cli/args.js +213 -0
  11. package/dist/cli.d.ts +9 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +284 -0
  14. package/dist/clock/SystemClock.d.ts +6 -0
  15. package/dist/clock/SystemClock.d.ts.map +1 -0
  16. package/dist/clock/SystemClock.js +8 -0
  17. package/dist/config/configLoader.d.ts +5 -0
  18. package/dist/config/configLoader.d.ts.map +1 -0
  19. package/dist/config/configLoader.js +105 -0
  20. package/dist/config/generate-schema.d.ts +2 -0
  21. package/dist/config/generate-schema.d.ts.map +1 -0
  22. package/dist/config/generate-schema.js +8 -0
  23. package/dist/config/jsonSchema.d.ts +3 -0
  24. package/dist/config/jsonSchema.d.ts.map +1 -0
  25. package/dist/config/jsonSchema.js +44 -0
  26. package/dist/config/preset.d.ts +16 -0
  27. package/dist/config/preset.d.ts.map +1 -0
  28. package/dist/config/preset.js +14 -0
  29. package/dist/config/resolve.d.ts +12 -0
  30. package/dist/config/resolve.d.ts.map +1 -0
  31. package/dist/config/resolve.js +30 -0
  32. package/dist/config/schema.d.ts +68 -0
  33. package/dist/config/schema.d.ts.map +1 -0
  34. package/dist/config/schema.js +80 -0
  35. package/dist/drivers/StoryRunner.d.ts +24 -0
  36. package/dist/drivers/StoryRunner.d.ts.map +1 -0
  37. package/dist/drivers/StoryRunner.js +1 -0
  38. package/dist/drivers/codex-mcp/CodexMcpStoryRunner.d.ts +25 -0
  39. package/dist/drivers/codex-mcp/CodexMcpStoryRunner.d.ts.map +1 -0
  40. package/dist/drivers/codex-mcp/CodexMcpStoryRunner.js +145 -0
  41. package/dist/drivers/codex-mcp/schemaValidation.d.ts +7 -0
  42. package/dist/drivers/codex-mcp/schemaValidation.d.ts.map +1 -0
  43. package/dist/drivers/codex-mcp/schemaValidation.js +43 -0
  44. package/dist/drivers/codex-mcp/toolInput.d.ts +12 -0
  45. package/dist/drivers/codex-mcp/toolInput.d.ts.map +1 -0
  46. package/dist/drivers/codex-mcp/toolInput.js +82 -0
  47. package/dist/git/GitInspector.d.ts +34 -0
  48. package/dist/git/GitInspector.d.ts.map +1 -0
  49. package/dist/git/GitInspector.js +73 -0
  50. package/dist/index.d.ts +11 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +9 -0
  53. package/dist/internal/guards.d.ts +4 -0
  54. package/dist/internal/guards.d.ts.map +1 -0
  55. package/dist/internal/guards.js +9 -0
  56. package/dist/logging/ConsoleLogger.d.ts +7 -0
  57. package/dist/logging/ConsoleLogger.d.ts.map +1 -0
  58. package/dist/logging/ConsoleLogger.js +16 -0
  59. package/dist/metrics/aggregate.d.ts +6 -0
  60. package/dist/metrics/aggregate.d.ts.map +1 -0
  61. package/dist/metrics/aggregate.js +32 -0
  62. package/dist/metrics/liveMetrics.d.ts +16 -0
  63. package/dist/metrics/liveMetrics.d.ts.map +1 -0
  64. package/dist/metrics/liveMetrics.js +16 -0
  65. package/dist/runner/CompletionGate.d.ts +25 -0
  66. package/dist/runner/CompletionGate.d.ts.map +1 -0
  67. package/dist/runner/CompletionGate.js +49 -0
  68. package/dist/runner/MetricsCollector.d.ts +27 -0
  69. package/dist/runner/MetricsCollector.d.ts.map +1 -0
  70. package/dist/runner/MetricsCollector.js +49 -0
  71. package/dist/runner/RunJournal.d.ts +32 -0
  72. package/dist/runner/RunJournal.d.ts.map +1 -0
  73. package/dist/runner/RunJournal.js +78 -0
  74. package/dist/runner/WorkflowRunner.d.ts +45 -0
  75. package/dist/runner/WorkflowRunner.d.ts.map +1 -0
  76. package/dist/runner/WorkflowRunner.js +289 -0
  77. package/dist/scheduler/scheduler.d.ts +8 -0
  78. package/dist/scheduler/scheduler.d.ts.map +1 -0
  79. package/dist/scheduler/scheduler.js +8 -0
  80. package/dist/tracks/markdownTracker.d.ts +29 -0
  81. package/dist/tracks/markdownTracker.d.ts.map +1 -0
  82. package/dist/tracks/markdownTracker.js +349 -0
  83. package/dist/types.d.ts +222 -0
  84. package/dist/types.d.ts.map +1 -0
  85. package/dist/types.js +1 -0
  86. package/package.json +75 -0
@@ -0,0 +1,32 @@
1
+ export function mergeChildMetrics(children) {
2
+ const toolCounts = {};
3
+ const subagentCounts = {};
4
+ let tokenTotals = emptyTokenTotals();
5
+ let sawTokens = false;
6
+ for (const child of children) {
7
+ mergeCounts(toolCounts, child.toolCounts);
8
+ mergeCounts(subagentCounts, child.subagentCounts);
9
+ if (child.tokenTotals) {
10
+ sawTokens = true;
11
+ tokenTotals = addTokenTotals(tokenTotals, child.tokenTotals);
12
+ }
13
+ }
14
+ return { toolCounts, subagentCounts, tokenTotals: sawTokens ? tokenTotals : null };
15
+ }
16
+ export function addTokenTotals(a, b) {
17
+ return {
18
+ inputTokens: a.inputTokens + b.inputTokens,
19
+ cachedInputTokens: a.cachedInputTokens + b.cachedInputTokens,
20
+ outputTokens: a.outputTokens + b.outputTokens,
21
+ reasoningOutputTokens: a.reasoningOutputTokens + b.reasoningOutputTokens,
22
+ totalTokens: a.totalTokens + b.totalTokens,
23
+ };
24
+ }
25
+ export function mergeCounts(target, source) {
26
+ for (const [key, value] of Object.entries(source)) {
27
+ target[key] = (target[key] ?? 0) + value;
28
+ }
29
+ }
30
+ export function emptyTokenTotals() {
31
+ return { inputTokens: 0, cachedInputTokens: 0, outputTokens: 0, reasoningOutputTokens: 0, totalTokens: 0 };
32
+ }
@@ -0,0 +1,16 @@
1
+ import type { ChildMetricsSnapshot, LiveMetricsSnapshot, RunStatus } from '../types.js';
2
+ export interface BuildLiveMetricsInput {
3
+ runId: string;
4
+ status: RunStatus;
5
+ startedAt: string;
6
+ now: string;
7
+ maxParallel: number;
8
+ active: string[];
9
+ completed: unknown[];
10
+ blockedStoryId: string | null;
11
+ blockedReason: string | null;
12
+ childMetrics: Record<string, ChildMetricsSnapshot>;
13
+ }
14
+ export declare function buildLiveMetricsSnapshot(input: BuildLiveMetricsInput): LiveMetricsSnapshot;
15
+ export { mergeChildMetrics } from './aggregate.js';
16
+ //# sourceMappingURL=liveMetrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liveMetrics.d.ts","sourceRoot":"","sources":["../../src/metrics/liveMetrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxF,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CACpD;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,qBAAqB,GAAG,mBAAmB,CAa1F;AAED,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { mergeChildMetrics } from './aggregate.js';
2
+ export function buildLiveMetricsSnapshot(input) {
3
+ return {
4
+ runId: input.runId,
5
+ status: input.status,
6
+ elapsedMs: Date.parse(input.now) - Date.parse(input.startedAt),
7
+ maxParallel: input.maxParallel,
8
+ active: input.active,
9
+ completedCount: input.completed.length,
10
+ blockedStoryId: input.blockedStoryId,
11
+ blockedReason: input.blockedReason,
12
+ children: input.childMetrics,
13
+ aggregate: mergeChildMetrics(Object.values(input.childMetrics)),
14
+ };
15
+ }
16
+ export { mergeChildMetrics } from './aggregate.js';
@@ -0,0 +1,25 @@
1
+ import type { GitInspector, StoryCommitEvidence } from '../git/GitInspector.js';
2
+ import type { ResolvedGitConfig, ResolvedWorkflowConfig, WorkflowStory } from '../types.js';
3
+ import type { SettledStoryRun } from './RunJournal.js';
4
+ export type ReturnEvaluation = {
5
+ complete: true;
6
+ returnedStory: WorkflowStory;
7
+ commitEvidence?: StoryCommitEvidence;
8
+ } | {
9
+ complete: false;
10
+ returnedStory: WorkflowStory | null;
11
+ reason: string;
12
+ commitEvidence?: StoryCommitEvidence;
13
+ };
14
+ export interface CompletionGateDeps {
15
+ gitInspector: GitInspector;
16
+ statuses: ResolvedWorkflowConfig['statuses'];
17
+ git: ResolvedGitConfig;
18
+ childCwdAbs: string;
19
+ }
20
+ export declare class CompletionGate {
21
+ private readonly deps;
22
+ constructor(deps: CompletionGateDeps);
23
+ evaluate(settled: SettledStoryRun, stories: WorkflowStory[]): Promise<ReturnEvaluation>;
24
+ }
25
+ //# sourceMappingURL=CompletionGate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompletionGate.d.ts","sourceRoot":"","sources":["../../src/runner/CompletionGate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAEhF,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,EAAE,IAAI,CAAC;IAAC,aAAa,EAAE,aAAa,CAAC;IAAC,cAAc,CAAC,EAAE,mBAAmB,CAAA;CAAE,GACtF;IAAE,QAAQ,EAAE,KAAK,CAAC;IAAC,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAEnH,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAC7C,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,cAAc;IACb,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE,kBAAkB;IAE/C,QAAQ,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAqC9F"}
@@ -0,0 +1,49 @@
1
+ import { isCompleteStatus } from '../scheduler/scheduler.js';
2
+ export class CompletionGate {
3
+ deps;
4
+ constructor(deps) {
5
+ this.deps = deps;
6
+ }
7
+ async evaluate(settled, stories) {
8
+ const returnedStory = stories.find((entry) => entry.id === settled.storyId) ?? null;
9
+ if (!returnedStory) {
10
+ return {
11
+ complete: false,
12
+ returnedStory,
13
+ reason: `${settled.storyId} returned but story source no longer contains it`,
14
+ };
15
+ }
16
+ if (!isCompleteStatus(returnedStory.status, this.deps.statuses.complete)) {
17
+ return {
18
+ complete: false,
19
+ returnedStory,
20
+ reason: `${settled.storyId} returned but status is ${returnedStory.status}`,
21
+ };
22
+ }
23
+ let commitEvidence;
24
+ try {
25
+ commitEvidence = await this.deps.gitInspector.inspectStory({
26
+ story: returnedStory,
27
+ git: this.deps.git,
28
+ cwdAbs: invocationCwd(settled) ?? this.deps.childCwdAbs,
29
+ baseShaAtLaunch: settled.baseShaAtLaunch,
30
+ });
31
+ }
32
+ catch (error) {
33
+ const message = error instanceof Error ? error.message : String(error);
34
+ return { complete: false, returnedStory, reason: `inspect-failed: ${message}` };
35
+ }
36
+ const dirtyBlocks = this.deps.git.strategy !== 'worktree' && commitEvidence.uncommittedChanges;
37
+ if (!commitEvidence.committed || dirtyBlocks) {
38
+ return { complete: false, returnedStory, reason: 'complete-but-uncommitted', commitEvidence };
39
+ }
40
+ if (this.deps.git.commitOnBase === 'forbid' && commitEvidence.isBaseBranch) {
41
+ return { complete: false, returnedStory, reason: 'complete-on-forbidden-base', commitEvidence };
42
+ }
43
+ return { complete: true, returnedStory, commitEvidence };
44
+ }
45
+ }
46
+ function invocationCwd(settled) {
47
+ const cwd = settled.invocation?.cwd;
48
+ return typeof cwd === 'string' && cwd.length > 0 ? cwd : null;
49
+ }
@@ -0,0 +1,27 @@
1
+ import type { ChildMetricsSnapshot, Clock, RunMetrics, RunStatus } from '../types.js';
2
+ interface ChildTiming {
3
+ startedAt: string;
4
+ completedAt?: string;
5
+ durationMs?: number;
6
+ }
7
+ export interface BuildRunMetricsInput {
8
+ startedAt: string;
9
+ completedAt?: string;
10
+ completedCount: number;
11
+ status: RunStatus;
12
+ blockedReason: string | null;
13
+ }
14
+ export declare class MetricsCollector {
15
+ private readonly clock;
16
+ private readonly childMetrics;
17
+ private readonly observedMetrics;
18
+ constructor(clock: Clock);
19
+ start(storyId: string): string;
20
+ complete(storyId: string): string;
21
+ updateChildMetric(storyId: string, metrics: ChildMetricsSnapshot): void;
22
+ childTiming(storyId: string): ChildTiming | undefined;
23
+ observedChildMetrics(): Record<string, ChildMetricsSnapshot>;
24
+ buildRunMetrics(input: BuildRunMetricsInput): RunMetrics;
25
+ }
26
+ export {};
27
+ //# sourceMappingURL=MetricsCollector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MetricsCollector.d.ts","sourceRoot":"","sources":["../../src/runner/MetricsCollector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAkB,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEtG,UAAU,WAAW;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,SAAS,CAAC;IAClB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,qBAAa,gBAAgB;IAIf,OAAO,CAAC,QAAQ,CAAC,KAAK;IAHlC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAC/D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA4C;gBAE/C,KAAK,EAAE,KAAK;IAEzC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAM9B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAajC,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAIvE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIrD,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC;IAI5D,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,UAAU;CAkBzD"}
@@ -0,0 +1,49 @@
1
+ export class MetricsCollector {
2
+ clock;
3
+ childMetrics = new Map();
4
+ observedMetrics = {};
5
+ constructor(clock) {
6
+ this.clock = clock;
7
+ }
8
+ start(storyId) {
9
+ const startedAt = this.clock.now();
10
+ this.childMetrics.set(storyId, { startedAt });
11
+ return startedAt;
12
+ }
13
+ complete(storyId) {
14
+ const completedAt = this.clock.now();
15
+ const existing = this.childMetrics.get(storyId);
16
+ if (existing) {
17
+ this.childMetrics.set(storyId, {
18
+ ...existing,
19
+ completedAt,
20
+ durationMs: Date.parse(completedAt) - Date.parse(existing.startedAt),
21
+ });
22
+ }
23
+ return completedAt;
24
+ }
25
+ updateChildMetric(storyId, metrics) {
26
+ this.observedMetrics[storyId] = metrics;
27
+ }
28
+ childTiming(storyId) {
29
+ return this.childMetrics.get(storyId);
30
+ }
31
+ observedChildMetrics() {
32
+ return this.observedMetrics;
33
+ }
34
+ buildRunMetrics(input) {
35
+ const completedChildren = [...this.childMetrics.entries()]
36
+ .flatMap(([storyId, metric]) => metric.completedAt && metric.durationMs !== undefined
37
+ ? [{ storyId, startedAt: metric.startedAt, completedAt: metric.completedAt, durationMs: metric.durationMs }]
38
+ : [])
39
+ .sort((left, right) => left.startedAt.localeCompare(right.startedAt));
40
+ return {
41
+ elapsedMs: input.completedAt ? Date.parse(input.completedAt) - Date.parse(input.startedAt) : 0,
42
+ launchedCount: this.childMetrics.size,
43
+ completedCount: input.completedCount,
44
+ blockedCount: input.status === 'blocked' ? 1 : 0,
45
+ blockedReason: input.blockedReason,
46
+ criticalPath: completedChildren,
47
+ };
48
+ }
49
+ }
@@ -0,0 +1,32 @@
1
+ import type { StoryCommitEvidence } from '../git/GitInspector.js';
2
+ import type { ArtifactStore, ChildMetricsSnapshot, Clock, ResolvedWorkflowConfig, RunState, WorkflowStory } from '../types.js';
3
+ import type { MetricsCollector } from './MetricsCollector.js';
4
+ export interface SettledStoryRun {
5
+ storyId: string;
6
+ ok: boolean;
7
+ sessionId: string | null;
8
+ content?: string;
9
+ rawResult?: unknown;
10
+ invocation?: Record<string, unknown>;
11
+ error?: string;
12
+ completedAt: string;
13
+ metrics?: ChildMetricsSnapshot;
14
+ commitEvidence?: StoryCommitEvidence;
15
+ baseShaAtLaunch?: string | null;
16
+ }
17
+ export interface RunJournalDependencies {
18
+ artifactStore: ArtifactStore;
19
+ clock: Clock;
20
+ }
21
+ export declare class RunJournal {
22
+ private readonly dependencies;
23
+ constructor(dependencies: RunJournalDependencies);
24
+ writeRunMetadata(state: RunState): Promise<void>;
25
+ writeConfigSnapshot(config: ResolvedWorkflowConfig): Promise<void>;
26
+ writeState(state: RunState): Promise<void>;
27
+ writeLiveMetrics(state: RunState, childMetrics: Record<string, ChildMetricsSnapshot>): Promise<void>;
28
+ writeStorySnapshot(label: string, stories: WorkflowStory[]): Promise<void>;
29
+ recordSettledChild(metrics: MetricsCollector, settled: SettledStoryRun, returnedStory?: Pick<WorkflowStory, 'status'> | null, returnedComplete?: boolean | null): Promise<RunState['completed'][number]>;
30
+ record(type: string, fields?: Record<string, unknown>): Promise<void>;
31
+ }
32
+ //# sourceMappingURL=RunJournal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RunJournal.d.ts","sourceRoot":"","sources":["../../src/runner/RunJournal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAGlE,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACpB,KAAK,EACL,sBAAsB,EACtB,QAAQ,EACR,aAAa,EACd,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,oBAAoB,CAAC;IAC/B,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACrC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,KAAK,CAAC;CACd;AAED,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,EAAE,sBAAsB;IAE3D,gBAAgB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhD,mBAAmB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlE,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,gBAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBpG,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ1E,kBAAkB,CACtB,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,eAAe,EACxB,aAAa,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,GAAG,IAAI,EACpD,gBAAgB,CAAC,EAAE,OAAO,GAAG,IAAI,GAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;IA+BnC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAOhF"}
@@ -0,0 +1,78 @@
1
+ import path from 'node:path';
2
+ import { safeName } from '../internal/guards.js';
3
+ import { buildLiveMetricsSnapshot } from '../metrics/liveMetrics.js';
4
+ export class RunJournal {
5
+ dependencies;
6
+ constructor(dependencies) {
7
+ this.dependencies = dependencies;
8
+ }
9
+ async writeRunMetadata(state) {
10
+ await this.dependencies.artifactStore.writeJson('run.json', {
11
+ runId: state.runId,
12
+ command: state.command,
13
+ workspaceRoot: state.workspaceRoot,
14
+ artifactDir: state.artifactDir,
15
+ startedAt: state.startedAt,
16
+ });
17
+ }
18
+ async writeConfigSnapshot(config) {
19
+ await this.dependencies.artifactStore.writeJson('config.resolved.json', config);
20
+ }
21
+ async writeState(state) {
22
+ await this.dependencies.artifactStore.writeJson('state.json', state);
23
+ }
24
+ async writeLiveMetrics(state, childMetrics) {
25
+ await this.dependencies.artifactStore.writeJson('metrics.live.json', buildLiveMetricsSnapshot({
26
+ runId: state.runId,
27
+ status: state.status,
28
+ startedAt: state.startedAt,
29
+ now: this.dependencies.clock.now(),
30
+ maxParallel: state.maxParallel,
31
+ active: state.active,
32
+ completed: state.completed,
33
+ blockedStoryId: state.blockedStoryId,
34
+ blockedReason: state.blockedReason,
35
+ childMetrics,
36
+ }));
37
+ }
38
+ async writeStorySnapshot(label, stories) {
39
+ const fileName = `${safeName(label)}.json`;
40
+ await this.dependencies.artifactStore.writeJson(path.join('stories', fileName), stories);
41
+ if (label === 'initial') {
42
+ await this.dependencies.artifactStore.writeJson('stories.initial.json', stories);
43
+ }
44
+ }
45
+ async recordSettledChild(metrics, settled, returnedStory, returnedComplete) {
46
+ const childMetric = metrics.childTiming(settled.storyId);
47
+ const returnedStatus = returnedStory?.status ?? null;
48
+ const normalizedReturnedComplete = returnedComplete ?? null;
49
+ const augmentedSettled = {
50
+ ...settled,
51
+ startedAt: childMetric?.startedAt,
52
+ durationMs: childMetric?.durationMs,
53
+ returnedStatus,
54
+ returnedComplete: normalizedReturnedComplete,
55
+ };
56
+ await this.dependencies.artifactStore.writeJson(`children/${safeName(settled.storyId)}.json`, augmentedSettled);
57
+ if (settled.rawResult !== undefined) {
58
+ await this.dependencies.artifactStore.writeJson(`children/${safeName(settled.storyId)}.raw.json`, settled.rawResult);
59
+ }
60
+ return {
61
+ storyId: settled.storyId,
62
+ ok: settled.ok,
63
+ sessionId: settled.sessionId,
64
+ completedAt: settled.completedAt,
65
+ startedAt: childMetric?.startedAt,
66
+ durationMs: childMetric?.durationMs,
67
+ returnedStatus,
68
+ returnedComplete: normalizedReturnedComplete,
69
+ };
70
+ }
71
+ async record(type, fields = {}) {
72
+ await this.dependencies.artifactStore.appendEvent({
73
+ ts: this.dependencies.clock.now(),
74
+ type,
75
+ ...fields,
76
+ });
77
+ }
78
+ }
@@ -0,0 +1,45 @@
1
+ import type { StoryRunner } from '../drivers/StoryRunner.js';
2
+ import type { GitInspector } from '../git/GitInspector.js';
3
+ import type { ArtifactStore, Clock, Logger, ResolvedWorkflowConfig, RunState, StorySource, WorkflowStory } from '../types.js';
4
+ export interface WorkflowRunnerDependencies {
5
+ command: string;
6
+ config: ResolvedWorkflowConfig;
7
+ storySource: StorySource;
8
+ storyRunner: StoryRunner;
9
+ gitInspector: GitInspector;
10
+ artifactStore: ArtifactStore;
11
+ logger: Logger;
12
+ clock: Clock;
13
+ runId: string;
14
+ childTimer?: ChildTimer;
15
+ }
16
+ export interface ChildTimer {
17
+ setTimeout(callback: () => void, ms: number): unknown;
18
+ clearTimeout(handle: unknown): void;
19
+ setInterval(callback: () => void, ms: number): unknown;
20
+ clearInterval(handle: unknown): void;
21
+ }
22
+ export declare class WorkflowRunner {
23
+ private readonly dependencies;
24
+ private state;
25
+ private readonly metrics;
26
+ private readonly journal;
27
+ private readonly completionGate;
28
+ constructor(dependencies: WorkflowRunnerDependencies);
29
+ listEligible(): Promise<WorkflowStory[]>;
30
+ dryRunEligible(): Promise<RunState>;
31
+ runStory(storyId: string, options?: {
32
+ force?: boolean;
33
+ }): Promise<RunState>;
34
+ runEligible(): Promise<RunState>;
35
+ private launchChild;
36
+ private recordChildLaunch;
37
+ private executeChild;
38
+ private processSettled;
39
+ private recordSettledChild;
40
+ private blockOnce;
41
+ private finish;
42
+ private writeState;
43
+ private writeLiveMetrics;
44
+ }
45
+ //# sourceMappingURL=WorkflowRunner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkflowRunner.d.ts","sourceRoot":"","sources":["../../src/runner/WorkflowRunner.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,2BAA2B,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAG3D,OAAO,KAAK,EACV,aAAa,EACb,KAAK,EACL,MAAM,EACN,sBAAsB,EACtB,QAAQ,EACR,WAAW,EACX,aAAa,EACd,MAAM,aAAa,CAAC;AAKrB,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,EAAE,YAAY,CAAC;IAC3B,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACtD,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACpC,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACvD,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;CACtC;AASD,qBAAa,cAAc;IAMb,OAAO,CAAC,QAAQ,CAAC,YAAY;IALzC,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;gBAEnB,YAAY,EAAE,0BAA0B;IAwB/D,YAAY,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAKxC,cAAc,IAAI,OAAO,CAAC,QAAQ,CAAC;IAenC,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAwC/E,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC;YA2ExB,WAAW;YAKX,iBAAiB;YAQjB,YAAY;YA+DZ,cAAc;YAWd,kBAAkB;IAWhC,OAAO,CAAC,SAAS;YAMH,MAAM;YAyBN,UAAU;YAIV,gBAAgB;CAG/B"}