cool-workflow 0.1.97 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +11 -2
- package/apps/architecture-review/app.json +1 -1
- package/apps/architecture-review-fast/app.json +1 -1
- package/apps/end-to-end-golden-path/app.json +1 -1
- package/apps/pr-review-fix-ci/app.json +1 -1
- package/apps/release-cut/app.json +1 -1
- package/apps/research-synthesis/app.json +1 -1
- package/dist/cli/dispatch.js +236 -0
- package/dist/cli/entry.js +120 -0
- package/dist/cli/io.js +21 -4
- package/dist/cli/parseargv.js +157 -0
- package/dist/cli.js +6 -33
- package/dist/core/capability-table.js +3534 -0
- package/dist/core/format/help.js +314 -0
- package/dist/{state-explosion/format.js → core/format/state-explosion-text.js} +10 -1
- package/dist/core/hash.js +137 -0
- package/dist/core/multi-agent/candidate-scoring.js +219 -0
- package/dist/core/multi-agent/collaboration.js +481 -0
- package/dist/core/multi-agent/coordinator.js +515 -0
- package/dist/core/multi-agent/eval-replay.js +306 -0
- package/dist/core/multi-agent/runtime.js +929 -0
- package/dist/core/multi-agent/topology.js +298 -0
- package/dist/core/multi-agent/trust-policy.js +197 -0
- package/dist/core/pipeline/commit-gate.js +320 -0
- package/dist/{pipeline-contract.js → core/pipeline/contract.js} +24 -37
- package/dist/core/pipeline/dispatch.js +103 -0
- package/dist/core/pipeline/drive-decide.js +227 -0
- package/dist/core/pipeline/error-feedback.js +161 -0
- package/dist/core/pipeline/loop-expansion.js +124 -0
- package/dist/{result-normalize.js → core/pipeline/result-normalize.js} +14 -37
- package/dist/core/pipeline/runner.js +230 -0
- package/dist/{contract-migration.js → core/state/contract-migration.js} +68 -92
- package/dist/{state-migrations.js → core/state/migrations.js} +103 -96
- package/dist/core/state/node-projection.js +95 -0
- package/dist/core/state/node-snapshot.js +230 -0
- package/dist/core/state/run-paths.js +93 -0
- package/dist/{schema-validate.js → core/state/schema-validate.js} +35 -28
- package/dist/core/state/schema.js +50 -0
- package/dist/core/state/state-explosion/digest.js +243 -0
- package/dist/core/state/state-explosion/graph.js +527 -0
- package/dist/{state-explosion → core/state/state-explosion}/helpers.js +34 -3
- package/dist/core/state/state-explosion/report.js +187 -0
- package/dist/{state-explosion → core/state/state-explosion}/size.js +25 -7
- package/dist/{state-node.js → core/state/state-node.js} +90 -113
- package/dist/core/state/types.js +19 -0
- package/dist/{validation.js → core/state/validation.js} +64 -131
- package/dist/core/trust/evidence-grounding.js +134 -0
- package/dist/core/trust/ledger.js +199 -0
- package/dist/{telemetry-attestation.js → core/trust/telemetry-attestation.js} +94 -68
- package/dist/core/trust/telemetry-ledger.js +127 -0
- package/dist/core/types.js +20 -0
- package/dist/core/version.js +16 -0
- package/dist/{workflow-app-framework.js → core/workflow-apps/app-schema.js} +337 -426
- package/dist/mcp/dispatch.js +104 -0
- package/dist/mcp/server.js +144 -0
- package/dist/mcp-server.js +6 -84
- package/dist/{agent-config.js → shell/agent-config.js} +118 -71
- package/dist/shell/app-run-cli.js +88 -0
- package/dist/shell/audit-cli.js +259 -0
- package/dist/shell/audit-provenance.js +83 -0
- package/dist/shell/candidate-scoring-io.js +459 -0
- package/dist/shell/collaboration-io.js +264 -0
- package/dist/shell/commit-summary.js +104 -0
- package/dist/shell/commit.js +290 -0
- package/dist/shell/coordinator-io.js +476 -0
- package/dist/shell/demo-cli.js +19 -0
- package/dist/shell/dispatch.js +162 -0
- package/dist/{doctor.js → shell/doctor.js} +123 -56
- package/dist/shell/drive.js +873 -0
- package/dist/shell/error-feedback-io.js +305 -0
- package/dist/shell/eval-io.js +473 -0
- package/dist/{multi-agent-eval/format.js → shell/eval-text.js} +78 -49
- package/dist/{evidence-reasoning.js → shell/evidence-reasoning.js} +124 -255
- package/dist/shell/exec-backend-cli.js +88 -0
- package/dist/shell/execution-backend/agent.js +475 -0
- package/dist/shell/execution-backend/ci.js +15 -0
- package/dist/shell/execution-backend/container.js +69 -0
- package/dist/shell/execution-backend/envelopes.js +55 -0
- package/dist/shell/execution-backend/local.js +113 -0
- package/dist/shell/execution-backend/probes.js +175 -0
- package/dist/shell/execution-backend/registry.js +402 -0
- package/dist/shell/execution-backend/remote.js +128 -0
- package/dist/shell/execution-backend/types.js +11 -0
- package/dist/shell/feedback-cli.js +81 -0
- package/dist/shell/feedback-operations.js +48 -0
- package/dist/shell/fs-atomic.js +276 -0
- package/dist/shell/harness.js +98 -0
- package/dist/shell/ledger-cli.js +212 -0
- package/dist/shell/ledger-io.js +169 -0
- package/dist/shell/man-cli.js +89 -0
- package/dist/shell/metrics-cli.js +98 -0
- package/dist/shell/multi-agent-cli.js +1002 -0
- package/dist/shell/multi-agent-host.js +563 -0
- package/dist/shell/multi-agent-io.js +387 -0
- package/dist/{multi-agent-operator-ux.js → shell/multi-agent-operator-ux.js} +234 -191
- package/dist/shell/node-store.js +124 -0
- package/dist/{observability/format.js → shell/observability-format.js} +7 -1
- package/dist/{observability/intake.js → shell/observability-intake.js} +79 -56
- package/dist/{observability.js → shell/observability.js} +159 -332
- package/dist/{onramp.js → shell/onramp.js} +11 -0
- package/dist/{operator-ux/format.js → shell/operator-ux-text.js} +250 -239
- package/dist/shell/operator-ux.js +431 -0
- package/dist/shell/orchestrator.js +231 -0
- package/dist/shell/pipeline-cli.js +667 -0
- package/dist/shell/pipeline.js +217 -0
- package/dist/shell/reclamation-io.js +1366 -0
- package/dist/shell/registry-cli.js +329 -0
- package/dist/{remote-source.js → shell/remote-source.js} +12 -5
- package/dist/shell/report-cli.js +101 -0
- package/dist/shell/report-view-cli.js +117 -0
- package/dist/{orchestrator → shell}/report.js +289 -282
- package/dist/shell/reporter.js +62 -0
- package/dist/shell/run-export-cli.js +106 -0
- package/dist/shell/run-export.js +680 -0
- package/dist/shell/run-registry-io.js +1014 -0
- package/dist/shell/run-store.js +164 -0
- package/dist/{sandbox-profile.js → shell/sandbox-profile.js} +134 -95
- package/dist/{scheduler.js → shell/scheduler-io.js} +248 -48
- package/dist/shell/scheduling-io.js +311 -0
- package/dist/shell/state-cli.js +181 -0
- package/dist/shell/state-explosion-cli.js +197 -0
- package/dist/shell/telemetry-cli.js +85 -0
- package/dist/{telemetry-demo.js → shell/telemetry-demo.js} +149 -119
- package/dist/shell/telemetry-ledger-io.js +132 -0
- package/dist/{term.js → shell/term.js} +36 -46
- package/dist/shell/topology-io.js +361 -0
- package/dist/shell/trust-audit.js +471 -0
- package/dist/{multi-agent-trust.js → shell/trust-policy-io.js} +67 -205
- package/dist/shell/verifier.js +48 -0
- package/dist/shell/workbench-host.js +250 -0
- package/dist/shell/workbench-text.js +18 -0
- package/dist/shell/workbench.js +175 -0
- package/dist/shell/worker-cli.js +124 -0
- package/dist/shell/worker-isolation.js +852 -0
- package/dist/shell/workflow-app-loader.js +650 -0
- package/docs/agent-delegation-drive.7.md +4 -0
- package/docs/cli-mcp-parity.7.md +284 -211
- package/docs/contract-migration-tooling.7.md +4 -0
- package/docs/control-plane-scheduling.7.md +4 -0
- package/docs/cross-agent-ledger.7.md +217 -0
- package/docs/designs/handoff-ledger.md +145 -0
- package/docs/durable-state-and-locking.7.md +4 -0
- package/docs/evidence-adoption-reasoning-chain.7.md +4 -0
- package/docs/execution-backends.7.md +4 -0
- package/docs/handoff-setup.md +120 -0
- package/docs/multi-agent-cli-mcp-surface.7.md +4 -0
- package/docs/multi-agent-eval-replay-harness.7.md +4 -0
- package/docs/multi-agent-operator-ux.7.md +4 -0
- package/docs/node-snapshot-diff-replay.7.md +4 -0
- package/docs/observability-cost-accounting.7.md +4 -0
- package/docs/project-index.md +143 -71
- package/docs/real-execution-backends.7.md +4 -0
- package/docs/release-and-migration.7.md +4 -0
- package/docs/release-tooling.7.md +4 -0
- package/docs/run-registry-control-plane.7.md +4 -0
- package/docs/run-retention-reclamation.7.md +25 -0
- package/docs/state-explosion-management.7.md +4 -0
- package/docs/team-collaboration.7.md +4 -0
- package/docs/web-desktop-workbench.7.md +4 -0
- package/manifest/plugin.manifest.json +1 -1
- package/manifest/source-context-profiles.json +9 -13
- package/package.json +1 -1
- package/scripts/agents/codex-agent.js +34 -4
- package/scripts/agents/cw-attest-wrap.js +2 -2
- package/scripts/bump-version.js +4 -3
- package/scripts/canonical-apps.js +4 -4
- package/scripts/children/batch-delegate-child.js +30 -10
- package/scripts/dogfood-architecture-review.js +2 -3
- package/scripts/dogfood-release.js +3 -3
- package/scripts/gen-parity-doc.js +15 -2
- package/scripts/golden-path.js +4 -4
- package/scripts/onramp-check.js +1 -1
- package/scripts/parity-check.js +38 -21
- package/scripts/release-flow.js +9 -3
- package/scripts/sync-project-index.js +51 -27
- package/scripts/validate-run-state-schema.js +2 -2
- package/scripts/version-sync-check.js +30 -30
- package/dist/candidate-scoring.js +0 -729
- package/dist/capability-core.js +0 -1186
- package/dist/capability-registry.js +0 -879
- package/dist/cli/command-surface.js +0 -490
- package/dist/cli/format.js +0 -56
- package/dist/cli/handlers/audit.js +0 -82
- package/dist/cli/handlers/blackboard.js +0 -81
- package/dist/cli/handlers/candidate.js +0 -40
- package/dist/cli/handlers/clones.js +0 -34
- package/dist/cli/handlers/collaboration.js +0 -61
- package/dist/cli/handlers/eval.js +0 -40
- package/dist/cli/handlers/maintenance.js +0 -107
- package/dist/cli/handlers/multi-agent.js +0 -165
- package/dist/cli/handlers/node.js +0 -41
- package/dist/cli/handlers/operational.js +0 -155
- package/dist/cli/handlers/operator.js +0 -146
- package/dist/cli/handlers/registry.js +0 -68
- package/dist/cli/handlers/run.js +0 -153
- package/dist/cli/handlers/scheduling.js +0 -132
- package/dist/cli/handlers/workbench.js +0 -41
- package/dist/cli/handlers/worker.js +0 -45
- package/dist/cli/run-summary.js +0 -45
- package/dist/clones.js +0 -162
- package/dist/collaboration.js +0 -726
- package/dist/commit.js +0 -592
- package/dist/compare.js +0 -18
- package/dist/coordinator/classify.js +0 -45
- package/dist/coordinator/paths.js +0 -42
- package/dist/coordinator/util.js +0 -126
- package/dist/coordinator.js +0 -990
- package/dist/daemon.js +0 -44
- package/dist/dispatch.js +0 -250
- package/dist/drive.js +0 -827
- package/dist/error-feedback.js +0 -419
- package/dist/evidence-grounding.js +0 -184
- package/dist/execution-backend/agent.js +0 -294
- package/dist/execution-backend/probes.js +0 -112
- package/dist/execution-backend/util.js +0 -47
- package/dist/execution-backend.js +0 -961
- package/dist/gates.js +0 -48
- package/dist/harness.js +0 -61
- package/dist/loop-expansion.js +0 -60
- package/dist/mcp/tool-call.js +0 -434
- package/dist/mcp/tool-definitions.js +0 -1040
- package/dist/mcp-surface.js +0 -30
- package/dist/multi-agent/graph.js +0 -84
- package/dist/multi-agent/helpers.js +0 -141
- package/dist/multi-agent/ids.js +0 -20
- package/dist/multi-agent/paths.js +0 -22
- package/dist/multi-agent-eval/normalize.js +0 -51
- package/dist/multi-agent-eval.js +0 -678
- package/dist/multi-agent-host.js +0 -777
- package/dist/multi-agent.js +0 -984
- package/dist/node-projection.js +0 -59
- package/dist/node-snapshot.js +0 -260
- package/dist/operator-ux.js +0 -631
- package/dist/orchestrator/app-operations.js +0 -211
- package/dist/orchestrator/audit-operations.js +0 -182
- package/dist/orchestrator/candidate-operations.js +0 -117
- package/dist/orchestrator/cli-options.js +0 -294
- package/dist/orchestrator/collaboration-operations.js +0 -86
- package/dist/orchestrator/feedback-operations.js +0 -81
- package/dist/orchestrator/host-operations.js +0 -78
- package/dist/orchestrator/lifecycle-operations.js +0 -626
- package/dist/orchestrator/migration-operations.js +0 -44
- package/dist/orchestrator/multi-agent-operations.js +0 -362
- package/dist/orchestrator/topology-operations.js +0 -84
- package/dist/orchestrator.js +0 -917
- package/dist/pipeline-runner.js +0 -285
- package/dist/reclamation/hash.js +0 -72
- package/dist/reclamation.js +0 -812
- package/dist/reporter.js +0 -67
- package/dist/run-export.js +0 -784
- package/dist/run-registry/derive.js +0 -175
- package/dist/run-registry/format.js +0 -124
- package/dist/run-registry/gc.js +0 -251
- package/dist/run-registry/policy.js +0 -16
- package/dist/run-registry/queue.js +0 -115
- package/dist/run-registry.js +0 -850
- package/dist/run-state-schema.js +0 -68
- package/dist/scheduling.js +0 -184
- package/dist/state-explosion.js +0 -1014
- package/dist/state.js +0 -367
- package/dist/telemetry-ledger.js +0 -196
- package/dist/topology.js +0 -565
- package/dist/triggers.js +0 -184
- package/dist/trust-audit.js +0 -644
- package/dist/types/blackboard.js +0 -2
- package/dist/types/candidate.js +0 -2
- package/dist/types/collaboration.js +0 -2
- package/dist/types/core.js +0 -2
- package/dist/types/drive.js +0 -10
- package/dist/types/error-feedback.js +0 -2
- package/dist/types/evidence-reasoning.js +0 -2
- package/dist/types/execution-backend.js +0 -2
- package/dist/types/multi-agent.js +0 -2
- package/dist/types/observability.js +0 -2
- package/dist/types/pipeline.js +0 -2
- package/dist/types/reclamation.js +0 -8
- package/dist/types/report-bundle.js +0 -6
- package/dist/types/result.js +0 -2
- package/dist/types/run-registry.js +0 -2
- package/dist/types/run.js +0 -2
- package/dist/types/sandbox.js +0 -2
- package/dist/types/schedule.js +0 -2
- package/dist/types/state-node.js +0 -2
- package/dist/types/topology.js +0 -2
- package/dist/types/trust.js +0 -2
- package/dist/types/workbench.js +0 -2
- package/dist/types/worker.js +0 -2
- package/dist/types/workflow-app.js +0 -2
- package/dist/types.js +0 -44
- package/dist/util/fingerprint.js +0 -19
- package/dist/util/fingerprint.test.js +0 -27
- package/dist/verifier.js +0 -78
- package/dist/version.js +0 -8
- package/dist/workbench-host.js +0 -182
- package/dist/workbench.js +0 -192
- package/dist/worker-accept/acceptance.js +0 -114
- package/dist/worker-accept/blackboard-fanout.js +0 -80
- package/dist/worker-accept/blackboard-linkage.js +0 -19
- package/dist/worker-accept/context.js +0 -2
- package/dist/worker-accept/telemetry-ledger.js +0 -126
- package/dist/worker-accept/validation.js +0 -77
- package/dist/worker-accept/verifier-completion.js +0 -73
- package/dist/worker-isolation/helpers.js +0 -51
- package/dist/worker-isolation/paths.js +0 -46
- package/dist/worker-isolation.js +0 -656
- package/dist/workflow-api.js +0 -131
- /package/dist/{types → core/types}/boundary.js +0 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// shell/execution-backend/registry.ts — the 7-driver registry: DRIVER_SPECS,
|
|
3
|
+
// registerBackend, resolveBackendSelection, attestSandbox, probeBackend,
|
|
4
|
+
// runBackend, and the CLI-facing inspection payloads.
|
|
5
|
+
//
|
|
6
|
+
// MILESTONE 5 (v2/PLAN.md build order, step 5). Byte-exact port of
|
|
7
|
+
// plugins/cool-workflow/src/execution-backend.ts (the parts not carved into
|
|
8
|
+
// local.ts/container.ts/remote.ts/ci.ts/agent.ts/probes.ts).
|
|
9
|
+
//
|
|
10
|
+
// Evidence: SPEC/execution-backend.md "The driver registry".
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.hasExecutable = exports.BackendError = exports.SANDBOX_DIMENSIONS = exports.DEFAULT_BACKEND_ID = exports.EXECUTION_BACKEND_SCHEMA_VERSION = void 0;
|
|
13
|
+
exports.registerBackend = registerBackend;
|
|
14
|
+
exports.getBackendDriver = getBackendDriver;
|
|
15
|
+
exports.listBackendDescriptors = listBackendDescriptors;
|
|
16
|
+
exports.backendIds = backendIds;
|
|
17
|
+
exports.isBackendId = isBackendId;
|
|
18
|
+
exports.getBackendDescriptor = getBackendDescriptor;
|
|
19
|
+
exports.resolveBackendSelection = resolveBackendSelection;
|
|
20
|
+
exports.requiredSandboxDimensions = requiredSandboxDimensions;
|
|
21
|
+
exports.attestSandbox = attestSandbox;
|
|
22
|
+
exports.probeBackend = probeBackend;
|
|
23
|
+
exports.runBackend = runBackend;
|
|
24
|
+
exports.createExecutionBackend = createExecutionBackend;
|
|
25
|
+
exports.backendListPayload = backendListPayload;
|
|
26
|
+
exports.backendShowPayload = backendShowPayload;
|
|
27
|
+
exports.backendProbePayload = backendProbePayload;
|
|
28
|
+
const probes_1 = require("./probes");
|
|
29
|
+
Object.defineProperty(exports, "hasExecutable", { enumerable: true, get: function () { return probes_1.hasExecutable; } });
|
|
30
|
+
const local_1 = require("./local");
|
|
31
|
+
const envelopes_1 = require("./envelopes");
|
|
32
|
+
const container_1 = require("./container");
|
|
33
|
+
const remote_1 = require("./remote");
|
|
34
|
+
const ci_1 = require("./ci");
|
|
35
|
+
const agent_1 = require("./agent");
|
|
36
|
+
exports.EXECUTION_BACKEND_SCHEMA_VERSION = 1;
|
|
37
|
+
exports.DEFAULT_BACKEND_ID = "node";
|
|
38
|
+
exports.SANDBOX_DIMENSIONS = ["read", "write", "command", "network", "env"];
|
|
39
|
+
class BackendError extends Error {
|
|
40
|
+
code;
|
|
41
|
+
details;
|
|
42
|
+
constructor(code, message, details) {
|
|
43
|
+
super(message);
|
|
44
|
+
this.name = "BackendError";
|
|
45
|
+
this.code = code;
|
|
46
|
+
this.details = details;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.BackendError = BackendError;
|
|
50
|
+
const DRIVER_SPECS = [
|
|
51
|
+
{
|
|
52
|
+
id: "node",
|
|
53
|
+
title: "Node (default)",
|
|
54
|
+
description: "Default backend. Reproduces pre-v0.1.29 behavior exactly: the host runs the worker in-process under CW's worker-output acceptance. When executing a command it enforces the command + env policy via the Node child process and attests OS read/write/network isolation to the host.",
|
|
55
|
+
kind: "local",
|
|
56
|
+
locality: "local",
|
|
57
|
+
default: true,
|
|
58
|
+
readiness: "ready",
|
|
59
|
+
support: { read: "attest", write: "attest", command: "enforce", network: "attest", env: "enforce" },
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: "bun",
|
|
63
|
+
title: "Bun",
|
|
64
|
+
description: "Bun-friendly backend. Node-compatible by default: it executes via the Node-compatible runtime so evidence is byte-stable with the node backend, and attests Bun availability in provenance. Enforces command + env via the child process; attests read/write/network to the host.",
|
|
65
|
+
kind: "local",
|
|
66
|
+
locality: "local",
|
|
67
|
+
default: false,
|
|
68
|
+
delegate: "bun",
|
|
69
|
+
readiness: "ready",
|
|
70
|
+
support: { read: "attest", write: "attest", command: "enforce", network: "attest", env: "enforce" },
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: "shell",
|
|
74
|
+
title: "Shell",
|
|
75
|
+
description: "Runs a command/worker via the system shell (/bin/sh -c) under the sandbox contract. Enforces command + env via the child process; attests read/write/network to the host.",
|
|
76
|
+
kind: "local",
|
|
77
|
+
locality: "local",
|
|
78
|
+
default: false,
|
|
79
|
+
delegate: "/bin/sh",
|
|
80
|
+
readiness: "ready",
|
|
81
|
+
support: { read: "attest", write: "attest", command: "enforce", network: "attest", env: "enforce" },
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: "container",
|
|
85
|
+
title: "Container",
|
|
86
|
+
description: "Delegates execution to a container runtime (docker/podman) and records the image@digest handle + attestation + result. A container can enforce all five dimensions via mounts, dropped capabilities, a network namespace, and a filtered env. Fails closed when no image is supplied or no runtime is present.",
|
|
87
|
+
kind: "delegating",
|
|
88
|
+
locality: "local",
|
|
89
|
+
default: false,
|
|
90
|
+
delegate: "docker",
|
|
91
|
+
readiness: "unverified",
|
|
92
|
+
support: { read: "enforce", write: "enforce", command: "enforce", network: "enforce", env: "enforce" },
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "remote",
|
|
96
|
+
title: "Remote Runner",
|
|
97
|
+
description: "Delegates execution to a remote runner and records the endpoint + job handle + attestation + result. Enforces command + env at the remote; attests read/write/network. Fails closed when no endpoint is configured.",
|
|
98
|
+
kind: "delegating",
|
|
99
|
+
locality: "remote",
|
|
100
|
+
default: false,
|
|
101
|
+
delegate: "remote-runner",
|
|
102
|
+
readiness: "unverified",
|
|
103
|
+
support: { read: "attest", write: "attest", command: "enforce", network: "attest", env: "enforce" },
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: "ci",
|
|
107
|
+
title: "CI Runner",
|
|
108
|
+
description: "Delegates execution to a CI runner and records the job handle + attestation + result. Enforces command + env in the CI job; attests read/write/network. Fails closed when no CI job target is configured.",
|
|
109
|
+
kind: "delegating",
|
|
110
|
+
locality: "remote",
|
|
111
|
+
default: false,
|
|
112
|
+
delegate: "ci-runner",
|
|
113
|
+
readiness: "unverified",
|
|
114
|
+
support: { read: "attest", write: "attest", command: "enforce", network: "attest", env: "enforce" },
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
id: "agent",
|
|
118
|
+
title: "Agent (external process)",
|
|
119
|
+
description: "Delegates each worker to an EXTERNAL agent process (claude -p / codex exec / an HTTP agent endpoint) and records the agent CHILD's command + exit + stdout digest as the canonical evidence triple, plus a kind:process handle and the agent-reported model + prompt/result digests as provenance. The MODEL runs in the agent's process, NEVER in CW — CW imports no model SDK and holds no API key; it spawns an out-of-process child argv-style (shell:false) or POSTs to a configured endpoint. CW enforces only the exact argv it spawns; the agent host attests read/write/network/env. Fails closed when no command-template/endpoint is configured, on non-zero exit, or on a missing/invalid result.md.",
|
|
120
|
+
kind: "delegating",
|
|
121
|
+
locality: "local",
|
|
122
|
+
default: false,
|
|
123
|
+
delegate: "agent-process",
|
|
124
|
+
readiness: "unverified",
|
|
125
|
+
support: { read: "attest", write: "attest", command: "enforce", network: "attest", env: "attest" },
|
|
126
|
+
},
|
|
127
|
+
];
|
|
128
|
+
function specCapabilities(spec) {
|
|
129
|
+
return exports.SANDBOX_DIMENSIONS.map((dimension) => ({ dimension, support: spec.support[dimension] }));
|
|
130
|
+
}
|
|
131
|
+
function specDescriptor(spec) {
|
|
132
|
+
const capabilities = specCapabilities(spec);
|
|
133
|
+
return {
|
|
134
|
+
schemaVersion: 1,
|
|
135
|
+
id: spec.id,
|
|
136
|
+
title: spec.title,
|
|
137
|
+
description: spec.description,
|
|
138
|
+
kind: spec.kind,
|
|
139
|
+
locality: spec.locality,
|
|
140
|
+
default: spec.default,
|
|
141
|
+
capabilities,
|
|
142
|
+
enforces: capabilities.filter((cap) => cap.support === "enforce").map((cap) => cap.dimension),
|
|
143
|
+
attests: capabilities.filter((cap) => cap.support === "attest").map((cap) => cap.dimension),
|
|
144
|
+
delegate: spec.delegate,
|
|
145
|
+
readiness: spec.readiness,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
const BACKEND_REGISTRY = new Map();
|
|
149
|
+
/** Register (or override) a backend driver. The public extension seam. */
|
|
150
|
+
function registerBackend(driver) {
|
|
151
|
+
BACKEND_REGISTRY.set(driver.spec.id, driver);
|
|
152
|
+
}
|
|
153
|
+
function getBackendDriver(id) {
|
|
154
|
+
return BACKEND_REGISTRY.get(id);
|
|
155
|
+
}
|
|
156
|
+
function registeredDrivers() {
|
|
157
|
+
return [...BACKEND_REGISTRY.values()];
|
|
158
|
+
}
|
|
159
|
+
function listBackendDescriptors() {
|
|
160
|
+
return registeredDrivers()
|
|
161
|
+
.map((driver) => specDescriptor(driver.spec))
|
|
162
|
+
.sort((left, right) => left.id.localeCompare(right.id));
|
|
163
|
+
}
|
|
164
|
+
function backendIds() {
|
|
165
|
+
return registeredDrivers()
|
|
166
|
+
.map((driver) => driver.spec.id)
|
|
167
|
+
.sort();
|
|
168
|
+
}
|
|
169
|
+
function isBackendId(id) {
|
|
170
|
+
return Boolean(id) && BACKEND_REGISTRY.has(id);
|
|
171
|
+
}
|
|
172
|
+
function getBackendDescriptor(id) {
|
|
173
|
+
const driver = BACKEND_REGISTRY.get(id);
|
|
174
|
+
if (!driver) {
|
|
175
|
+
throw new BackendError("backend-not-found", `Execution backend not found: ${id}`, { backendId: id, available: backendIds() });
|
|
176
|
+
}
|
|
177
|
+
return specDescriptor(driver.spec);
|
|
178
|
+
}
|
|
179
|
+
function ctxDelegate(impl) {
|
|
180
|
+
return (ctx) => impl(ctx.descriptor, ctx.policy, ctx.request, ctx.label, ctx.handle, ctx.attestation);
|
|
181
|
+
}
|
|
182
|
+
const BUILTIN_DRIVER_BEHAVIORS = {
|
|
183
|
+
node: { spawnStyle: "direct", runtimeNote: () => (0, local_1.runtimeNoteFor)("node"), probe: probes_1.probeNodeBackend },
|
|
184
|
+
bun: { spawnStyle: "direct", runtimeNote: () => (0, local_1.runtimeNoteFor)("bun"), probe: probes_1.probeBunBackend },
|
|
185
|
+
shell: { spawnStyle: "shell", runtimeNote: () => (0, local_1.runtimeNoteFor)("shell"), probe: probes_1.probeShellBackend },
|
|
186
|
+
container: { delegateRun: ctxDelegate(container_1.runContainer), buildHandle: container_1.containerHandle, probe: probes_1.probeContainerBackend },
|
|
187
|
+
remote: { delegateRun: ctxDelegate(remote_1.runHttpDelegation), buildHandle: remote_1.remoteHandle, probe: probes_1.probeRemoteBackend },
|
|
188
|
+
ci: { delegateRun: ctxDelegate(ci_1.runCiDelegation), buildHandle: ci_1.ciHandle, probe: probes_1.probeCiBackend },
|
|
189
|
+
agent: {
|
|
190
|
+
delegateRun: (ctx) => (0, agent_1.runAgentProcess)(ctx.descriptor, ctx.policy, ctx.request, ctx.label, ctx.attestation),
|
|
191
|
+
buildHandle: agent_1.agentHandle,
|
|
192
|
+
commandlessDelegate: true,
|
|
193
|
+
probe: probes_1.probeAgentBackend,
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
for (const spec of DRIVER_SPECS) {
|
|
197
|
+
registerBackend({ spec, ...(BUILTIN_DRIVER_BEHAVIORS[spec.id] || {}) });
|
|
198
|
+
}
|
|
199
|
+
// ---------------------------------------------------------------------------
|
|
200
|
+
// Selection & resolution. `--backend <id>` (flag) > CW_BACKEND (env) > default.
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
function resolveBackendSelection(requested, env = process.env) {
|
|
203
|
+
const normalizedRequested = requested && requested.trim() ? requested.trim() : undefined;
|
|
204
|
+
if (normalizedRequested) {
|
|
205
|
+
if (!isBackendId(normalizedRequested)) {
|
|
206
|
+
throw new BackendError("backend-not-found", `Unknown execution backend: ${normalizedRequested}`, {
|
|
207
|
+
backendId: normalizedRequested,
|
|
208
|
+
available: backendIds(),
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
return { backendId: normalizedRequested, source: "flag", requested: normalizedRequested };
|
|
212
|
+
}
|
|
213
|
+
const envBackend = env.CW_BACKEND && env.CW_BACKEND.trim() ? env.CW_BACKEND.trim() : undefined;
|
|
214
|
+
if (envBackend) {
|
|
215
|
+
if (!isBackendId(envBackend)) {
|
|
216
|
+
throw new BackendError("backend-not-found", `Unknown execution backend in CW_BACKEND: ${envBackend}`, {
|
|
217
|
+
backendId: envBackend,
|
|
218
|
+
available: backendIds(),
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
return { backendId: envBackend, source: "env", requested: envBackend };
|
|
222
|
+
}
|
|
223
|
+
return { backendId: exports.DEFAULT_BACKEND_ID, source: "default" };
|
|
224
|
+
}
|
|
225
|
+
// ---------------------------------------------------------------------------
|
|
226
|
+
// Sandbox dimension mapping + attestation.
|
|
227
|
+
// ---------------------------------------------------------------------------
|
|
228
|
+
function requiredSandboxDimensions(policy) {
|
|
229
|
+
const required = [];
|
|
230
|
+
required.push("read");
|
|
231
|
+
required.push("write");
|
|
232
|
+
if (policy.execute.mode !== "any")
|
|
233
|
+
required.push("command");
|
|
234
|
+
if (policy.network.mode !== "any")
|
|
235
|
+
required.push("network");
|
|
236
|
+
if (policy.env.inherit === false)
|
|
237
|
+
required.push("env");
|
|
238
|
+
return required;
|
|
239
|
+
}
|
|
240
|
+
function attestSandbox(descriptor, policy, options = { mode: "execute" }) {
|
|
241
|
+
const required = requiredSandboxDimensions(policy);
|
|
242
|
+
const supportByDimension = new Map(descriptor.capabilities.map((cap) => [cap.dimension, cap.support]));
|
|
243
|
+
const enforced = [];
|
|
244
|
+
const attested = [];
|
|
245
|
+
const unenforceable = [];
|
|
246
|
+
for (const dimension of required) {
|
|
247
|
+
const declared = supportByDimension.get(dimension) || "unsupported";
|
|
248
|
+
let effective = declared;
|
|
249
|
+
if (options.mode === "delegate-host" && declared !== "unsupported") {
|
|
250
|
+
effective = dimension === "write" ? "enforce" : "attest";
|
|
251
|
+
}
|
|
252
|
+
if (effective === "enforce")
|
|
253
|
+
enforced.push(dimension);
|
|
254
|
+
else if (effective === "attest")
|
|
255
|
+
attested.push(dimension);
|
|
256
|
+
else
|
|
257
|
+
unenforceable.push(dimension);
|
|
258
|
+
}
|
|
259
|
+
const refusedForReadiness = options.ready === false;
|
|
260
|
+
const status = unenforceable.length || refusedForReadiness ? "refused" : enforced.length ? "enforced" : "attested";
|
|
261
|
+
return {
|
|
262
|
+
schemaVersion: 1,
|
|
263
|
+
backendId: descriptor.id,
|
|
264
|
+
locality: descriptor.locality,
|
|
265
|
+
kind: descriptor.kind,
|
|
266
|
+
sandboxProfileId: policy.id,
|
|
267
|
+
required,
|
|
268
|
+
enforced,
|
|
269
|
+
attested,
|
|
270
|
+
unenforceable,
|
|
271
|
+
status,
|
|
272
|
+
enforcedByCW: policy.enforcement.enforcedByCW,
|
|
273
|
+
hostRequired: policy.enforcement.hostRequired,
|
|
274
|
+
recordedAt: options.recordedAt || new Date().toISOString(),
|
|
275
|
+
handle: options.handle,
|
|
276
|
+
notes: options.notes,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
// ---------------------------------------------------------------------------
|
|
280
|
+
// Readiness probe.
|
|
281
|
+
// ---------------------------------------------------------------------------
|
|
282
|
+
function probeBackend(id, context = {}) {
|
|
283
|
+
const descriptor = getBackendDescriptor(id);
|
|
284
|
+
const driver = BACKEND_REGISTRY.get(id);
|
|
285
|
+
// Config-based probes (agent/remote/ci) read readiness from the environment;
|
|
286
|
+
// the local probes (node/bun/shell/container) ignore their arg. Pass
|
|
287
|
+
// process.env, NOT the {cwd} context — otherwise the context object shadows
|
|
288
|
+
// process.env and a configured agent always reads back "unverified".
|
|
289
|
+
void context;
|
|
290
|
+
const body = driver?.probe ? driver.probe(process.env) : { checks: [], readiness: descriptor.readiness };
|
|
291
|
+
return {
|
|
292
|
+
schemaVersion: 1,
|
|
293
|
+
backendId: descriptor.id,
|
|
294
|
+
locality: descriptor.locality,
|
|
295
|
+
kind: descriptor.kind,
|
|
296
|
+
readiness: body.readiness,
|
|
297
|
+
ready: body.readiness === "ready",
|
|
298
|
+
enforces: descriptor.enforces,
|
|
299
|
+
attests: descriptor.attests,
|
|
300
|
+
checks: body.checks,
|
|
301
|
+
reason: body.reason,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
// ---------------------------------------------------------------------------
|
|
305
|
+
// The run entry.
|
|
306
|
+
// ---------------------------------------------------------------------------
|
|
307
|
+
function commandDenied(policy, command) {
|
|
308
|
+
const normalized = command.trim();
|
|
309
|
+
if (!normalized)
|
|
310
|
+
return "empty command";
|
|
311
|
+
if (policy.execute.mode === "none") {
|
|
312
|
+
return `command execution is denied by sandbox profile ${policy.id}`;
|
|
313
|
+
}
|
|
314
|
+
if (policy.execute.mode === "allowlist" && !(policy.execute.allow || []).includes(normalized)) {
|
|
315
|
+
return `command is outside sandbox profile ${policy.id} allowlist`;
|
|
316
|
+
}
|
|
317
|
+
return undefined;
|
|
318
|
+
}
|
|
319
|
+
function delegationHandle(descriptor, request) {
|
|
320
|
+
return getBackendDriver(descriptor.id)?.buildHandle?.(request);
|
|
321
|
+
}
|
|
322
|
+
function delegate(descriptor, policy, request, label, probe) {
|
|
323
|
+
const handle = delegationHandle(descriptor, request);
|
|
324
|
+
if (!handle) {
|
|
325
|
+
return (0, envelopes_1.refusedEnvelope)(descriptor, policy, label, "delegation-target-missing", probe.reason || `Backend ${descriptor.id} has no delegation target; refusing rather than running unsandboxed`, attestSandbox(descriptor, policy, { mode: "execute", ready: probe.ready }));
|
|
326
|
+
}
|
|
327
|
+
if (!getBackendDriver(descriptor.id)?.commandlessDelegate && !request.command) {
|
|
328
|
+
return (0, envelopes_1.refusedEnvelope)(descriptor, policy, label, "no-command", `Backend ${descriptor.id} requires a command to delegate`, attestSandbox(descriptor, policy, { mode: "execute", ready: probe.ready }));
|
|
329
|
+
}
|
|
330
|
+
const attestation = attestSandbox(descriptor, policy, {
|
|
331
|
+
mode: "execute",
|
|
332
|
+
ready: true,
|
|
333
|
+
handle,
|
|
334
|
+
notes: [`delegated: ${descriptor.id} -> ${handle.ref}`],
|
|
335
|
+
});
|
|
336
|
+
const driver = getBackendDriver(descriptor.id);
|
|
337
|
+
if (!driver?.delegateRun) {
|
|
338
|
+
return (0, envelopes_1.refusedEnvelope)(descriptor, policy, label, "backend-not-runnable", `Backend ${descriptor.id} has no delegate runner`, attestation);
|
|
339
|
+
}
|
|
340
|
+
return driver.delegateRun({ descriptor, policy, request, label, handle, attestation });
|
|
341
|
+
}
|
|
342
|
+
function runBackend(request) {
|
|
343
|
+
const descriptor = getBackendDescriptor(request.backendId);
|
|
344
|
+
const policy = request.sandboxPolicy;
|
|
345
|
+
const label = request.label || request.command || `${descriptor.id}-execution`;
|
|
346
|
+
const probe = probeBackend(descriptor.id, { cwd: request.cwd });
|
|
347
|
+
if (request.command) {
|
|
348
|
+
const denied = commandDenied(policy, `${request.command} ${(request.args || []).join(" ")}`.trim());
|
|
349
|
+
if (denied) {
|
|
350
|
+
return (0, envelopes_1.refusedEnvelope)(descriptor, policy, label, "sandbox-command-denied", denied, attestSandbox(descriptor, policy, { mode: "execute", ready: probe.ready }));
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
const attestation = attestSandbox(descriptor, policy, { mode: "execute", ready: probe.ready });
|
|
354
|
+
if (attestation.unenforceable.length) {
|
|
355
|
+
return (0, envelopes_1.refusedEnvelope)(descriptor, policy, label, "sandbox-unenforceable", `Backend ${descriptor.id} cannot enforce or attest required sandbox dimension(s): ${attestation.unenforceable.join(", ")}`, attestation);
|
|
356
|
+
}
|
|
357
|
+
if (descriptor.kind === "delegating") {
|
|
358
|
+
return delegate(descriptor, policy, request, label, probe);
|
|
359
|
+
}
|
|
360
|
+
if (!probe.ready) {
|
|
361
|
+
return (0, envelopes_1.refusedEnvelope)(descriptor, policy, label, "backend-not-ready", probe.reason || `Backend ${descriptor.id} is not ready`, attestation);
|
|
362
|
+
}
|
|
363
|
+
if (!request.command) {
|
|
364
|
+
return (0, envelopes_1.refusedEnvelope)(descriptor, policy, label, "no-command", `Backend ${descriptor.id} requires a command to execute`, attestation);
|
|
365
|
+
}
|
|
366
|
+
return (0, local_1.executeLocal)(descriptor, request, label, attestation, getBackendDriver(descriptor.id)?.spawnStyle);
|
|
367
|
+
}
|
|
368
|
+
function createExecutionBackend(id) {
|
|
369
|
+
const descriptor = getBackendDescriptor(id);
|
|
370
|
+
return {
|
|
371
|
+
descriptor,
|
|
372
|
+
probe: (context) => probeBackend(id, context),
|
|
373
|
+
run: (request) => runBackend({ ...request, backendId: id }),
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
// ---- inspection payloads ---------------------------------------------------
|
|
377
|
+
function backendListPayload() {
|
|
378
|
+
return { schemaVersion: 1, default: exports.DEFAULT_BACKEND_ID, backends: listBackendDescriptors() };
|
|
379
|
+
}
|
|
380
|
+
function backendShowPayload(id) {
|
|
381
|
+
return getBackendDescriptor(id);
|
|
382
|
+
}
|
|
383
|
+
const _probeCache = new Map();
|
|
384
|
+
function probeCacheTtlMs() {
|
|
385
|
+
const raw = process.env.CW_PROBE_CACHE_TTL_MS;
|
|
386
|
+
const n = raw ? parseInt(raw, 10) : 60_000;
|
|
387
|
+
return Number.isFinite(n) && n >= 0 ? n : 60_000;
|
|
388
|
+
}
|
|
389
|
+
function cachedProbeBackend(id, context) {
|
|
390
|
+
const key = `${id}:${context.cwd || ""}`;
|
|
391
|
+
const cached = _probeCache.get(key);
|
|
392
|
+
if (cached && Date.now() - cached.at < probeCacheTtlMs())
|
|
393
|
+
return cached.result;
|
|
394
|
+
const result = probeBackend(id, context);
|
|
395
|
+
_probeCache.set(key, { result, at: Date.now() });
|
|
396
|
+
return result;
|
|
397
|
+
}
|
|
398
|
+
function backendProbePayload(id, context = {}) {
|
|
399
|
+
if (id && id.trim())
|
|
400
|
+
return cachedProbeBackend(id.trim(), context);
|
|
401
|
+
return { schemaVersion: 1, default: exports.DEFAULT_BACKEND_ID, probes: backendIds().map((backendId) => cachedProbeBackend(backendId, context)) };
|
|
402
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// shell/execution-backend/remote.ts — remote/ci delegating drivers (shared
|
|
3
|
+
// HTTP-delegation body) + handle builders.
|
|
4
|
+
//
|
|
5
|
+
// MILESTONE 5 (v2/PLAN.md build order, step 5). Byte-exact port of
|
|
6
|
+
// plugins/cool-workflow/src/execution-backend.ts's `runHttpDelegation`
|
|
7
|
+
// (:821-876), `remoteHandle` (:1077-1084), `ciHandle` (:1086-1093), and
|
|
8
|
+
// `delegateChildScript` (:801-811).
|
|
9
|
+
//
|
|
10
|
+
// Evidence: SPEC/execution-backend.md "remote / ci drivers
|
|
11
|
+
// (runHttpDelegation)".
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.delegateChildScript = delegateChildScript;
|
|
47
|
+
exports.remoteHandle = remoteHandle;
|
|
48
|
+
exports.ciHandle = ciHandle;
|
|
49
|
+
exports.runHttpDelegation = runHttpDelegation;
|
|
50
|
+
const fs = __importStar(require("node:fs"));
|
|
51
|
+
const path = __importStar(require("node:path"));
|
|
52
|
+
const node_child_process_1 = require("node:child_process");
|
|
53
|
+
const envelopes_1 = require("./envelopes");
|
|
54
|
+
const local_1 = require("./local");
|
|
55
|
+
function messageOf(error) {
|
|
56
|
+
return error instanceof Error ? error.message : String(error);
|
|
57
|
+
}
|
|
58
|
+
/** Resolves scripts/children/http-delegate-child.js next to the compiled
|
|
59
|
+
* module. Throws the exact broken-installation message when missing. */
|
|
60
|
+
function delegateChildScript() {
|
|
61
|
+
// __dirname is dist/shell/execution-backend — three levels up reaches
|
|
62
|
+
// the package root (scripts/ is a sibling of dist/, not two levels up).
|
|
63
|
+
const resolved = path.resolve(__dirname, "..", "..", "..", "scripts", "children", "http-delegate-child.js");
|
|
64
|
+
if (!fs.existsSync(resolved)) {
|
|
65
|
+
throw new Error(`Delegate child script not found at ${resolved}. ` +
|
|
66
|
+
`This indicates a broken installation — reinstall cool-workflow or ensure ` +
|
|
67
|
+
`"scripts/children/http-delegate-child.js" is shipped in the package.`);
|
|
68
|
+
}
|
|
69
|
+
return resolved;
|
|
70
|
+
}
|
|
71
|
+
function remoteHandle(request, env = process.env) {
|
|
72
|
+
const delegation = request.delegation || {};
|
|
73
|
+
const endpoint = delegation.endpoint || (env.CW_REMOTE_ENDPOINT || "").trim() || undefined;
|
|
74
|
+
if (!endpoint)
|
|
75
|
+
return undefined;
|
|
76
|
+
const jobId = delegation.jobId || (env.CW_REMOTE_JOB || "").trim() || undefined;
|
|
77
|
+
const ref = jobId ? `${endpoint}#${jobId}` : endpoint;
|
|
78
|
+
return { kind: "remote", ref, endpoint, jobId };
|
|
79
|
+
}
|
|
80
|
+
function ciHandle(request, env = process.env) {
|
|
81
|
+
const delegation = request.delegation || {};
|
|
82
|
+
const endpoint = delegation.endpoint || (env.CW_CI_ENDPOINT || "").trim() || undefined;
|
|
83
|
+
const jobId = delegation.jobId || (env.CW_CI_JOB || "").trim() || undefined;
|
|
84
|
+
if (!endpoint && !jobId)
|
|
85
|
+
return undefined;
|
|
86
|
+
const ref = endpoint && jobId ? `${endpoint}#${jobId}` : jobId || endpoint || "";
|
|
87
|
+
return { kind: "ci", ref, endpoint, jobId };
|
|
88
|
+
}
|
|
89
|
+
/** remote / ci — real HTTP delegation. POSTs the job to the configured
|
|
90
|
+
* endpoint (and polls a returned jobId) via a Node child, then records the
|
|
91
|
+
* runner's exit + stdout digest as canonical evidence. Fails closed when
|
|
92
|
+
* the endpoint is missing, unreachable, errors, or returns no exitCode. */
|
|
93
|
+
function runHttpDelegation(descriptor, policy, request, label, handle, attestation) {
|
|
94
|
+
const endpoint = handle.endpoint;
|
|
95
|
+
if (!endpoint) {
|
|
96
|
+
return (0, envelopes_1.refusedEnvelope)(descriptor, policy, label, "delegation-target-missing", `Backend ${descriptor.id} has no endpoint to POST to`, attestation);
|
|
97
|
+
}
|
|
98
|
+
const command = String(request.command);
|
|
99
|
+
const args = (request.args || []).map(String);
|
|
100
|
+
const job = JSON.stringify({
|
|
101
|
+
command,
|
|
102
|
+
args,
|
|
103
|
+
env: (0, local_1.buildChildEnv)(policy),
|
|
104
|
+
sandboxProfileId: policy.id,
|
|
105
|
+
jobId: handle.jobId,
|
|
106
|
+
});
|
|
107
|
+
const child = (0, node_child_process_1.spawnSync)(process.execPath, [delegateChildScript()], {
|
|
108
|
+
input: job,
|
|
109
|
+
env: { ...process.env, CW_DELEGATE_ENDPOINT: endpoint },
|
|
110
|
+
encoding: "utf8",
|
|
111
|
+
timeout: request.timeoutMs || 120000,
|
|
112
|
+
maxBuffer: 32 * 1024 * 1024,
|
|
113
|
+
});
|
|
114
|
+
if (child.error) {
|
|
115
|
+
return (0, envelopes_1.refusedEnvelope)(descriptor, policy, label, "delegation-failed", `${descriptor.id} delegation failed: ${messageOf(child.error)}`, attestation);
|
|
116
|
+
}
|
|
117
|
+
let parsed;
|
|
118
|
+
try {
|
|
119
|
+
parsed = JSON.parse(String(child.stdout || "").trim() || "{}");
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return (0, envelopes_1.refusedEnvelope)(descriptor, policy, label, "delegation-failed", `${descriptor.id} runner returned an unparseable response`, attestation);
|
|
123
|
+
}
|
|
124
|
+
if (parsed.error || typeof parsed.exitCode !== "number") {
|
|
125
|
+
return (0, envelopes_1.refusedEnvelope)(descriptor, policy, label, "delegation-failed", `${descriptor.id} runner error: ${parsed.error || "no exitCode reported"}`, attestation);
|
|
126
|
+
}
|
|
127
|
+
return (0, envelopes_1.delegatedEnvelope)(descriptor, label, handle, attestation, command, args, parsed.exitCode, String(parsed.stdout || ""));
|
|
128
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// shell/execution-backend/types.ts — plain data shapes for the driver layer.
|
|
3
|
+
//
|
|
4
|
+
// MILESTONE 5 (v2/PLAN.md build order, step 5). Byte-exact port of the shapes
|
|
5
|
+
// in the old build's src/types/execution-backend.ts and the sandbox slice of
|
|
6
|
+
// src/types/sandbox.ts that this subsystem needs. Types only — no logic — so
|
|
7
|
+
// this file is safe to import from both shell/ (impure) and any future core/
|
|
8
|
+
// caller without violating the core/shell purity split.
|
|
9
|
+
//
|
|
10
|
+
// Evidence: SPEC/execution-backend.md.
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// shell/feedback-cli.ts — `cw feedback list|show|summary|collect|task|resolve`
|
|
3
|
+
// (and the mirrored cw_feedback_* MCP tools) handler bodies. Loads run state
|
|
4
|
+
// and routes to the feedback-operations lifecycle.
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.feedbackListCli = feedbackListCli;
|
|
40
|
+
exports.feedbackShowCli = feedbackShowCli;
|
|
41
|
+
exports.feedbackSummaryCli = feedbackSummaryCli;
|
|
42
|
+
exports.feedbackCollectCli = feedbackCollectCli;
|
|
43
|
+
exports.feedbackTaskCli = feedbackTaskCli;
|
|
44
|
+
exports.feedbackResolveCli = feedbackResolveCli;
|
|
45
|
+
const path = __importStar(require("node:path"));
|
|
46
|
+
const run_store_1 = require("./run-store");
|
|
47
|
+
const error_feedback_1 = require("../core/pipeline/error-feedback");
|
|
48
|
+
const feedback_operations_1 = require("./feedback-operations");
|
|
49
|
+
function cwdFor(args) {
|
|
50
|
+
return typeof args.cwd === "string" && args.cwd.trim() ? path.resolve(args.cwd) : process.cwd();
|
|
51
|
+
}
|
|
52
|
+
function req(value, label) {
|
|
53
|
+
const s = value === undefined || value === null ? "" : String(value);
|
|
54
|
+
if (!s)
|
|
55
|
+
throw new Error(`Missing ${label}`);
|
|
56
|
+
return s;
|
|
57
|
+
}
|
|
58
|
+
function feedbackListCli(args) {
|
|
59
|
+
const run = (0, run_store_1.loadRunFromCwd)(req(args.runId, "run id"), cwdFor(args));
|
|
60
|
+
return (0, feedback_operations_1.listFeedback)(run, args);
|
|
61
|
+
}
|
|
62
|
+
function feedbackShowCli(args) {
|
|
63
|
+
const run = (0, run_store_1.loadRunFromCwd)(req(args.runId, "run id"), cwdFor(args));
|
|
64
|
+
return (0, feedback_operations_1.showFeedback)(run, req(args.feedbackId, "feedback id"));
|
|
65
|
+
}
|
|
66
|
+
function feedbackSummaryCli(args) {
|
|
67
|
+
const run = (0, run_store_1.loadRunFromCwd)(req(args.runId, "run id"), cwdFor(args));
|
|
68
|
+
return (0, error_feedback_1.summarizeFeedback)((0, feedback_operations_1.listFeedback)(run));
|
|
69
|
+
}
|
|
70
|
+
function feedbackCollectCli(args) {
|
|
71
|
+
const run = (0, run_store_1.loadRunFromCwd)(req(args.runId, "run id"), cwdFor(args));
|
|
72
|
+
return (0, feedback_operations_1.collectFeedback)(run);
|
|
73
|
+
}
|
|
74
|
+
function feedbackTaskCli(args) {
|
|
75
|
+
const run = (0, run_store_1.loadRunFromCwd)(req(args.runId, "run id"), cwdFor(args));
|
|
76
|
+
return (0, feedback_operations_1.createFeedbackTask)(run, req(args.feedbackId, "feedback id"), args);
|
|
77
|
+
}
|
|
78
|
+
function feedbackResolveCli(args) {
|
|
79
|
+
const run = (0, run_store_1.loadRunFromCwd)(req(args.runId, "run id"), cwdFor(args));
|
|
80
|
+
return (0, feedback_operations_1.resolveFeedback)(run, req(args.feedbackId, "feedback id"), args);
|
|
81
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// shell/feedback-operations.ts — operator-facing feedback lifecycle:
|
|
3
|
+
// collect / list / show / create-task / resolve. Byte-behavior port of the old
|
|
4
|
+
// src/orchestrator/feedback-operations.ts (thin wrappers over the
|
|
5
|
+
// error-feedback-io primitives that also refresh the report + persist).
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.collectFeedback = collectFeedback;
|
|
8
|
+
exports.listFeedback = listFeedback;
|
|
9
|
+
exports.showFeedback = showFeedback;
|
|
10
|
+
exports.createFeedbackTask = createFeedbackTask;
|
|
11
|
+
exports.resolveFeedback = resolveFeedback;
|
|
12
|
+
const report_1 = require("./report");
|
|
13
|
+
const error_feedback_io_1 = require("./error-feedback-io");
|
|
14
|
+
function collectFeedback(run) {
|
|
15
|
+
const collected = (0, error_feedback_io_1.collectRunErrors)(run);
|
|
16
|
+
(0, report_1.writeReport)(run);
|
|
17
|
+
return collected;
|
|
18
|
+
}
|
|
19
|
+
function listFeedback(run, options = {}) {
|
|
20
|
+
return (0, error_feedback_io_1.listFeedback)(run, {
|
|
21
|
+
status: options.status ? String(options.status) : undefined,
|
|
22
|
+
severity: options.severity ? String(options.severity) : undefined,
|
|
23
|
+
classification: options.classification ? String(options.classification) : undefined,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function showFeedback(run, feedbackId) {
|
|
27
|
+
const feedback = (0, error_feedback_io_1.getFeedback)(run, feedbackId);
|
|
28
|
+
if (!feedback)
|
|
29
|
+
throw new Error(`Unknown feedback id for run ${run.id}: ${feedbackId}`);
|
|
30
|
+
return feedback;
|
|
31
|
+
}
|
|
32
|
+
function createFeedbackTask(run, feedbackId, options = {}) {
|
|
33
|
+
const feedback = (0, error_feedback_io_1.createCorrectionTask)(run, feedbackId, {
|
|
34
|
+
verifierCommand: options.verify ? String(options.verify) : undefined,
|
|
35
|
+
guidance: options.guidance ? String(options.guidance) : undefined,
|
|
36
|
+
});
|
|
37
|
+
(0, report_1.writeReport)(run);
|
|
38
|
+
return feedback;
|
|
39
|
+
}
|
|
40
|
+
function resolveFeedback(run, feedbackId, options = {}) {
|
|
41
|
+
const feedback = (0, error_feedback_io_1.resolveFeedback)(run, feedbackId, {
|
|
42
|
+
status: options.status === "rejected" ? "rejected" : "resolved",
|
|
43
|
+
nodeId: options.node ? String(options.node) : undefined,
|
|
44
|
+
message: options.message ? String(options.message) : undefined,
|
|
45
|
+
});
|
|
46
|
+
(0, report_1.writeReport)(run);
|
|
47
|
+
return feedback;
|
|
48
|
+
}
|