@crewx/workflow 0.3.22-rc.13 → 0.3.22-rc.131

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 (38) hide show
  1. package/SKILL.md +38 -2
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +78 -9
  4. package/dist/cli.js.map +1 -1
  5. package/dist/src/engine.d.ts +4 -2
  6. package/dist/src/engine.d.ts.map +1 -1
  7. package/dist/src/engine.js +57 -2
  8. package/dist/src/engine.js.map +1 -1
  9. package/dist/src/failure.d.ts +41 -0
  10. package/dist/src/failure.d.ts.map +1 -0
  11. package/dist/src/failure.js +122 -0
  12. package/dist/src/failure.js.map +1 -0
  13. package/dist/src/mermaid.d.ts.map +1 -1
  14. package/dist/src/mermaid.js +7 -4
  15. package/dist/src/mermaid.js.map +1 -1
  16. package/dist/src/parent-task-sync.d.ts +49 -0
  17. package/dist/src/parent-task-sync.d.ts.map +1 -0
  18. package/dist/src/parent-task-sync.js +132 -0
  19. package/dist/src/parent-task-sync.js.map +1 -0
  20. package/dist/src/retry-policy.d.ts +38 -0
  21. package/dist/src/retry-policy.d.ts.map +1 -0
  22. package/dist/src/retry-policy.js +140 -0
  23. package/dist/src/retry-policy.js.map +1 -0
  24. package/dist/src/run-manager.d.ts +28 -2
  25. package/dist/src/run-manager.d.ts.map +1 -1
  26. package/dist/src/run-manager.js +935 -210
  27. package/dist/src/run-manager.js.map +1 -1
  28. package/dist/src/types.d.ts +39 -4
  29. package/dist/src/types.d.ts.map +1 -1
  30. package/dist/src/types.js +2 -0
  31. package/dist/src/types.js.map +1 -1
  32. package/dist/src/utils/output-format.d.ts +12 -0
  33. package/dist/src/utils/output-format.d.ts.map +1 -1
  34. package/dist/src/utils/output-format.js +103 -5
  35. package/dist/src/utils/output-format.js.map +1 -1
  36. package/dist/workflow-schema.json +34 -5
  37. package/package.json +14 -4
  38. package/workflow-schema.json +34 -5
