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,630 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Shared capability core: the SINGLE source of truth for composite capabilities
|
|
3
|
+
// whose payload is assembled from more than one orchestrator call.
|
|
4
|
+
//
|
|
5
|
+
// BSD discipline (mechanism vs policy): these functions are MECHANISM. They live
|
|
6
|
+
// here — never in cli.ts or mcp-server.ts — so the CLI and the MCP surface are
|
|
7
|
+
// two renderings of ONE data source. Any capability that composes multiple
|
|
8
|
+
// runner calls (plan summary, app run, sandbox choice, commit envelope) MUST be
|
|
9
|
+
// expressed here and called identically by both surfaces. A composite that lives
|
|
10
|
+
// in only one surface is exactly the cross-surface drift v0.1.27 forbids.
|
|
11
|
+
//
|
|
12
|
+
// From v0.1.46: each exported entry function SHOULD self-register its capability
|
|
13
|
+
// metadata via registerCapability() from capability-registry.ts. This replaces
|
|
14
|
+
// the manual "add an entry to the giant array in capability-registry.ts" workflow
|
|
15
|
+
// with automatic discovery. New capabilities just add a registerCapability() call
|
|
16
|
+
// next to their implementation — no need to touch capability-registry.ts.
|
|
17
|
+
//
|
|
18
|
+
// See docs/cli-mcp-parity.7.md and src/capability-registry.ts.
|
|
19
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
20
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.QUICKSTART_DEFAULT_APP = void 0;
|
|
24
|
+
exports.planSummary = planSummary;
|
|
25
|
+
exports.appRun = appRun;
|
|
26
|
+
exports.sandboxChoose = sandboxChoose;
|
|
27
|
+
exports.commitEnvelope = commitEnvelope;
|
|
28
|
+
exports.compactOperatorStatus = compactOperatorStatus;
|
|
29
|
+
exports.runRegistryFor = runRegistryFor;
|
|
30
|
+
exports.runRegistryRefresh = runRegistryRefresh;
|
|
31
|
+
exports.runRegistryShow = runRegistryShow;
|
|
32
|
+
exports.runSearch = runSearch;
|
|
33
|
+
exports.runList = runList;
|
|
34
|
+
exports.runShow = runShow;
|
|
35
|
+
exports.runResume = runResume;
|
|
36
|
+
exports.runArchive = runArchive;
|
|
37
|
+
exports.runRerun = runRerun;
|
|
38
|
+
exports.queueAdd = queueAdd;
|
|
39
|
+
exports.queueList = queueList;
|
|
40
|
+
exports.queueDrain = queueDrain;
|
|
41
|
+
exports.queueShow = queueShow;
|
|
42
|
+
exports.schedPlan = schedPlan;
|
|
43
|
+
exports.schedLease = schedLease;
|
|
44
|
+
exports.schedRelease = schedRelease;
|
|
45
|
+
exports.schedComplete = schedComplete;
|
|
46
|
+
exports.schedReclaim = schedReclaim;
|
|
47
|
+
exports.schedReset = schedReset;
|
|
48
|
+
exports.schedPolicyShow = schedPolicyShow;
|
|
49
|
+
exports.schedPolicySet = schedPolicySet;
|
|
50
|
+
exports.runDrivePreview = runDrivePreview;
|
|
51
|
+
exports.runDrive = runDrive;
|
|
52
|
+
exports.quickstart = quickstart;
|
|
53
|
+
exports.backendAgentConfigShow = backendAgentConfigShow;
|
|
54
|
+
exports.backendAgentConfigSet = backendAgentConfigSet;
|
|
55
|
+
exports.gcPlan = gcPlan;
|
|
56
|
+
exports.gcRun = gcRun;
|
|
57
|
+
exports.gcVerify = gcVerify;
|
|
58
|
+
exports.runHistory = runHistory;
|
|
59
|
+
exports.metricsSummary = metricsSummary;
|
|
60
|
+
exports.sandboxProfileIdFrom = sandboxProfileIdFrom;
|
|
61
|
+
exports.withoutRuntimeKeys = withoutRuntimeKeys;
|
|
62
|
+
exports.optionalString = optionalString;
|
|
63
|
+
exports.isRecord = isRecord;
|
|
64
|
+
const capability_registry_1 = require("./capability-registry");
|
|
65
|
+
const drive_1 = require("./drive");
|
|
66
|
+
const agent_config_1 = require("./agent-config");
|
|
67
|
+
const run_registry_1 = require("./run-registry");
|
|
68
|
+
const observability_1 = require("./observability");
|
|
69
|
+
const state_1 = require("./state");
|
|
70
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
71
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
72
|
+
const scheduling_1 = require("./scheduling");
|
|
73
|
+
// ---- canonical plan payload -----------------------------------------------
|
|
74
|
+
// Both `cw plan` (default + --json) and `cw_plan` resolve to this exact object.
|
|
75
|
+
function planSummary(runner, workflowId, options) {
|
|
76
|
+
const run = runner.plan(workflowId, options);
|
|
77
|
+
return {
|
|
78
|
+
runId: run.id,
|
|
79
|
+
workflowId: run.workflow.id,
|
|
80
|
+
statePath: run.paths.state,
|
|
81
|
+
reportPath: run.paths.report,
|
|
82
|
+
pendingTasks: run.tasks.filter((task) => task.status === "pending").length
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
// Auto-register with the capability registry (v0.1.46 — no need to edit capability-registry.ts)
|
|
86
|
+
(0, capability_registry_1.registerCapability)({ capability: "plan", summary: "Plan a workflow run on a repo + app.", entry: "planSummary", surface: "both", cli: { path: ["plan"], jsonMode: "default" }, mcp: { tool: "cw_plan" } });
|
|
87
|
+
// ---- canonical app-run payload --------------------------------------------
|
|
88
|
+
// Both `cw app run` and `cw_app_run` resolve to this exact object. Structured
|
|
89
|
+
// app inputs + optional sandbox resolution, then a compact operator status.
|
|
90
|
+
function appRun(runner, args) {
|
|
91
|
+
const appId = String(args.appId || args.workflowId || "");
|
|
92
|
+
const inputs = isRecord(args.inputs) ? args.inputs : {};
|
|
93
|
+
const planOptions = { ...inputs, ...withoutRuntimeKeys(args) };
|
|
94
|
+
const sandboxProfileId = sandboxProfileIdFrom(args);
|
|
95
|
+
const resolvedSandbox = sandboxProfileId ? runner.showSandboxProfile(sandboxProfileId, args) : undefined;
|
|
96
|
+
const run = runner.plan(appId, planOptions);
|
|
97
|
+
const status = runner.operatorStatus(run.id);
|
|
98
|
+
return {
|
|
99
|
+
runId: run.id,
|
|
100
|
+
workflowId: run.workflow.id,
|
|
101
|
+
appId: run.workflow.app?.id || appId,
|
|
102
|
+
appVersion: run.workflow.app?.version,
|
|
103
|
+
statePath: run.paths.state,
|
|
104
|
+
reportPath: run.paths.report,
|
|
105
|
+
pendingTasks: run.tasks.filter((task) => task.status === "pending").length,
|
|
106
|
+
operatorStatus: compactOperatorStatus(status),
|
|
107
|
+
nextActions: status.nextActions,
|
|
108
|
+
sandboxProfileId,
|
|
109
|
+
sandboxProfile: resolvedSandbox
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
(0, capability_registry_1.registerCapability)({ capability: "app.run", summary: "Plan a run on a named app with structured inputs.", entry: "appRun", surface: "both", cli: { path: ["app", "run"], caseTokens: ["app"], jsonMode: "default" }, mcp: { tool: "cw_app_run" } });
|
|
113
|
+
// ---- canonical sandbox choice payload -------------------------------------
|
|
114
|
+
// Both `cw sandbox choose|resolve` and `cw_sandbox_choose|cw_sandbox_resolve`
|
|
115
|
+
// resolve to this exact object.
|
|
116
|
+
function sandboxChoose(runner, args) {
|
|
117
|
+
const profileId = sandboxProfileIdFrom(args) || "readonly";
|
|
118
|
+
const profile = runner.showSandboxProfile(profileId, args);
|
|
119
|
+
return {
|
|
120
|
+
profileId,
|
|
121
|
+
sandboxProfileId: profile.id,
|
|
122
|
+
valid: true,
|
|
123
|
+
profile
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
// ---- canonical commit envelope --------------------------------------------
|
|
127
|
+
// `cw_commit` resolves to this operator-facing envelope. The CLI `commit`
|
|
128
|
+
// command intentionally emits the raw StateCommitResult for scripting; both
|
|
129
|
+
// derive from the single core entry runner.commit (declared, not drift — see
|
|
130
|
+
// the capability registry's `commit` descriptor).
|
|
131
|
+
function commitEnvelope(runner, runId, args) {
|
|
132
|
+
const result = runner.commit(runId, args);
|
|
133
|
+
const commit = result.commit;
|
|
134
|
+
const status = runner.operatorStatus(runId);
|
|
135
|
+
return {
|
|
136
|
+
runId,
|
|
137
|
+
commitId: commit.id,
|
|
138
|
+
verifierGated: commit.verifierGated,
|
|
139
|
+
checkpoint: commit.checkpoint,
|
|
140
|
+
verifierNodeId: commit.verifierNodeId,
|
|
141
|
+
candidateId: commit.candidateId,
|
|
142
|
+
selectionId: commit.selectionId,
|
|
143
|
+
evidenceCount: (commit.evidence || []).length,
|
|
144
|
+
snapshotPath: commit.snapshotPath,
|
|
145
|
+
nextActions: status.nextActions,
|
|
146
|
+
commit
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
(0, capability_registry_1.registerCapability)({ capability: "commit", summary: "Create a verifier-gated state commit with evidence.", entry: "commitEnvelope", surface: "both", cli: { path: ["commit"], jsonMode: "default" }, mcp: { tool: "cw_commit" }, payloadIdentical: false, reason: "CLI renders a human summary with path hints; MCP returns the structured commit payload alone." });
|
|
150
|
+
function compactOperatorStatus(status) {
|
|
151
|
+
return {
|
|
152
|
+
runId: status.runId,
|
|
153
|
+
workflowId: status.workflowId,
|
|
154
|
+
appId: status.appId,
|
|
155
|
+
appVersion: status.appVersion,
|
|
156
|
+
loopStage: status.loopStage,
|
|
157
|
+
activePhase: status.activePhase,
|
|
158
|
+
blocked: status.blocked,
|
|
159
|
+
blockedReasons: status.blockedReasons,
|
|
160
|
+
pendingTasks: status.tasks.pending.length,
|
|
161
|
+
runningTasks: status.tasks.running.length,
|
|
162
|
+
completedTasks: status.tasks.completed.length,
|
|
163
|
+
nextActions: status.nextActions
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
// ---- run registry / control plane (v0.1.28) -------------------------------
|
|
167
|
+
// MECHANISM, ONE SOURCE: the CLI and MCP surfaces both route through these
|
|
168
|
+
// functions so `cw <cmd> --json` is byte-identical to `cw_<tool>`. Each accepts
|
|
169
|
+
// the raw CLI options OR the raw MCP arguments and normalizes them identically,
|
|
170
|
+
// then calls the single RunRegistry method. The registry is constructed from the
|
|
171
|
+
// same resolved cwd on both surfaces (CLI: --cwd|process.cwd(); MCP chdir'd to
|
|
172
|
+
// args.cwd), so repo/home roots line up.
|
|
173
|
+
function runRegistryFor(args, planner) {
|
|
174
|
+
return new run_registry_1.RunRegistry(String(args.cwd || process.cwd()), planner);
|
|
175
|
+
}
|
|
176
|
+
function scopeOf(args, fallback) {
|
|
177
|
+
if (args.scope === "repo")
|
|
178
|
+
return "repo";
|
|
179
|
+
if (args.scope === "home")
|
|
180
|
+
return "home";
|
|
181
|
+
return fallback;
|
|
182
|
+
}
|
|
183
|
+
function lifecycleOf(value) {
|
|
184
|
+
return (0, run_registry_1.isRunLifecycleState)(value) ? value : undefined;
|
|
185
|
+
}
|
|
186
|
+
function flag(value) {
|
|
187
|
+
if (value === undefined)
|
|
188
|
+
return undefined;
|
|
189
|
+
if (value === false || value === "false" || value === "no" || value === "0")
|
|
190
|
+
return false;
|
|
191
|
+
return Boolean(value);
|
|
192
|
+
}
|
|
193
|
+
function runRegistryRefresh(reg, args) {
|
|
194
|
+
return reg.refresh({ scope: scopeOf(args, "repo") });
|
|
195
|
+
}
|
|
196
|
+
function runRegistryShow(reg, args) {
|
|
197
|
+
return reg.show({ scope: scopeOf(args, "repo") });
|
|
198
|
+
}
|
|
199
|
+
function runSearch(reg, args) {
|
|
200
|
+
return reg.search({
|
|
201
|
+
scope: scopeOf(args, "home"),
|
|
202
|
+
text: optionalString(args.text || args.q || args.query),
|
|
203
|
+
app: optionalString(args.app || args.appId),
|
|
204
|
+
status: lifecycleOf(args.status),
|
|
205
|
+
repo: optionalString(args.repo),
|
|
206
|
+
since: optionalString(args.since),
|
|
207
|
+
until: optionalString(args.until),
|
|
208
|
+
includeArchived: flag(args.includeArchived ?? args["include-archived"]),
|
|
209
|
+
limit: args.limit === undefined ? undefined : Number(args.limit),
|
|
210
|
+
offset: args.offset === undefined ? undefined : Number(args.offset)
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
function runList(reg, args) {
|
|
214
|
+
return reg.list({
|
|
215
|
+
scope: scopeOf(args, "home"),
|
|
216
|
+
includeArchived: flag(args.includeArchived ?? args["include-archived"]),
|
|
217
|
+
limit: args.limit === undefined ? undefined : Number(args.limit),
|
|
218
|
+
offset: args.offset === undefined ? undefined : Number(args.offset)
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
function runShow(reg, runId, args) {
|
|
222
|
+
return reg.showRun(runId, { scope: scopeOf(args, "home") });
|
|
223
|
+
}
|
|
224
|
+
function runResume(reg, runId, args) {
|
|
225
|
+
return reg.resume(runId, {
|
|
226
|
+
scope: scopeOf(args, "home"),
|
|
227
|
+
limit: args.limit === undefined ? undefined : Number(args.limit)
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
function runArchive(reg, runId, args) {
|
|
231
|
+
if (runId) {
|
|
232
|
+
return reg.archive(runId, {
|
|
233
|
+
scope: scopeOf(args, "home"),
|
|
234
|
+
reason: optionalString(args.reason),
|
|
235
|
+
unarchive: flag(args.unarchive)
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
const days = Number(args.olderThanDays ?? args["older-than-days"]);
|
|
239
|
+
const states = parseLifecycleList(args.state ?? args.status);
|
|
240
|
+
return reg.archiveByPolicy({
|
|
241
|
+
schemaVersion: 1,
|
|
242
|
+
archiveOlderThanDays: Number.isFinite(days) ? days : 0,
|
|
243
|
+
archiveStates: states.length ? states : ["completed", "failed"],
|
|
244
|
+
defaultQueuePriority: 100
|
|
245
|
+
}, { scope: scopeOf(args, "home") });
|
|
246
|
+
}
|
|
247
|
+
function runRerun(reg, runId, args) {
|
|
248
|
+
return reg.rerun(runId, { scope: scopeOf(args, "home"), reason: optionalString(args.reason) });
|
|
249
|
+
}
|
|
250
|
+
function queueAdd(reg, args) {
|
|
251
|
+
return reg.queueAdd({
|
|
252
|
+
runId: optionalString(args.runId),
|
|
253
|
+
appId: optionalString(args.appId || args.app),
|
|
254
|
+
workflowId: optionalString(args.workflowId || args.workflow),
|
|
255
|
+
repo: optionalString(args.repo),
|
|
256
|
+
priority: args.priority === undefined ? undefined : Number(args.priority),
|
|
257
|
+
note: optionalString(args.note),
|
|
258
|
+
id: optionalString(args.id)
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
function queueList(reg, args) {
|
|
262
|
+
const status = optionalString(args.status);
|
|
263
|
+
return reg.queueList({
|
|
264
|
+
status: status,
|
|
265
|
+
repo: optionalString(args.repo)
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
function queueDrain(reg, args) {
|
|
269
|
+
return reg.queueDrain({
|
|
270
|
+
limit: args.limit === undefined ? undefined : Number(args.limit),
|
|
271
|
+
repo: optionalString(args.repo)
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
function queueShow(reg, id) {
|
|
275
|
+
return reg.queueShow(id);
|
|
276
|
+
}
|
|
277
|
+
// ---- control-plane scheduling (v0.1.37) -----------------------------------
|
|
278
|
+
function loadSchedulingPolicy(reg) {
|
|
279
|
+
const file = reg.schedulingPolicyPath();
|
|
280
|
+
if (node_fs_1.default.existsSync(file)) {
|
|
281
|
+
try {
|
|
282
|
+
return { policy: (0, scheduling_1.normalizeSchedulingPolicy)((0, state_1.readJson)(file)), source: "file" };
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
/* fall through to default */
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return { policy: scheduling_1.DEFAULT_SCHEDULING_POLICY, source: "default" };
|
|
289
|
+
}
|
|
290
|
+
function schedNow(args) {
|
|
291
|
+
return optionalString(args.now) || new Date().toISOString();
|
|
292
|
+
}
|
|
293
|
+
function isTrue(value) {
|
|
294
|
+
return value === true || value === "true" || value === "1";
|
|
295
|
+
}
|
|
296
|
+
function schedPlan(reg, args) {
|
|
297
|
+
return (0, scheduling_1.planSchedule)(reg.loadQueueEntries(), loadSchedulingPolicy(reg).policy, schedNow(args));
|
|
298
|
+
}
|
|
299
|
+
function schedLease(reg, args) {
|
|
300
|
+
const now = schedNow(args);
|
|
301
|
+
const policy = loadSchedulingPolicy(reg).policy;
|
|
302
|
+
const limit = args.limit === undefined ? undefined : Number(args.limit);
|
|
303
|
+
const { entries, leases } = (0, scheduling_1.applyLease)(reg.loadQueueEntries(), policy, now, limit);
|
|
304
|
+
reg.saveQueueEntries(entries);
|
|
305
|
+
return { schemaVersion: 1, now, granted: leases.length, leases };
|
|
306
|
+
}
|
|
307
|
+
function schedRelease(reg, args) {
|
|
308
|
+
const now = schedNow(args);
|
|
309
|
+
const failed = isTrue(args.failed);
|
|
310
|
+
const { entries, matched } = (0, scheduling_1.leaseRelease)(reg.loadQueueEntries(), String(args.leaseId || ""), loadSchedulingPolicy(reg).policy, now, {
|
|
311
|
+
failed,
|
|
312
|
+
reason: optionalString(args.reason)
|
|
313
|
+
});
|
|
314
|
+
if (!matched)
|
|
315
|
+
throw new Error(`No active lease to release: ${args.leaseId}`);
|
|
316
|
+
reg.saveQueueEntries(entries);
|
|
317
|
+
return { schemaVersion: 1, released: String(args.leaseId || ""), failed };
|
|
318
|
+
}
|
|
319
|
+
function schedComplete(reg, args) {
|
|
320
|
+
const { entries, matched } = (0, scheduling_1.leaseComplete)(reg.loadQueueEntries(), String(args.leaseId || ""), schedNow(args));
|
|
321
|
+
if (!matched)
|
|
322
|
+
throw new Error(`No active lease to complete: ${args.leaseId}`);
|
|
323
|
+
reg.saveQueueEntries(entries);
|
|
324
|
+
return { schemaVersion: 1, completed: String(args.leaseId || "") };
|
|
325
|
+
}
|
|
326
|
+
function schedReclaim(reg, args) {
|
|
327
|
+
const now = schedNow(args);
|
|
328
|
+
const { entries, reclaimed } = (0, scheduling_1.reclaimExpired)(reg.loadQueueEntries(), loadSchedulingPolicy(reg).policy, now);
|
|
329
|
+
reg.saveQueueEntries(entries);
|
|
330
|
+
return { schemaVersion: 1, now, reclaimed };
|
|
331
|
+
}
|
|
332
|
+
function schedReset(reg, args) {
|
|
333
|
+
const { entries, matched } = (0, scheduling_1.resetEntry)(reg.loadQueueEntries(), String(args.id || ""));
|
|
334
|
+
if (!matched)
|
|
335
|
+
throw new Error(`No parked entry to reset: ${args.id}`);
|
|
336
|
+
reg.saveQueueEntries(entries);
|
|
337
|
+
return { schemaVersion: 1, reset: String(args.id || "") };
|
|
338
|
+
}
|
|
339
|
+
function schedPolicyShow(reg) {
|
|
340
|
+
const { policy, source } = loadSchedulingPolicy(reg);
|
|
341
|
+
return { schemaVersion: 1, policy, source };
|
|
342
|
+
}
|
|
343
|
+
function schedPolicySet(reg, args) {
|
|
344
|
+
const current = loadSchedulingPolicy(reg).policy;
|
|
345
|
+
const patch = {};
|
|
346
|
+
for (const key of ["maxConcurrent", "maxAttempts", "leaseTtlMs", "backoffBaseMs", "backoffFactor", "backoffCapMs"]) {
|
|
347
|
+
if (args[key] !== undefined)
|
|
348
|
+
patch[key] = Number(args[key]);
|
|
349
|
+
}
|
|
350
|
+
const policy = (0, scheduling_1.normalizeSchedulingPolicy)({ ...current, ...patch });
|
|
351
|
+
(0, state_1.writeJson)(reg.schedulingPolicyPath(), policy);
|
|
352
|
+
return { schemaVersion: 1, policy, source: "file" };
|
|
353
|
+
}
|
|
354
|
+
// ---- agent delegation drive (v0.1.38) -------------------------------------
|
|
355
|
+
// MECHANISM, ONE SOURCE: both surfaces route drive/preview/config through these.
|
|
356
|
+
// The read-only preview + config-show payloads are deterministic (counts from
|
|
357
|
+
// state, host-stable config path) with NO now-derived numeric field, so
|
|
358
|
+
// `cw <cmd> --json` is byte-identical to `cw_<tool>`.
|
|
359
|
+
/** Read-only, deterministic preview of a run's NEXT drive step. */
|
|
360
|
+
function runDrivePreview(runner, args) {
|
|
361
|
+
return (0, drive_1.drivePreview)(runner, String(args.runId || ""), args);
|
|
362
|
+
}
|
|
363
|
+
const DRIVE_RUNTIME_KEYS = [
|
|
364
|
+
"once",
|
|
365
|
+
"now",
|
|
366
|
+
"preview",
|
|
367
|
+
"step",
|
|
368
|
+
"drive",
|
|
369
|
+
"json",
|
|
370
|
+
"format",
|
|
371
|
+
"run",
|
|
372
|
+
"runId",
|
|
373
|
+
"cwd",
|
|
374
|
+
"agentCommand",
|
|
375
|
+
"agent-command",
|
|
376
|
+
"agentArgs",
|
|
377
|
+
"agent-args",
|
|
378
|
+
"agentEndpoint",
|
|
379
|
+
"agent-endpoint",
|
|
380
|
+
"agentModel",
|
|
381
|
+
"agent-model",
|
|
382
|
+
"agentTimeoutMs",
|
|
383
|
+
"agent-timeout-ms"
|
|
384
|
+
];
|
|
385
|
+
function planInputsFor(args) {
|
|
386
|
+
const copy = withoutRuntimeKeys(args);
|
|
387
|
+
for (const key of DRIVE_RUNTIME_KEYS)
|
|
388
|
+
delete copy[key];
|
|
389
|
+
return copy;
|
|
390
|
+
}
|
|
391
|
+
/** Mutating drive step/run. Plans a fresh run for an app id, or continues a run id.
|
|
392
|
+
* The agent hop goes ONLY through the agent backend; this composes existing verbs.
|
|
393
|
+
*
|
|
394
|
+
* The run lives under its repo's `.cw/` and every runner verb resolves a run from
|
|
395
|
+
* the process cwd, so the drive operates WITH the run's repo as cwd (exactly how
|
|
396
|
+
* the golden path runs each verb from the repo dir) — then restores cwd. This lets
|
|
397
|
+
* `cw run <app> --drive --repo X` work when invoked from anywhere. */
|
|
398
|
+
function runDrive(runner, args) {
|
|
399
|
+
const cwd0 = process.cwd();
|
|
400
|
+
try {
|
|
401
|
+
let runId = optionalString(args.runId || args.run);
|
|
402
|
+
let repoCwd = optionalString(args.repo);
|
|
403
|
+
if (!runId) {
|
|
404
|
+
const appId = String(args.appId || args.workflowId || args.app || "");
|
|
405
|
+
if (!appId)
|
|
406
|
+
throw new Error("run --drive requires an app id (or --run <run-id> to continue)");
|
|
407
|
+
const run = runner.plan(appId, planInputsFor(args));
|
|
408
|
+
runId = run.id;
|
|
409
|
+
repoCwd = run.cwd;
|
|
410
|
+
}
|
|
411
|
+
if (repoCwd && repoCwd !== process.cwd() && node_fs_1.default.existsSync(repoCwd))
|
|
412
|
+
process.chdir(repoCwd);
|
|
413
|
+
return (0, drive_1.drive)(runner, runId, { once: isTrue(args.once), now: optionalString(args.now), args });
|
|
414
|
+
}
|
|
415
|
+
finally {
|
|
416
|
+
if (process.cwd() !== cwd0)
|
|
417
|
+
process.chdir(cwd0);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
/** The app the one-command quickstart plans when none is named. */
|
|
421
|
+
exports.QUICKSTART_DEFAULT_APP = "architecture-review";
|
|
422
|
+
/** ONE-COMMAND quickstart (v0.1.38+): plan(app) -> run --drive -> report in a single
|
|
423
|
+
* invocation, so a newcomer gets a cited risk report from one command on a target
|
|
424
|
+
* repo. This is a THIN UX wrapper — NOT a new engine: it composes the EXISTING
|
|
425
|
+
* `runDrive` core (which already plans the run, then delegates every worker to the
|
|
426
|
+
* configured agent backend and commits) and then writes the report. It introduces
|
|
427
|
+
* no second executor, queue, or scheduler, and imports no model SDK.
|
|
428
|
+
*
|
|
429
|
+
* RED LINE (DIRECTION.md): worker execution still DELEGATES to the operator's own
|
|
430
|
+
* agent backend (claude -p / codex exec / HTTP endpoint). With no agent configured
|
|
431
|
+
* the drive fails closed (status=blocked) and we never fabricate a completion. */
|
|
432
|
+
function quickstart(runner, args) {
|
|
433
|
+
const appId = String(args.appId || args.app || args.workflowId || exports.QUICKSTART_DEFAULT_APP);
|
|
434
|
+
const agentConfigured = Boolean((0, agent_config_1.resolveAgentConfig)(args).command || (0, agent_config_1.resolveAgentConfig)(args).endpoint);
|
|
435
|
+
// `--preview`: read-only, deterministic next-step projection (no spawn, no commit).
|
|
436
|
+
// Plan a fresh run (the read-only first verb) then project the next drive step.
|
|
437
|
+
if (isTrue(args.preview)) {
|
|
438
|
+
const cwd0 = process.cwd();
|
|
439
|
+
try {
|
|
440
|
+
let runId = optionalString(args.runId || args.run);
|
|
441
|
+
let repoCwd = optionalString(args.repo);
|
|
442
|
+
if (!runId) {
|
|
443
|
+
const run = runner.plan(appId, planInputsFor(args));
|
|
444
|
+
runId = run.id;
|
|
445
|
+
repoCwd = run.cwd;
|
|
446
|
+
}
|
|
447
|
+
if (repoCwd && repoCwd !== process.cwd() && node_fs_1.default.existsSync(repoCwd))
|
|
448
|
+
process.chdir(repoCwd);
|
|
449
|
+
return (0, drive_1.drivePreview)(runner, runId, args);
|
|
450
|
+
}
|
|
451
|
+
finally {
|
|
452
|
+
if (process.cwd() !== cwd0)
|
|
453
|
+
process.chdir(cwd0);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
// Drive end-to-end (or one `--once` step). runDrive plans the run, delegates each
|
|
457
|
+
// worker to the agent backend, and commits — we add only the report write + a
|
|
458
|
+
// single assembled payload. No orchestration is duplicated here.
|
|
459
|
+
const result = runDrive(runner, { ...args, appId });
|
|
460
|
+
// Always (re)write the report so the one command yields a report.md on disk, even
|
|
461
|
+
// when the drive blocked/parked (a partial report is still useful triage).
|
|
462
|
+
const cwd0 = process.cwd();
|
|
463
|
+
let reportPath = result.reportPath;
|
|
464
|
+
try {
|
|
465
|
+
// runDrive restored cwd, so the runs root would resolve against the CALLER's
|
|
466
|
+
// cwd here — orphaning the run when quickstart is invoked cross-directory
|
|
467
|
+
// (cwd = plugin dir, --repo elsewhere: the README's headline command). The
|
|
468
|
+
// run's statePath (<repo>/.cw/runs/<id>/state.json) is authoritative however
|
|
469
|
+
// the run was planned or continued; chdir to ITS repo BEFORE any run read.
|
|
470
|
+
const runRepoCwd = node_path_1.default.resolve(node_path_1.default.dirname(result.statePath), "..", "..", "..");
|
|
471
|
+
if (runRepoCwd !== process.cwd() && node_fs_1.default.existsSync(runRepoCwd))
|
|
472
|
+
process.chdir(runRepoCwd);
|
|
473
|
+
reportPath = runner.report(result.runId).path;
|
|
474
|
+
}
|
|
475
|
+
finally {
|
|
476
|
+
if (process.cwd() !== cwd0)
|
|
477
|
+
process.chdir(cwd0);
|
|
478
|
+
}
|
|
479
|
+
let hint;
|
|
480
|
+
if (!agentConfigured) {
|
|
481
|
+
hint =
|
|
482
|
+
"agent backend not configured — set CW_AGENT_COMMAND (e.g. \"claude -p\") or pass --agent-command, then re-run. The one command DELEGATES worker execution to YOUR agent; it never executes a model itself.";
|
|
483
|
+
}
|
|
484
|
+
else if (result.status === "parked") {
|
|
485
|
+
hint = `a worker parked past its retry budget — inspect: cw run show ${result.runId}`;
|
|
486
|
+
}
|
|
487
|
+
else if (result.status === "blocked") {
|
|
488
|
+
hint = `the drive is blocked — inspect: cw run drive ${result.runId}`;
|
|
489
|
+
}
|
|
490
|
+
else if (result.status === "in-progress") {
|
|
491
|
+
hint = `one step advanced (--once) — continue: cw quickstart ${appId} --run ${result.runId} --once`;
|
|
492
|
+
}
|
|
493
|
+
return {
|
|
494
|
+
schemaVersion: 1,
|
|
495
|
+
appId,
|
|
496
|
+
runId: result.runId,
|
|
497
|
+
workflowId: result.workflowId,
|
|
498
|
+
status: result.status,
|
|
499
|
+
plannedWorkers: result.plannedWorkers,
|
|
500
|
+
completedWorkers: result.completedWorkers,
|
|
501
|
+
parkedWorkers: result.parkedWorkers,
|
|
502
|
+
commitId: result.commitId,
|
|
503
|
+
reportPath,
|
|
504
|
+
statePath: result.statePath,
|
|
505
|
+
agentConfigured,
|
|
506
|
+
steps: result.steps,
|
|
507
|
+
hint
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
/** Read-only, deterministic projection of the effective agent config (secret-stripped). */
|
|
511
|
+
function backendAgentConfigShow(args) {
|
|
512
|
+
return (0, agent_config_1.agentConfigShow)(args);
|
|
513
|
+
}
|
|
514
|
+
/** Persist the durable agent config (secret-stripped) and return the new state. */
|
|
515
|
+
function backendAgentConfigSet(args) {
|
|
516
|
+
(0, agent_config_1.setAgentConfigFile)(args);
|
|
517
|
+
return (0, agent_config_1.agentConfigShow)(args);
|
|
518
|
+
}
|
|
519
|
+
// ---- run retention & provable reclamation (v0.1.39) -----------------------
|
|
520
|
+
// MECHANISM, ONE SOURCE: both surfaces route gc plan/run/verify through these.
|
|
521
|
+
// `gc plan`/`gc verify` are read-only + deterministic (only `generatedAt` is
|
|
522
|
+
// now-derived ISO, allowed by the parity rule); `gc run` is the disk-freeing tier.
|
|
523
|
+
function reclaimPolicyFrom(args) {
|
|
524
|
+
const policy = {};
|
|
525
|
+
const days = Number(args.reclaimAfterArchiveDays ?? args["reclaim-after-archive-days"] ?? args.olderThanDays ?? args["older-than-days"]);
|
|
526
|
+
if (Number.isFinite(days))
|
|
527
|
+
policy.reclaimAfterArchiveDays = days;
|
|
528
|
+
const keepScratch = flag(args.keepScratch ?? args["keep-scratch"]);
|
|
529
|
+
if (keepScratch !== undefined)
|
|
530
|
+
policy.keepScratch = keepScratch;
|
|
531
|
+
const keepSnapshots = flag(args.keepSnapshots ?? args["keep-snapshots"]);
|
|
532
|
+
if (keepSnapshots !== undefined)
|
|
533
|
+
policy.keepSnapshots = keepSnapshots;
|
|
534
|
+
const maxRuns = Number(args.maxReclaimRuns ?? args["max-reclaim-runs"]);
|
|
535
|
+
if (Number.isFinite(maxRuns))
|
|
536
|
+
policy.maxReclaimRuns = maxRuns;
|
|
537
|
+
const maxBytes = Number(args.maxReclaimBytes ?? args["max-reclaim-bytes"]);
|
|
538
|
+
if (Number.isFinite(maxBytes))
|
|
539
|
+
policy.maxReclaimBytes = maxBytes;
|
|
540
|
+
const states = parseLifecycleList(args.state ?? args.status);
|
|
541
|
+
if (states.length)
|
|
542
|
+
policy.reclaimStates = states;
|
|
543
|
+
return policy;
|
|
544
|
+
}
|
|
545
|
+
function gcPlan(reg, runId, args) {
|
|
546
|
+
return reg.gcPlan({ scope: scopeOf(args, "home"), runId: runId || optionalString(args.runId), policy: reclaimPolicyFrom(args), now: optionalString(args.now) });
|
|
547
|
+
}
|
|
548
|
+
function gcRun(reg, runId, args) {
|
|
549
|
+
return reg.gcRun({
|
|
550
|
+
scope: scopeOf(args, "home"),
|
|
551
|
+
runId: runId || optionalString(args.runId),
|
|
552
|
+
policy: reclaimPolicyFrom(args),
|
|
553
|
+
now: optionalString(args.now),
|
|
554
|
+
actor: optionalString(args.actor),
|
|
555
|
+
limit: args.limit === undefined ? undefined : Number(args.limit)
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
function gcVerify(reg, runId, args) {
|
|
559
|
+
return reg.gcVerify(runId, { scope: scopeOf(args, "home") });
|
|
560
|
+
}
|
|
561
|
+
function runHistory(reg, args) {
|
|
562
|
+
return reg.history({
|
|
563
|
+
scope: scopeOf(args, "home"),
|
|
564
|
+
app: optionalString(args.app || args.appId),
|
|
565
|
+
status: lifecycleOf(args.status),
|
|
566
|
+
limit: args.limit === undefined ? undefined : Number(args.limit),
|
|
567
|
+
offset: args.offset === undefined ? undefined : Number(args.offset)
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
// ---- observability + cost accounting (v0.1.31) ----------------------------
|
|
571
|
+
// MECHANISM, ONE SOURCE: both `cw metrics summary --json` and `cw_metrics_summary`
|
|
572
|
+
// route through this function. It enumerates the v0.1.28 registry (derived live
|
|
573
|
+
// from source), loads each run's durable state, and DERIVES the cross-repo
|
|
574
|
+
// rollup. Runs whose source is unreadable are counted in `unreadableRuns` (fail
|
|
575
|
+
// closed), never silently dropped. Pricing is POLICY via `--pricing`; `now` is
|
|
576
|
+
// injectable via `args.now` for eval/replay determinism.
|
|
577
|
+
function metricsSummary(reg, runner, args) {
|
|
578
|
+
const scope = scopeOf(args, "repo");
|
|
579
|
+
const report = reg.show({ scope });
|
|
580
|
+
const policy = (0, observability_1.loadCostPolicy)(args, runner.pluginRoot);
|
|
581
|
+
const now = optionalString(args.now) || new Date().toISOString();
|
|
582
|
+
const inputs = [];
|
|
583
|
+
let unreadableRuns = 0;
|
|
584
|
+
for (const record of report.index.records) {
|
|
585
|
+
try {
|
|
586
|
+
const loaded = (0, state_1.loadRunStateFile)(record.statePath, { dryRun: true });
|
|
587
|
+
if (loaded.report.status === "unsupported") {
|
|
588
|
+
unreadableRuns++;
|
|
589
|
+
continue;
|
|
590
|
+
}
|
|
591
|
+
inputs.push({
|
|
592
|
+
run: loaded.run,
|
|
593
|
+
repo: record.repo,
|
|
594
|
+
persistedFingerprint: (0, observability_1.loadPersistedMetricsFingerprint)(loaded.run)
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
catch {
|
|
598
|
+
unreadableRuns++;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
return (0, observability_1.deriveMetricsSummary)(inputs, { now, scope, policy, unreadableRuns });
|
|
602
|
+
}
|
|
603
|
+
function parseLifecycleList(value) {
|
|
604
|
+
const raw = Array.isArray(value) ? value : value === undefined ? [] : [value];
|
|
605
|
+
const out = [];
|
|
606
|
+
for (const item of raw) {
|
|
607
|
+
if ((0, run_registry_1.isRunLifecycleState)(item))
|
|
608
|
+
out.push(item);
|
|
609
|
+
}
|
|
610
|
+
return out;
|
|
611
|
+
}
|
|
612
|
+
// ---- shared argument helpers ----------------------------------------------
|
|
613
|
+
function sandboxProfileIdFrom(args) {
|
|
614
|
+
return optionalString(args.sandbox || args.sandboxProfile || args.sandboxProfileId || args.profileId);
|
|
615
|
+
}
|
|
616
|
+
function withoutRuntimeKeys(args) {
|
|
617
|
+
const copy = { ...args };
|
|
618
|
+
for (const key of ["appId", "workflowId", "inputs", "sandbox", "sandboxProfile", "sandboxProfileId", "profileId"]) {
|
|
619
|
+
delete copy[key];
|
|
620
|
+
}
|
|
621
|
+
return copy;
|
|
622
|
+
}
|
|
623
|
+
function optionalString(value) {
|
|
624
|
+
if (value === undefined || value === null || value === "")
|
|
625
|
+
return undefined;
|
|
626
|
+
return String(value);
|
|
627
|
+
}
|
|
628
|
+
function isRecord(value) {
|
|
629
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
630
|
+
}
|