cool-workflow 0.1.78
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/.claude-plugin/plugin.json +20 -0
- package/.codex-plugin/mcp.json +10 -0
- package/.codex-plugin/plugin.json +38 -0
- package/.mcp.json +10 -0
- package/LICENSE +24 -0
- package/README.md +638 -0
- package/apps/architecture-review/app.json +51 -0
- package/apps/architecture-review/workflow.js +116 -0
- package/apps/end-to-end-golden-path/app.json +30 -0
- package/apps/end-to-end-golden-path/workflow.js +33 -0
- package/apps/pr-review-fix-ci/app.json +59 -0
- package/apps/pr-review-fix-ci/workflow.js +90 -0
- package/apps/release-cut/app.json +54 -0
- package/apps/release-cut/workflow.js +82 -0
- package/apps/research-synthesis/app.json +50 -0
- package/apps/research-synthesis/workflow.js +76 -0
- package/apps/workflow-app-framework-demo/app.json +29 -0
- package/apps/workflow-app-framework-demo/workflow.js +44 -0
- package/dist/agent-config.js +223 -0
- package/dist/candidate-scoring.js +715 -0
- package/dist/capability-core.js +630 -0
- package/dist/capability-dispatcher.js +86 -0
- package/dist/capability-registry.js +523 -0
- package/dist/cli.js +1276 -0
- package/dist/collaboration.js +727 -0
- package/dist/commit.js +570 -0
- package/dist/contract-migration.js +234 -0
- package/dist/coordinator.js +1163 -0
- package/dist/daemon.js +44 -0
- package/dist/dispatch.js +201 -0
- package/dist/drive.js +503 -0
- package/dist/error-feedback.js +415 -0
- package/dist/evidence-grounding.js +179 -0
- package/dist/evidence-reasoning.js +733 -0
- package/dist/execution-backend.js +1279 -0
- package/dist/harness.js +61 -0
- package/dist/mcp-server.js +1615 -0
- package/dist/multi-agent-eval.js +857 -0
- package/dist/multi-agent-host.js +764 -0
- package/dist/multi-agent-operator-ux.js +537 -0
- package/dist/multi-agent-trust.js +366 -0
- package/dist/multi-agent.js +1173 -0
- package/dist/node-snapshot.js +270 -0
- package/dist/observability.js +922 -0
- package/dist/operator-ux.js +971 -0
- package/dist/orchestrator/audit-operations.js +182 -0
- package/dist/orchestrator/candidate-operations.js +117 -0
- package/dist/orchestrator/cli-options.js +288 -0
- package/dist/orchestrator/collaboration-operations.js +86 -0
- package/dist/orchestrator/feedback-operations.js +81 -0
- package/dist/orchestrator/host-operations.js +78 -0
- package/dist/orchestrator/lifecycle-operations.js +462 -0
- package/dist/orchestrator/migration-operations.js +44 -0
- package/dist/orchestrator/multi-agent-operations.js +362 -0
- package/dist/orchestrator/report.js +369 -0
- package/dist/orchestrator/topology-operations.js +84 -0
- package/dist/orchestrator.js +874 -0
- package/dist/pipeline-contract.js +92 -0
- package/dist/pipeline-runner.js +285 -0
- package/dist/reclamation.js +882 -0
- package/dist/result-normalize.js +194 -0
- package/dist/run-export.js +64 -0
- package/dist/run-registry.js +1347 -0
- package/dist/run-state-schema.js +67 -0
- package/dist/sandbox-profile.js +471 -0
- package/dist/scheduler.js +266 -0
- package/dist/scheduling.js +184 -0
- package/dist/schema-validate.js +98 -0
- package/dist/state-explosion.js +1213 -0
- package/dist/state-migrations.js +463 -0
- package/dist/state-node.js +301 -0
- package/dist/state.js +308 -0
- package/dist/telemetry-attestation.js +156 -0
- package/dist/telemetry-ledger.js +145 -0
- package/dist/topology.js +527 -0
- package/dist/triggers.js +159 -0
- package/dist/trust-audit.js +475 -0
- package/dist/types/blackboard.js +2 -0
- package/dist/types/boundary.js +29 -0
- package/dist/types/candidate.js +2 -0
- package/dist/types/collaboration.js +2 -0
- package/dist/types/core.js +2 -0
- package/dist/types/drive.js +10 -0
- package/dist/types/error-feedback.js +2 -0
- package/dist/types/evidence-reasoning.js +2 -0
- package/dist/types/execution-backend.js +2 -0
- package/dist/types/multi-agent.js +2 -0
- package/dist/types/observability.js +2 -0
- package/dist/types/pipeline.js +2 -0
- package/dist/types/reclamation.js +8 -0
- package/dist/types/result.js +2 -0
- package/dist/types/run-registry.js +2 -0
- package/dist/types/run.js +2 -0
- package/dist/types/sandbox.js +2 -0
- package/dist/types/schedule.js +2 -0
- package/dist/types/state-node.js +2 -0
- package/dist/types/topology.js +2 -0
- package/dist/types/trust.js +2 -0
- package/dist/types/workbench.js +2 -0
- package/dist/types/worker.js +2 -0
- package/dist/types/workflow-app.js +2 -0
- package/dist/types.js +43 -0
- package/dist/verifier-registry.js +46 -0
- package/dist/verifier.js +78 -0
- package/dist/version.js +8 -0
- package/dist/workbench-host.js +172 -0
- package/dist/workbench.js +190 -0
- package/dist/worker-isolation.js +1028 -0
- package/dist/workflow-api.js +98 -0
- package/dist/workflow-app-framework.js +626 -0
- package/docs/agent-delegation-drive.7.md +190 -0
- package/docs/agent-framework.md +176 -0
- package/docs/candidate-scoring.7.md +106 -0
- package/docs/canonical-workflow-apps.7.md +137 -0
- package/docs/capability-topology-registry.7.md +168 -0
- package/docs/cli-mcp-parity.7.md +373 -0
- package/docs/contract-migration-tooling.7.md +123 -0
- package/docs/control-plane-scheduling.7.md +110 -0
- package/docs/coordinator-blackboard.7.md +183 -0
- package/docs/dogfood/architecture-review-cool-workflow.md +16 -0
- package/docs/dogfood-one-real-repo.7.md +168 -0
- package/docs/durable-state-and-locking.7.md +107 -0
- package/docs/end-to-end-golden-path.7.md +117 -0
- package/docs/error-feedback.7.md +153 -0
- package/docs/evidence-adoption-reasoning-chain.7.md +270 -0
- package/docs/execution-backends.7.md +300 -0
- package/docs/getting-started.md +99 -0
- package/docs/index.md +41 -0
- package/docs/mcp-app-surface.7.md +235 -0
- package/docs/multi-agent-cli-mcp-surface.7.md +265 -0
- package/docs/multi-agent-eval-replay-harness.7.md +302 -0
- package/docs/multi-agent-operator-ux.7.md +314 -0
- package/docs/multi-agent-runtime-core.7.md +231 -0
- package/docs/multi-agent-topologies.7.md +103 -0
- package/docs/multi-agent-trust-policy-audit.7.md +154 -0
- package/docs/node-snapshot-diff-replay.7.md +135 -0
- package/docs/observability-cost-accounting.7.md +194 -0
- package/docs/operator-ux.7.md +180 -0
- package/docs/pipeline-runner.7.md +136 -0
- package/docs/project-index.md +261 -0
- package/docs/real-execution-backends.7.md +142 -0
- package/docs/release-and-migration.7.md +280 -0
- package/docs/release-tooling.7.md +159 -0
- package/docs/routines.md +48 -0
- package/docs/run-registry-control-plane.7.md +312 -0
- package/docs/run-retention-reclamation.7.md +191 -0
- package/docs/sandbox-profiles.7.md +137 -0
- package/docs/scheduled-tasks.md +80 -0
- package/docs/security-trust-hardening.7.md +117 -0
- package/docs/state-explosion-management.7.md +264 -0
- package/docs/state-node.7.md +96 -0
- package/docs/team-collaboration.7.md +207 -0
- package/docs/unix-principles.md +192 -0
- package/docs/verifier-gated-commit.7.md +140 -0
- package/docs/web-desktop-workbench.7.md +215 -0
- package/docs/worker-isolation.7.md +167 -0
- package/docs/workflow-app-framework.7.md +274 -0
- package/manifest/README.md +43 -0
- package/manifest/plugin.manifest.json +316 -0
- package/manifest/pricing.policy.json +14 -0
- package/package.json +79 -0
- package/scripts/agents/claude-p-agent.js +104 -0
- package/scripts/agents/claude-p-agent.sh +9 -0
- package/scripts/agents/cw-attest-keygen.js +55 -0
- package/scripts/agents/cw-attest-wrap.js +143 -0
- package/scripts/block-unapproved-tag.sh +39 -0
- package/scripts/bump-version.js +249 -0
- package/scripts/canonical-apps.js +171 -0
- package/scripts/cw.js +4 -0
- package/scripts/dist-drift-check.js +79 -0
- package/scripts/dogfood-architecture-review.js +237 -0
- package/scripts/dogfood-release.js +624 -0
- package/scripts/forward-ref-docs.js +73 -0
- package/scripts/gen-manifests.js +232 -0
- package/scripts/golden-path.js +300 -0
- package/scripts/mcp-server.js +4 -0
- package/scripts/new-feature.js +121 -0
- package/scripts/parity-check.js +213 -0
- package/scripts/release-check.js +118 -0
- package/scripts/release-flow.js +272 -0
- package/scripts/release-gate.sh +85 -0
- package/scripts/sync-project-index.js +387 -0
- package/scripts/validate-run-state-schema.js +126 -0
- package/scripts/verify-container-selfref.js +64 -0
- package/scripts/version-sync-check.js +237 -0
- package/skills/cool-workflow/SKILL.md +162 -0
- package/skills/cool-workflow/references/commands.md +282 -0
- package/tsconfig.json +16 -0
- package/ui/workbench/app.css +76 -0
- package/ui/workbench/app.js +159 -0
- package/ui/workbench/index.html +32 -0
- package/workflows/architecture-review.workflow.js +84 -0
- package/workflows/research-synthesis.workflow.js +47 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeResultEnvelope = normalizeResultEnvelope;
|
|
4
|
+
exports.firstNonEmptyLine = firstNonEmptyLine;
|
|
5
|
+
exports.isEmptyCapture = isEmptyCapture;
|
|
6
|
+
const evidence_grounding_1 = require("./evidence-grounding");
|
|
7
|
+
// Alternative keys a capable model naturally uses for the findings array.
|
|
8
|
+
const FINDING_ARRAY_KEYS = [
|
|
9
|
+
"findings",
|
|
10
|
+
"candidate_risks",
|
|
11
|
+
"candidateRisks",
|
|
12
|
+
"risks",
|
|
13
|
+
"ranked_risks",
|
|
14
|
+
"rankedRisks",
|
|
15
|
+
"top_risks",
|
|
16
|
+
"topRisks",
|
|
17
|
+
"issues",
|
|
18
|
+
"problems",
|
|
19
|
+
"concerns"
|
|
20
|
+
];
|
|
21
|
+
// Per-finding keys that may carry evidence locators.
|
|
22
|
+
const FINDING_EVIDENCE_KEYS = ["evidence", "evidence_paths", "evidencePaths", "locators", "refs", "files", "location", "locations", "path", "paths", "line", "lines", "where"];
|
|
23
|
+
const CLASSIFICATIONS = new Set(["real", "conditional", "non-issue", "unknown"]);
|
|
24
|
+
// Evidence caps (v0.1.42): the v0.1.41 experiment hit a single flat cap of 64 on
|
|
25
|
+
// the top-level union, silently dropping locators on richly-cited workers. The
|
|
26
|
+
// top-level array now holds the whole run's harvested locators (high cap), while
|
|
27
|
+
// each finding keeps a focused, readable set.
|
|
28
|
+
const TOP_LEVEL_EVIDENCE_CAP = 256;
|
|
29
|
+
const PER_FINDING_EVIDENCE_CAP = 32;
|
|
30
|
+
function normalizeResultEnvelope(markdown) {
|
|
31
|
+
const match = markdown.match(/```cw:result\s*([\s\S]*?)```/);
|
|
32
|
+
if (!match) {
|
|
33
|
+
// No fence: still DERIVE grounded evidence from the prose so a fence-less but
|
|
34
|
+
// well-cited report is not silently captured as empty.
|
|
35
|
+
return { summary: firstNonEmptyLine(markdown), findings: [], evidence: harvestGrounded([markdown], TOP_LEVEL_EVIDENCE_CAP) };
|
|
36
|
+
}
|
|
37
|
+
let parsed;
|
|
38
|
+
try {
|
|
39
|
+
parsed = JSON.parse(match[1]);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
43
|
+
throw new Error(`Invalid cw:result JSON: ${message}`);
|
|
44
|
+
}
|
|
45
|
+
const summary = pickString(parsed, ["summary", "short_answer", "shortAnswer", "verdict", "answer", "conclusion"]) || firstNonEmptyLine(markdown);
|
|
46
|
+
// Findings: prefer the canonical `findings` array, else the first present
|
|
47
|
+
// alternative array. EVERY finding is then normalized (id guaranteed, severity/
|
|
48
|
+
// classification coerced, evidence derived) so a capable agent that omits an `id`
|
|
49
|
+
// or uses `high`/`candidate_risks` is captured rather than fail-closed-rejected.
|
|
50
|
+
const canonicalFindings = Array.isArray(parsed.findings) ? parsed.findings : undefined;
|
|
51
|
+
const rawFindings = (canonicalFindings && canonicalFindings.length ? canonicalFindings : extractFindingsRaw(parsed)) ?? [];
|
|
52
|
+
const findings = rawFindings.map((item, index) => normalizeFinding(item, index));
|
|
53
|
+
// Evidence: canonical non-empty wins; else CW derives grounded locators itself
|
|
54
|
+
// from the entire envelope JSON, the findings, and the prose.
|
|
55
|
+
const canonicalEvidence = Array.isArray(parsed.evidence) ? parsed.evidence : undefined;
|
|
56
|
+
const evidence = canonicalEvidence && canonicalEvidence.length
|
|
57
|
+
? canonicalEvidence
|
|
58
|
+
: harvestGrounded([parsed, findings, stripFence(markdown)], TOP_LEVEL_EVIDENCE_CAP);
|
|
59
|
+
return { summary, findings, evidence };
|
|
60
|
+
}
|
|
61
|
+
/** The first recognized alternative findings array (raw items, normalized by the
|
|
62
|
+
* caller). Returns undefined when no alternative findings source is present. */
|
|
63
|
+
function extractFindingsRaw(parsed) {
|
|
64
|
+
for (const key of FINDING_ARRAY_KEYS) {
|
|
65
|
+
if (key === "findings")
|
|
66
|
+
continue; // canonical handled by the caller
|
|
67
|
+
const raw = parsed[key];
|
|
68
|
+
if (Array.isArray(raw) && raw.length)
|
|
69
|
+
return raw;
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
function normalizeFinding(item, index) {
|
|
74
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
75
|
+
const obj = item;
|
|
76
|
+
const id = pickString(obj, ["id", "key", "name", "title"]) || `finding-${index + 1}`;
|
|
77
|
+
const classification = normalizeClassification(pickString(obj, ["classification", "class", "kind", "status"]));
|
|
78
|
+
const severity = normalizeSeverity(pickString(obj, ["severity", "priority", "level", "rank", "rating"]));
|
|
79
|
+
// Evidence: explicit per-finding evidence keys first, else derive grounded
|
|
80
|
+
// locators from the whole finding object (so `{title, detail, file, line}` works).
|
|
81
|
+
const explicit = harvestGrounded(FINDING_EVIDENCE_KEYS.map((k) => obj[k]).filter((v) => v !== undefined), PER_FINDING_EVIDENCE_CAP);
|
|
82
|
+
const evidence = explicit.length ? explicit : harvestGrounded([obj], PER_FINDING_EVIDENCE_CAP);
|
|
83
|
+
return { id, classification, severity, evidence };
|
|
84
|
+
}
|
|
85
|
+
// A bare string finding ("P1 — revoke stays live (app.ts:1644)").
|
|
86
|
+
const text = String(item ?? "");
|
|
87
|
+
return {
|
|
88
|
+
id: `finding-${index + 1}`,
|
|
89
|
+
classification: "unknown",
|
|
90
|
+
severity: normalizeSeverity(text),
|
|
91
|
+
evidence: harvestGrounded([text], PER_FINDING_EVIDENCE_CAP)
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function normalizeClassification(value) {
|
|
95
|
+
if (!value)
|
|
96
|
+
return undefined;
|
|
97
|
+
const v = value.trim().toLowerCase();
|
|
98
|
+
if (CLASSIFICATIONS.has(v))
|
|
99
|
+
return v;
|
|
100
|
+
if (v.includes("non") && v.includes("issue"))
|
|
101
|
+
return "non-issue";
|
|
102
|
+
if (v === "confirmed" || v === "true" || v === "valid")
|
|
103
|
+
return "real";
|
|
104
|
+
if (v === "possible" || v === "maybe" || v === "potential")
|
|
105
|
+
return "conditional";
|
|
106
|
+
return "unknown";
|
|
107
|
+
}
|
|
108
|
+
function normalizeSeverity(value) {
|
|
109
|
+
const s = String(value || "").toUpperCase();
|
|
110
|
+
const tag = s.match(/\bP[0-3]\b/);
|
|
111
|
+
if (tag)
|
|
112
|
+
return tag[0];
|
|
113
|
+
if (/CRIT|BLOCKER/.test(s))
|
|
114
|
+
return "P0";
|
|
115
|
+
if (/HIGH|SEV(ERE)?\b/.test(s))
|
|
116
|
+
return "P1";
|
|
117
|
+
if (/MED(IUM)?\b/.test(s))
|
|
118
|
+
return "P2";
|
|
119
|
+
if (/LOW|MINOR|NIT\b/.test(s))
|
|
120
|
+
return "P3";
|
|
121
|
+
return "none";
|
|
122
|
+
}
|
|
123
|
+
/** Collect GROUNDED locators (path:line / URL / namespace:value) from any mix of
|
|
124
|
+
* JSON values and prose strings. This is how CW derives evidence itself instead
|
|
125
|
+
* of trusting the agent's `evidence` key. Deterministic: deduped + sorted + capped. */
|
|
126
|
+
function harvestGrounded(values, cap = TOP_LEVEL_EVIDENCE_CAP) {
|
|
127
|
+
const acc = [];
|
|
128
|
+
for (const v of values)
|
|
129
|
+
collect(v, acc);
|
|
130
|
+
const unique = Array.from(new Set(acc.map((s) => s.trim()).filter(Boolean)));
|
|
131
|
+
unique.sort();
|
|
132
|
+
return unique.slice(0, cap);
|
|
133
|
+
}
|
|
134
|
+
function collect(value, acc) {
|
|
135
|
+
if (value === null || value === undefined)
|
|
136
|
+
return;
|
|
137
|
+
if (typeof value === "string") {
|
|
138
|
+
const v = value.trim();
|
|
139
|
+
// A single whitespace-free token that is itself a grounded locator is kept
|
|
140
|
+
// verbatim; anything with spaces is PROSE — extract the locator tokens from it
|
|
141
|
+
// (a sentence containing a "/" must not be captured whole as one "locator").
|
|
142
|
+
if (v && !/\s/.test(v) && (0, evidence_grounding_1.isGroundedEvidence)(v))
|
|
143
|
+
acc.push(v);
|
|
144
|
+
else
|
|
145
|
+
for (const tok of locatorsFromText(v))
|
|
146
|
+
acc.push(tok);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (Array.isArray(value)) {
|
|
150
|
+
for (const item of value)
|
|
151
|
+
collect(item, acc);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (typeof value === "object") {
|
|
155
|
+
for (const item of Object.values(value))
|
|
156
|
+
collect(item, acc);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Pull file:line / file.ext / URL / `backtick` tokens out of a prose string, then
|
|
160
|
+
// keep only the grounded ones. Backtick spans are a strong signal for code refs.
|
|
161
|
+
const LOCATOR_RE = /`([^`]+)`|([A-Za-z0-9_@./-]+\.[A-Za-z]{1,8}(?::\d+(?:-\d+)?)?)|(https?:\/\/[^\s)]+)/g;
|
|
162
|
+
function locatorsFromText(text) {
|
|
163
|
+
const out = [];
|
|
164
|
+
let m;
|
|
165
|
+
LOCATOR_RE.lastIndex = 0;
|
|
166
|
+
while ((m = LOCATOR_RE.exec(text))) {
|
|
167
|
+
const tok = (m[1] || m[2] || m[3] || "").trim();
|
|
168
|
+
if (tok && (0, evidence_grounding_1.isGroundedEvidence)(tok))
|
|
169
|
+
out.push(tok);
|
|
170
|
+
}
|
|
171
|
+
return out;
|
|
172
|
+
}
|
|
173
|
+
function stripFence(markdown) {
|
|
174
|
+
return markdown.replace(/```cw:result\s*[\s\S]*?```/g, "");
|
|
175
|
+
}
|
|
176
|
+
function pickString(obj, keys) {
|
|
177
|
+
for (const key of keys) {
|
|
178
|
+
const v = obj[key];
|
|
179
|
+
if (typeof v === "string" && v.trim())
|
|
180
|
+
return v.trim();
|
|
181
|
+
}
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
function firstNonEmptyLine(markdown) {
|
|
185
|
+
return (markdown
|
|
186
|
+
.split(/\r?\n/)
|
|
187
|
+
.map((line) => line.trim())
|
|
188
|
+
.find((line) => line && !line.startsWith("#") && !line.startsWith("```")) || "");
|
|
189
|
+
}
|
|
190
|
+
/** True when an accepted result captured no structured signal at all. Drives the
|
|
191
|
+
* "warn, don't silently pass" surface in the record paths. */
|
|
192
|
+
function isEmptyCapture(envelope) {
|
|
193
|
+
return (envelope.findings?.length || 0) === 0 && (envelope.evidence?.length || 0) === 0;
|
|
194
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Run Export / Import — portable run archive format (v0.1.74).
|
|
3
|
+
//
|
|
4
|
+
// BSD discipline: explicit state, portable format. Export serializes a run
|
|
5
|
+
// to a single JSON file; import restores it in a new location. Both functions
|
|
6
|
+
// are pure — they read the run, write the export/import, and return the result.
|
|
7
|
+
//
|
|
8
|
+
// Track B: users can export a run on one machine and restore it on another.
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.exportRun = exportRun;
|
|
14
|
+
exports.importRun = importRun;
|
|
15
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
16
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
17
|
+
const state_1 = require("./state");
|
|
18
|
+
const version_1 = require("./version");
|
|
19
|
+
/** Export a run to a portable JSON file. The export includes the full run
|
|
20
|
+
* state but NOT raw artifact files — only their paths and digests. */
|
|
21
|
+
function exportRun(run, outputPath) {
|
|
22
|
+
const exportedAt = new Date().toISOString();
|
|
23
|
+
const exported = {
|
|
24
|
+
schemaVersion: 1,
|
|
25
|
+
exportedAt,
|
|
26
|
+
sourceVersion: version_1.CURRENT_COOL_WORKFLOW_VERSION,
|
|
27
|
+
run,
|
|
28
|
+
artifacts: [],
|
|
29
|
+
audit: []
|
|
30
|
+
};
|
|
31
|
+
(0, state_1.writeJson)(outputPath, exported);
|
|
32
|
+
return {
|
|
33
|
+
runId: run.id,
|
|
34
|
+
exportedAt,
|
|
35
|
+
path: outputPath,
|
|
36
|
+
taskCount: run.tasks.length,
|
|
37
|
+
commitCount: run.commits.length
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Import a run from a portable JSON file into a target directory.
|
|
41
|
+
* Rebuilds run paths relative to the target dir. */
|
|
42
|
+
function importRun(exportPath, targetDir) {
|
|
43
|
+
const raw = JSON.parse(node_fs_1.default.readFileSync(exportPath, "utf8"));
|
|
44
|
+
if (raw.schemaVersion !== 1)
|
|
45
|
+
throw new Error(`Unsupported export schema version: ${raw.schemaVersion}`);
|
|
46
|
+
const run = raw.run;
|
|
47
|
+
const runDir = node_path_1.default.join(targetDir, ".cw", "runs", run.id);
|
|
48
|
+
const paths = (0, state_1.createRunPaths)(runDir);
|
|
49
|
+
(0, state_1.ensureRunDirs)(paths);
|
|
50
|
+
// Rebase all paths to the new target directory
|
|
51
|
+
run.paths = paths;
|
|
52
|
+
run.cwd = targetDir;
|
|
53
|
+
run.updatedAt = new Date().toISOString();
|
|
54
|
+
// Rebase node artifact paths too
|
|
55
|
+
for (const node of run.nodes || []) {
|
|
56
|
+
for (const artifact of node.artifacts || []) {
|
|
57
|
+
if (artifact.path && artifact.path.includes(".cw/runs/")) {
|
|
58
|
+
// Keep the original path as-is — the artifact may not exist in new location
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
(0, state_1.saveCheckpoint)(run);
|
|
63
|
+
return { run, runDir, statePath: paths.state };
|
|
64
|
+
}
|