@@ -0,0 +1,41 @@
1
+ import type { RunExecution, WorkflowFailureCode, WorkflowNodeFailure } from './types';
2
+ export type WorkflowErrorOrigin = 'spawn' | 'post_spawn' | 'stdin' | null;
3
+ export interface ProcessFailureMetadata {
4
+ status: number | null;
5
+ timedOut: boolean;
6
+ signal: NodeJS.Signals | null;
7
+ errorOrigin: WorkflowErrorOrigin;
8
+ }
9
+ export type PersistedWorkflowFailureCode = Exclude<WorkflowFailureCode, 'RATE_LIMITED'>;
10
+ export interface WorkflowFailureClassificationInput {
11
+ errorCode?: unknown;
12
+ process?: ProcessFailureMetadata;
13
+ }
14
+ export declare function getStableCauseMessage(code: PersistedWorkflowFailureCode): string;
15
+ export declare function createWorkflowFailureError(code: PersistedWorkflowFailureCode, message: string): Error & {
16
+ code: PersistedWorkflowFailureCode;
17
+ };
18
+ export declare function getWorkflowFailureCode(error: unknown): PersistedWorkflowFailureCode | undefined;
19
+ export declare function classifyWorkflowFailure(input: WorkflowFailureClassificationInput): PersistedWorkflowFailureCode;
20
+ export interface NodeFailureInput {
21
+ failedNode: string;
22
+ attempt: number;
23
+ causeCode: PersistedWorkflowFailureCode;
24
+ exitCode: number | null;
25
+ signal: NodeJS.Signals | null;
26
+ errorOrigin: WorkflowErrorOrigin;
27
+ timedOut?: boolean;
28
+ occurredAt?: string;
29
+ }
30
+ export declare function buildNodeFailure(input: NodeFailureInput): WorkflowNodeFailure;
31
+ export interface EvidenceInput {
32
+ causeCode: PersistedWorkflowFailureCode;
33
+ exitCode: number | null;
34
+ signal: NodeJS.Signals | null;
35
+ errorOrigin: WorkflowErrorOrigin;
36
+ timedOut: boolean;
37
+ }
38
+ export declare function buildEvidencePreview(input: EvidenceInput): string | null;
39
+ export declare function sanitizeLocalRunError(raw: unknown, fallback: string): string;
40
+ export declare function readNodeAttempt(run: RunExecution, nodeId: string): number;
41
+ //# sourceMappingURL=failure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failure.d.ts","sourceRoot":"","sources":["../../src/failure.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,SAAS,CAAC;AAGjB,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,YAAY,GAAG,OAAO,GAAG,IAAI,CAAC;AAG1E,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,mBAAmB,CAAC;CAClC;AAGD,MAAM,MAAM,4BAA4B,GAAG,OAAO,CAAC,mBAAmB,EAAE,cAAc,CAAC,CAAC;AAGxF,MAAM,WAAW,kCAAkC;IACjD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,sBAAsB,CAAC;CAClC;AAoBD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,4BAA4B,GAAG,MAAM,CAEhF;AAGD,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,4BAA4B,EAClC,OAAO,EAAE,MAAM,GACd,KAAK,GAAG;IAAE,IAAI,EAAE,4BAA4B,CAAA;CAAE,CAIhD;AAGD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,4BAA4B,GAAG,SAAS,CAM/F;AAMD,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,kCAAkC,GACxC,4BAA4B,CAqB9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,4BAA4B,CAAC;IACxC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,mBAAmB,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAKD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,gBAAgB,GAAG,mBAAmB,CAqB7E;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,4BAA4B,CAAC;IACxC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,mBAAmB,CAAC;IACjC,QAAQ,EAAE,OAAO,CAAC;CACnB;AAKD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAiBxE;AAGD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM5E;AAGD,wBAAgB,eAAe,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGzE"}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getStableCauseMessage = getStableCauseMessage;
4
+ exports.createWorkflowFailureError = createWorkflowFailureError;
5
+ exports.getWorkflowFailureCode = getWorkflowFailureCode;
6
+ exports.classifyWorkflowFailure = classifyWorkflowFailure;
7
+ exports.buildNodeFailure = buildNodeFailure;
8
+ exports.buildEvidencePreview = buildEvidencePreview;
9
+ exports.sanitizeLocalRunError = sanitizeLocalRunError;
10
+ exports.readNodeAttempt = readNodeAttempt;
11
+ const sdk_1 = require("@crewx/sdk");
12
+ const STABLE_CAUSE_MESSAGES = {
13
+ CLI_UNRESOLVABLE: 'CrewX CLI executable could not be resolved.',
14
+ SPAWN_FAILED: 'The node process could not be started.',
15
+ NODE_TIMEOUT: 'The node execution exceeded its timeout.',
16
+ NODE_EXIT_NONZERO: 'The node process exited with a non-zero status.',
17
+ OUTPUT_INVALID: 'The node output did not match the required format.',
18
+ CONFIG_INVALID: 'The workflow node configuration is invalid.',
19
+ INTERRUPTED: 'The node execution was interrupted.',
20
+ CANCELLED: 'The workflow run was cancelled.',
21
+ UNKNOWN: 'The node execution failed.',
22
+ };
23
+ const PERSISTED_FAILURE_CODES = new Set(Object.keys(STABLE_CAUSE_MESSAGES));
24
+ function getStableCauseMessage(code) {
25
+ return STABLE_CAUSE_MESSAGES[code];
26
+ }
27
+ function createWorkflowFailureError(code, message) {
28
+ const error = new Error(message);
29
+ error.code = code;
30
+ return error;
31
+ }
32
+ function getWorkflowFailureCode(error) {
33
+ if (!error || typeof error !== 'object')
34
+ return undefined;
35
+ const code = error.code;
36
+ return typeof code === 'string' && PERSISTED_FAILURE_CODES.has(code)
37
+ ? code
38
+ : undefined;
39
+ }
40
+ function classifyWorkflowFailure(input) {
41
+ const typedCode = input.errorCode;
42
+ if (typedCode === 'CLI_UNRESOLVABLE')
43
+ return 'CLI_UNRESOLVABLE';
44
+ if (typedCode === 'CONFIG_INVALID')
45
+ return 'CONFIG_INVALID';
46
+ if (typedCode === 'OUTPUT_INVALID')
47
+ return 'OUTPUT_INVALID';
48
+ if (typedCode === 'CANCELLED')
49
+ return 'CANCELLED';
50
+ if (typedCode === 'INTERRUPTED')
51
+ return 'INTERRUPTED';
52
+ if (typedCode === 'UNKNOWN')
53
+ return 'UNKNOWN';
54
+ const processResult = input.process;
55
+ if (!processResult)
56
+ return 'UNKNOWN';
57
+ if (processResult.errorOrigin === 'spawn')
58
+ return 'SPAWN_FAILED';
59
+ if (processResult.timedOut)
60
+ return 'NODE_TIMEOUT';
61
+ if (processResult.signal !== null)
62
+ return 'INTERRUPTED';
63
+ if (processResult.errorOrigin === 'post_spawn' || processResult.errorOrigin === 'stdin') {
64
+ return 'UNKNOWN';
65
+ }
66
+ if (typeof processResult.status === 'number' && processResult.status !== 0) {
67
+ return 'NODE_EXIT_NONZERO';
68
+ }
69
+ return 'UNKNOWN';
70
+ }
71
+ function buildNodeFailure(input) {
72
+ const exitCode = input.causeCode === 'NODE_EXIT_NONZERO' && typeof input.exitCode === 'number'
73
+ ? input.exitCode
74
+ : null;
75
+ const signal = input.causeCode === 'INTERRUPTED' ? input.signal : null;
76
+ return {
77
+ failedNode: input.failedNode,
78
+ attempt: input.attempt,
79
+ causeCode: input.causeCode,
80
+ causeMessage: getStableCauseMessage(input.causeCode),
81
+ exitCode,
82
+ evidencePreview: buildEvidencePreview({
83
+ causeCode: input.causeCode,
84
+ exitCode,
85
+ signal,
86
+ errorOrigin: input.errorOrigin,
87
+ timedOut: input.timedOut ?? false,
88
+ }),
89
+ occurredAt: input.occurredAt ?? new Date().toISOString(),
90
+ };
91
+ }
92
+ function buildEvidencePreview(input) {
93
+ switch (input.causeCode) {
94
+ case 'NODE_EXIT_NONZERO':
95
+ return typeof input.exitCode === 'number' ? `exit code: ${input.exitCode}` : null;
96
+ case 'NODE_TIMEOUT':
97
+ return input.timedOut ? 'timeout' : null;
98
+ case 'SPAWN_FAILED':
99
+ return input.errorOrigin === 'spawn' ? 'origin: spawn' : null;
100
+ case 'INTERRUPTED':
101
+ return input.signal === null ? null : `signal: ${input.signal}`;
102
+ case 'UNKNOWN':
103
+ return input.errorOrigin === 'post_spawn' || input.errorOrigin === 'stdin'
104
+ ? `origin: ${input.errorOrigin}`
105
+ : null;
106
+ default:
107
+ return null;
108
+ }
109
+ }
110
+ function sanitizeLocalRunError(raw, fallback) {
111
+ try {
112
+ return (0, sdk_1.redactTechnicalMessage)(raw) ?? fallback;
113
+ }
114
+ catch {
115
+ return fallback;
116
+ }
117
+ }
118
+ function readNodeAttempt(run, nodeId) {
119
+ const attempt = run.node_attempts?.[nodeId];
120
+ return typeof attempt === 'number' && Number.isInteger(attempt) && attempt > 0 ? attempt : 1;
121
+ }
122
+ //# sourceMappingURL=failure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failure.js","sourceRoot":"","sources":["../../src/failure.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mermaid.d.ts","sourceRoot":"","sources":["../../src/mermaid.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAA0B,MAAM,SAAS,CAAC;AAQpE,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAMD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CASpD;AAkFD,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CA0EpD"}
1
+ {"version":3,"file":"mermaid.d.ts","sourceRoot":"","sources":["../../src/mermaid.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAA0B,MAAM,SAAS,CAAC;AAQpE,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD;AAMD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CASpD;AAoFD,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CA0EpD"}
@@ -22,6 +22,8 @@ function escapeMermaidLabel(s) {
22
22
  function buildLabel(nodeId, node) {
23
23
  if (node.type === 'end')
24
24
  return 'END';
25
+ if (node.type === 'error')
26
+ return 'ERROR';
25
27
  let subtitle = '';
26
28
  if (node.agent) {
27
29
  subtitle = `@${escapeMermaidLabel(node.agent)}`;
@@ -44,7 +46,7 @@ function buildLabel(nodeId, node) {
44
46
  }
45
47
  function wrapShape(nodeId, label, type) {
46
48
  const safe = safeNodeId(nodeId);
47
- if (type === 'end') {
49
+ if (type === 'end' || type === 'error') {
48
50
  return `${safe}(("${label}"))`;
49
51
  }
50
52
  const q = `"\`${label}\`"`;
@@ -68,6 +70,7 @@ function wrapShape(nodeId, label, type) {
68
70
  const NODE_STYLES = {
69
71
  approval: 'fill:#e0f2fe,stroke:#93c5fd,color:#1e3a5f',
70
72
  expression: 'fill:#fef3c7,stroke:#f59e0b,color:#78350f',
73
+ error: 'fill:#fee2e2,stroke:#f87171,color:#7f1d1d',
71
74
  };
72
75
  function toMermaid(spec) {
73
76
  const lines = ['flowchart TD'];
@@ -84,7 +87,7 @@ function toMermaid(spec) {
84
87
  }
85
88
  if (node.type === 'branch' && node.branches && !Array.isArray(node.branches)) {
86
89
  for (const [condLabel, target] of Object.entries(node.branches)) {
87
- const edgeLabel = escapeMermaidLabel(condLabel === 'true' ? '통과' : condLabel === 'false' ? '반려' : condLabel);
90
+ const edgeLabel = escapeMermaidLabel(condLabel === 'true' ? 'Approve' : condLabel === 'false' ? 'Reject' : condLabel);
88
91
  lines.push(` ${src} -->|${edgeLabel}| ${safeNodeId(target)}`);
89
92
  }
90
93
  }
@@ -103,10 +106,10 @@ function toMermaid(spec) {
103
106
  }
104
107
  if (node.type === 'approval') {
105
108
  if (node.on_approve) {
106
- lines.push(` ${src} -->|${escapeMermaidLabel('승인')}| ${safeNodeId(node.on_approve)}`);
109
+ lines.push(` ${src} -->|${escapeMermaidLabel('Approve')}| ${safeNodeId(node.on_approve)}`);
107
110
  }
108
111
  if (node.on_reject) {
109
- lines.push(` ${src} -->|${escapeMermaidLabel('반려')}| ${safeNodeId(node.on_reject)}`);
112
+ lines.push(` ${src} -->|${escapeMermaidLabel('Reject')}| ${safeNodeId(node.on_reject)}`);
110
113
  }
111
114
  }
112
115
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mermaid.js","sourceRoot":"","sources":["../../src/mermaid.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mermaid.js","sourceRoot":"","sources":["../../src/mermaid.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import type { RunExecution } from './types.js';
2
+ export type WorkflowParentTaskStatus = 'running' | 'success' | 'failed';
3
+ export interface WorkflowParentLifecycle {
4
+ status: WorkflowParentTaskStatus;
5
+ error: string | null;
6
+ completedAt: string | null;
7
+ durationMs: number | null;
8
+ }
9
+ export interface WorkflowParentTaskRow {
10
+ id: string;
11
+ agent_id: string;
12
+ thread_id: string | null;
13
+ workspace_id: string | null;
14
+ platform: string | null;
15
+ status: string;
16
+ error: string | null;
17
+ completed_at: string | null;
18
+ duration_ms: number | null;
19
+ started_at: string;
20
+ metadata: string | null;
21
+ }
22
+ export interface WorkflowParentTaskRepository {
23
+ findRunningWorkflowParentTasks(): WorkflowParentTaskRow[];
24
+ updateTaskLifecycle(opts: {
25
+ id: string;
26
+ status: WorkflowParentTaskStatus;
27
+ error: string | null;
28
+ completedAt: string | null;
29
+ durationMs: number | null;
30
+ workspaceId: string;
31
+ }): void;
32
+ }
33
+ export interface ReconcileWorkflowParentTasksOptions {
34
+ taskRepo: WorkflowParentTaskRepository;
35
+ resolveWorkspacePath: (workspaceId: string) => string | undefined;
36
+ loadRun: (workspacePath: string, workflowRunId: string) => RunExecution | null;
37
+ orphanGraceMs?: number;
38
+ nowMs?: number;
39
+ }
40
+ export interface WorkflowParentReconciliationResult {
41
+ aligned: number;
42
+ orphaned: number;
43
+ skipped: number;
44
+ }
45
+ export declare const WORKFLOW_PARENT_ORPHAN_GRACE_MS: number;
46
+ export declare const WORKFLOW_PARENT_ORPHAN_ERROR = "Workflow run file missing after grace period (orphaned workflow task)";
47
+ export declare function deriveWorkflowParentLifecycle(run: RunExecution): WorkflowParentLifecycle | null;
48
+ export declare function reconcileWorkflowParentTasks(options: ReconcileWorkflowParentTasksOptions): WorkflowParentReconciliationResult;
49
+ //# sourceMappingURL=parent-task-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parent-task-sync.d.ts","sourceRoot":"","sources":["../../src/parent-task-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAExE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,wBAAwB,CAAC;IACjC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAGD,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,4BAA4B;IAE3C,8BAA8B,IAAI,qBAAqB,EAAE,CAAC;IAC1D,mBAAmB,CAAC,IAAI,EAAE;QACxB,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,wBAAwB,CAAC;QACjC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,IAAI,CAAC;CACV;AAED,MAAM,WAAW,mCAAmC;IAClD,QAAQ,EAAE,4BAA4B,CAAC;IACvC,oBAAoB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAElE,OAAO,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,KAAK,YAAY,GAAG,IAAI,CAAC;IAC/E,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kCAAkC;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,+BAA+B,QAAiB,CAAC;AAC9D,eAAO,MAAM,4BAA4B,0EACgC,CAAC;AAoB1E,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,YAAY,GAAG,uBAAuB,GAAG,IAAI,CA6B/F;AAkCD,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,mCAAmC,GAC3C,kCAAkC,CAwEpC"}
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WORKFLOW_PARENT_ORPHAN_ERROR = exports.WORKFLOW_PARENT_ORPHAN_GRACE_MS = void 0;
4
+ exports.deriveWorkflowParentLifecycle = deriveWorkflowParentLifecycle;
5
+ exports.reconcileWorkflowParentTasks = reconcileWorkflowParentTasks;
6
+ exports.WORKFLOW_PARENT_ORPHAN_GRACE_MS = 10 * 60 * 1000;
7
+ exports.WORKFLOW_PARENT_ORPHAN_ERROR = 'Workflow run file missing after grace period (orphaned workflow task)';
8
+ function latestAuditEndedAt(run) {
9
+ let latest;
10
+ for (const entry of run.audit ?? []) {
11
+ const timestamp = Date.parse(entry.ended_at);
12
+ if (!Number.isFinite(timestamp))
13
+ continue;
14
+ if (!latest || timestamp >= latest.timestamp) {
15
+ latest = { value: entry.ended_at, timestamp };
16
+ }
17
+ }
18
+ return latest?.value ?? null;
19
+ }
20
+ function deriveWorkflowParentLifecycle(run) {
21
+ if (run.status === 'completed' || run.status === 'failed' || run.status === 'cancelled') {
22
+ const completedAt = latestAuditEndedAt(run) ?? run.updated_at;
23
+ const createdAtMs = Date.parse(run.created_at);
24
+ const completedAtMs = Date.parse(completedAt);
25
+ const durationMs = Number.isFinite(createdAtMs) && Number.isFinite(completedAtMs)
26
+ ? Math.max(0, completedAtMs - createdAtMs)
27
+ : null;
28
+ if (run.status === 'completed') {
29
+ return { status: 'success', error: null, completedAt, durationMs };
30
+ }
31
+ return {
32
+ status: 'failed',
33
+ error: run.error ?? (run.status === 'cancelled' ? 'Workflow run cancelled' : 'Workflow run failed'),
34
+ completedAt,
35
+ durationMs,
36
+ };
37
+ }
38
+ if (run.status === 'running' || run.status === 'retrying') {
39
+ return { status: 'running', error: null, completedAt: null, durationMs: null };
40
+ }
41
+ return null;
42
+ }
43
+ function parseWorkflowCardRunId(metadata) {
44
+ if (!metadata)
45
+ return null;
46
+ try {
47
+ const parsed = JSON.parse(metadata);
48
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
49
+ return null;
50
+ const record = parsed;
51
+ return (record.kind === 'workflow_card' || record.kind === 'workflow_ui_instance') && typeof record.workflowRunId === 'string'
52
+ ? record.workflowRunId
53
+ : null;
54
+ }
55
+ catch {
56
+ return null;
57
+ }
58
+ }
59
+ function lifecycleMatches(row, lifecycle) {
60
+ return row.status === lifecycle.status
61
+ && row.error === lifecycle.error
62
+ && row.completed_at === lifecycle.completedAt
63
+ && row.duration_ms === lifecycle.durationMs;
64
+ }
65
+ function isStale(startedAt, nowMs, graceMs) {
66
+ const startedAtMs = Date.parse(startedAt);
67
+ return Number.isFinite(startedAtMs) && nowMs - startedAtMs >= graceMs;
68
+ }
69
+ function reconcileWorkflowParentTasks(options) {
70
+ const graceMs = options.orphanGraceMs ?? exports.WORKFLOW_PARENT_ORPHAN_GRACE_MS;
71
+ const nowMs = options.nowMs ?? Date.now();
72
+ const result = { aligned: 0, orphaned: 0, skipped: 0 };
73
+ for (const row of options.taskRepo.findRunningWorkflowParentTasks()) {
74
+ if (row.platform !== 'workflow' || !parseWorkflowCardRunId(row.metadata)) {
75
+ result.skipped += 1;
76
+ continue;
77
+ }
78
+ const workspaceId = row.workspace_id;
79
+ if (!workspaceId) {
80
+ result.skipped += 1;
81
+ continue;
82
+ }
83
+ const workspacePath = options.resolveWorkspacePath(workspaceId);
84
+ if (!workspacePath) {
85
+ result.skipped += 1;
86
+ continue;
87
+ }
88
+ const workflowRunId = parseWorkflowCardRunId(row.metadata);
89
+ let run = null;
90
+ try {
91
+ run = options.loadRun(workspacePath, workflowRunId);
92
+ }
93
+ catch {
94
+ }
95
+ if (!run) {
96
+ if (row.status !== 'running' || !isStale(row.started_at, nowMs, graceMs)) {
97
+ result.skipped += 1;
98
+ continue;
99
+ }
100
+ const completedAt = row.completed_at ?? new Date(nowMs).toISOString();
101
+ const durationMs = row.duration_ms ?? Math.max(0, nowMs - Date.parse(row.started_at));
102
+ options.taskRepo.updateTaskLifecycle({
103
+ id: row.id,
104
+ status: 'failed',
105
+ error: exports.WORKFLOW_PARENT_ORPHAN_ERROR,
106
+ completedAt,
107
+ durationMs: Number.isFinite(durationMs) ? durationMs : null,
108
+ workspaceId,
109
+ });
110
+ result.orphaned += 1;
111
+ continue;
112
+ }
113
+ const lifecycle = deriveWorkflowParentLifecycle(run);
114
+ if (!lifecycle) {
115
+ result.skipped += 1;
116
+ continue;
117
+ }
118
+ if (lifecycleMatches(row, lifecycle))
119
+ continue;
120
+ options.taskRepo.updateTaskLifecycle({
121
+ id: row.id,
122
+ status: lifecycle.status,
123
+ error: lifecycle.error,
124
+ completedAt: lifecycle.completedAt,
125
+ durationMs: lifecycle.durationMs,
126
+ workspaceId,
127
+ });
128
+ result.aligned += 1;
129
+ }
130
+ return result;
131
+ }
132
+ //# sourceMappingURL=parent-task-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parent-task-sync.js","sourceRoot":"","sources":["../../src/parent-task-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { RetryPolicy } from './types';
2
+ export declare const RETRY_BASE_DELAY_MS = 1000;
3
+ export declare const RETRY_DEFAULT_MAX_DELAY_MS = 30000;
4
+ export declare const RETRY_HARD_MAX_DELAY_MS = 60000;
5
+ export declare const RETRY_MAX_ATTEMPTS_CEILING = 10;
6
+ export declare const DEFAULT_RETRYABLE_CODES: readonly ["NODE_EXIT_NONZERO", "NODE_TIMEOUT", "SPAWN_FAILED"];
7
+ export declare const RETRYABLE_NODE_TYPES: readonly ["agent_task", "skill_task", "shell_task"];
8
+ export type RetryPolicyParseResult = {
9
+ ok: true;
10
+ policy: RetryPolicy | undefined;
11
+ } | {
12
+ ok: false;
13
+ path: string;
14
+ reason: string;
15
+ };
16
+ export declare function parseRetryPolicy(node: unknown): RetryPolicyParseResult;
17
+ export interface RetryDecisionRun {
18
+ status?: 'pending' | 'running' | 'retrying' | 'completed' | 'failed' | 'cancelled';
19
+ last_failure?: {
20
+ failedNode?: unknown;
21
+ attempt?: unknown;
22
+ causeCode?: unknown;
23
+ };
24
+ node_attempts?: Record<string, unknown>;
25
+ }
26
+ export interface RetryDecisionInput {
27
+ policy?: RetryPolicy;
28
+ run: RetryDecisionRun;
29
+ nodeId: string;
30
+ }
31
+ export interface RetryDecision {
32
+ retry: boolean;
33
+ reason: string;
34
+ attempt?: number;
35
+ }
36
+ export declare function decideRetry(input: RetryDecisionInput): RetryDecision;
37
+ export declare function computeRetryDelayMs(policy: RetryPolicy, attempt: number): number;
38
+ //# sourceMappingURL=retry-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-policy.d.ts","sourceRoot":"","sources":["../../src/retry-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EAEZ,MAAM,SAAS,CAAC;AAGjB,eAAO,MAAM,mBAAmB,OAAQ,CAAC;AACzC,eAAO,MAAM,0BAA0B,QAAS,CAAC;AACjD,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAC9C,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,eAAO,MAAM,uBAAuB,gEAIe,CAAC;AAEpD,eAAO,MAAM,oBAAoB,qDAIvB,CAAC;AAmBX,MAAM,MAAM,sBAAsB,GAC9B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAAA;CAAE,GAC7C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAWhD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,sBAAsB,CA4DtE;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;IACnF,YAAY,CAAC,EAAE;QACb,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;IACF,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,GAAG,EAAE,gBAAgB,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAOD,wBAAgB,WAAW,CAAC,KAAK,EAAE,kBAAkB,GAAG,aAAa,CA8BpE;AAGD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAShF"}
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RETRYABLE_NODE_TYPES = exports.DEFAULT_RETRYABLE_CODES = exports.RETRY_MAX_ATTEMPTS_CEILING = exports.RETRY_HARD_MAX_DELAY_MS = exports.RETRY_DEFAULT_MAX_DELAY_MS = exports.RETRY_BASE_DELAY_MS = void 0;
4
+ exports.parseRetryPolicy = parseRetryPolicy;
5
+ exports.decideRetry = decideRetry;
6
+ exports.computeRetryDelayMs = computeRetryDelayMs;
7
+ const types_1 = require("./types");
8
+ exports.RETRY_BASE_DELAY_MS = 1000;
9
+ exports.RETRY_DEFAULT_MAX_DELAY_MS = 30000;
10
+ exports.RETRY_HARD_MAX_DELAY_MS = 60000;
11
+ exports.RETRY_MAX_ATTEMPTS_CEILING = 10;
12
+ exports.DEFAULT_RETRYABLE_CODES = [
13
+ 'NODE_EXIT_NONZERO',
14
+ 'NODE_TIMEOUT',
15
+ 'SPAWN_FAILED',
16
+ ];
17
+ exports.RETRYABLE_NODE_TYPES = [
18
+ 'agent_task',
19
+ 'skill_task',
20
+ 'shell_task',
21
+ ];
22
+ const FAILURE_CODES = new Set([
23
+ 'CLI_UNRESOLVABLE',
24
+ 'SPAWN_FAILED',
25
+ 'NODE_TIMEOUT',
26
+ 'NODE_EXIT_NONZERO',
27
+ 'OUTPUT_INVALID',
28
+ 'RATE_LIMITED',
29
+ 'CONFIG_INVALID',
30
+ 'INTERRUPTED',
31
+ 'CANCELLED',
32
+ 'UNKNOWN',
33
+ ]);
34
+ function isRecord(value) {
35
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
36
+ }
37
+ function invalid(path, reason) {
38
+ return { ok: false, path, reason };
39
+ }
40
+ function parseRetryPolicy(node) {
41
+ if (!isRecord(node))
42
+ return invalid('retry', 'node must be an object');
43
+ const rawRetry = node.retry;
44
+ if (rawRetry === undefined)
45
+ return { ok: true, policy: undefined };
46
+ if (!isRecord(rawRetry))
47
+ return invalid('retry', 'retry must be an object');
48
+ const nodeType = node.type;
49
+ if (typeof nodeType !== 'string'
50
+ || !exports.RETRYABLE_NODE_TYPES.includes(nodeType)) {
51
+ return invalid('retry', 'retry is only supported on agent_task, skill_task, and shell_task nodes');
52
+ }
53
+ const max = rawRetry.max;
54
+ if (typeof max !== 'number' || !Number.isFinite(max)) {
55
+ return invalid('retry.max', 'retry.max must be a finite number');
56
+ }
57
+ if (!Number.isInteger(max))
58
+ return invalid('retry.max', 'retry.max must be an integer');
59
+ if (max < 0 || max > exports.RETRY_MAX_ATTEMPTS_CEILING) {
60
+ return invalid('retry.max', `retry.max must be between 0 and ${exports.RETRY_MAX_ATTEMPTS_CEILING}`);
61
+ }
62
+ const delay = rawRetry.delay;
63
+ if (delay !== 'fixed' && delay !== 'exponential') {
64
+ return invalid('retry.delay', 'retry.delay must be "fixed" or "exponential"');
65
+ }
66
+ let maxDelay = exports.RETRY_DEFAULT_MAX_DELAY_MS;
67
+ if (rawRetry.max_delay !== undefined) {
68
+ if (typeof rawRetry.max_delay !== 'number' || !Number.isFinite(rawRetry.max_delay)) {
69
+ return invalid('retry.max_delay', 'retry.max_delay must be a finite number');
70
+ }
71
+ if (!Number.isInteger(rawRetry.max_delay) || rawRetry.max_delay < 0) {
72
+ return invalid('retry.max_delay', 'retry.max_delay must be a non-negative integer');
73
+ }
74
+ maxDelay = rawRetry.max_delay;
75
+ }
76
+ let on = [...exports.DEFAULT_RETRYABLE_CODES];
77
+ if (rawRetry.on !== undefined) {
78
+ if (!Array.isArray(rawRetry.on))
79
+ return invalid('retry.on', 'retry.on must be an array');
80
+ on = [];
81
+ for (const [index, candidate] of rawRetry.on.entries()) {
82
+ if (typeof candidate !== 'string' || !FAILURE_CODES.has(candidate)) {
83
+ return invalid(`retry.on[${index}]`, `retry.on[${index}] is not a supported workflow failure code`);
84
+ }
85
+ const code = candidate;
86
+ if (types_1.NEVER_RETRYABLE.includes(code)) {
87
+ return invalid(`retry.on[${index}]`, `${code} cannot be retried`);
88
+ }
89
+ on.push(code);
90
+ }
91
+ }
92
+ return {
93
+ ok: true,
94
+ policy: { max, delay, max_delay: maxDelay, on },
95
+ };
96
+ }
97
+ function declined(reason) {
98
+ return { retry: false, reason };
99
+ }
100
+ function decideRetry(input) {
101
+ const { policy, run, nodeId } = input;
102
+ if (!policy)
103
+ return declined('retry policy is not configured');
104
+ if (run.status !== 'failed')
105
+ return declined('run is not failed');
106
+ const failure = run.last_failure;
107
+ if (!failure || failure.failedNode !== nodeId)
108
+ return declined('latest failure is not for this node');
109
+ const attempt = failure.attempt;
110
+ const storedAttempt = run.node_attempts?.[nodeId];
111
+ if (typeof attempt !== 'number'
112
+ || !Number.isInteger(attempt)
113
+ || attempt <= 0
114
+ || storedAttempt !== attempt) {
115
+ return declined('latest attempt is stale');
116
+ }
117
+ const causeCode = failure.causeCode;
118
+ if (typeof causeCode !== 'string')
119
+ return declined('latest failure has no supported cause');
120
+ if (types_1.NEVER_RETRYABLE.includes(causeCode)) {
121
+ return declined('latest failure is never retryable');
122
+ }
123
+ if (!policy.on.includes(causeCode)) {
124
+ return declined('latest failure is outside the retry policy');
125
+ }
126
+ if (attempt >= policy.max + 1)
127
+ return declined('retry budget is exhausted');
128
+ return { retry: true, reason: 'retry policy matched', attempt };
129
+ }
130
+ function computeRetryDelayMs(policy, attempt) {
131
+ const safeAttempt = Number.isInteger(attempt) && attempt > 0 ? attempt : 1;
132
+ const base = policy.delay === 'exponential'
133
+ ? exports.RETRY_BASE_DELAY_MS * (2 ** (safeAttempt - 1))
134
+ : exports.RETRY_BASE_DELAY_MS;
135
+ const configuredCap = typeof policy.max_delay === 'number' && Number.isFinite(policy.max_delay)
136
+ ? Math.max(0, policy.max_delay)
137
+ : exports.RETRY_DEFAULT_MAX_DELAY_MS;
138
+ return Math.min(base, configuredCap, exports.RETRY_HARD_MAX_DELAY_MS);
139
+ }
140
+ //# sourceMappingURL=retry-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-policy.js","sourceRoot":"","sources":["../../src/retry-policy.ts"],"names":[],"mappings":"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"}