wicked-crew 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/api/audit.d.ts +13 -0
  2. package/dist/api/audit.d.ts.map +1 -1
  3. package/dist/api/audit.js +18 -2
  4. package/dist/api/audit.js.map +1 -1
  5. package/dist/api/guidance-index.d.ts +39 -0
  6. package/dist/api/guidance-index.d.ts.map +1 -0
  7. package/dist/api/guidance-index.js +67 -0
  8. package/dist/api/guidance-index.js.map +1 -0
  9. package/dist/api/open-path.d.ts +16 -0
  10. package/dist/api/open-path.d.ts.map +1 -1
  11. package/dist/api/open-path.js +22 -0
  12. package/dist/api/open-path.js.map +1 -1
  13. package/dist/api/retry-index.d.ts +30 -0
  14. package/dist/api/retry-index.d.ts.map +1 -0
  15. package/dist/api/retry-index.js +45 -0
  16. package/dist/api/retry-index.js.map +1 -0
  17. package/dist/api/routes.d.ts +53 -1
  18. package/dist/api/routes.d.ts.map +1 -1
  19. package/dist/api/routes.js +352 -23
  20. package/dist/api/routes.js.map +1 -1
  21. package/dist/api/run-files.d.ts +63 -0
  22. package/dist/api/run-files.d.ts.map +1 -0
  23. package/dist/api/run-files.js +271 -0
  24. package/dist/api/run-files.js.map +1 -0
  25. package/dist/api/server.d.ts +79 -0
  26. package/dist/api/server.d.ts.map +1 -1
  27. package/dist/api/server.js +135 -6
  28. package/dist/api/server.js.map +1 -1
  29. package/dist/api/stall-watchdog.d.ts +62 -0
  30. package/dist/api/stall-watchdog.d.ts.map +1 -0
  31. package/dist/api/stall-watchdog.js +138 -0
  32. package/dist/api/stall-watchdog.js.map +1 -0
  33. package/dist/cli/index.js +78 -13
  34. package/dist/cli/index.js.map +1 -1
  35. package/dist/core/adapter.d.ts +24 -10
  36. package/dist/core/adapter.d.ts.map +1 -1
  37. package/dist/core/adapter.js +191 -30
  38. package/dist/core/adapter.js.map +1 -1
  39. package/dist/core/bridge-reaper.d.ts +134 -0
  40. package/dist/core/bridge-reaper.d.ts.map +1 -0
  41. package/dist/core/bridge-reaper.js +286 -0
  42. package/dist/core/bridge-reaper.js.map +1 -0
  43. package/dist/core/deliver.d.ts +118 -0
  44. package/dist/core/deliver.d.ts.map +1 -0
  45. package/dist/core/deliver.js +241 -0
  46. package/dist/core/deliver.js.map +1 -0
  47. package/dist/core/deliverable-floor.d.ts +103 -0
  48. package/dist/core/deliverable-floor.d.ts.map +1 -0
  49. package/dist/core/deliverable-floor.js +173 -0
  50. package/dist/core/deliverable-floor.js.map +1 -0
  51. package/dist/core/exec.d.ts +2 -0
  52. package/dist/core/exec.d.ts.map +1 -1
  53. package/dist/core/exec.js.map +1 -1
  54. package/dist/core/types.d.ts +79 -1
  55. package/dist/core/types.d.ts.map +1 -1
  56. package/dist/core/types.js +3 -0
  57. package/dist/core/types.js.map +1 -1
  58. package/dist/interactive/bridge-pool.d.ts +28 -0
  59. package/dist/interactive/bridge-pool.d.ts.map +1 -1
  60. package/dist/interactive/bridge-pool.js +67 -10
  61. package/dist/interactive/bridge-pool.js.map +1 -1
  62. package/dist/interactive/chat-events.d.ts +207 -0
  63. package/dist/interactive/chat-events.d.ts.map +1 -0
  64. package/dist/interactive/chat-events.js +769 -0
  65. package/dist/interactive/chat-events.js.map +1 -0
  66. package/dist/interactive/demo-events.d.ts +283 -0
  67. package/dist/interactive/demo-events.d.ts.map +1 -0
  68. package/dist/interactive/demo-events.js +889 -0
  69. package/dist/interactive/demo-events.js.map +1 -0
  70. package/dist/interactive/draft-events.d.ts +87 -7
  71. package/dist/interactive/draft-events.d.ts.map +1 -1
  72. package/dist/interactive/draft-events.js +352 -49
  73. package/dist/interactive/draft-events.js.map +1 -1
  74. package/dist/interactive/edit-events.d.ts +22 -0
  75. package/dist/interactive/edit-events.d.ts.map +1 -1
  76. package/dist/interactive/edit-events.js +73 -2
  77. package/dist/interactive/edit-events.js.map +1 -1
  78. package/dist/interactive/repo-snapshot.d.ts +100 -0
  79. package/dist/interactive/repo-snapshot.d.ts.map +1 -0
  80. package/dist/interactive/repo-snapshot.js +289 -0
  81. package/dist/interactive/repo-snapshot.js.map +1 -0
  82. package/dist/projects/graph-paths.d.ts +92 -0
  83. package/dist/projects/graph-paths.d.ts.map +1 -0
  84. package/dist/projects/graph-paths.js +130 -0
  85. package/dist/projects/graph-paths.js.map +1 -0
  86. package/dist/projects/graph.d.ts +179 -0
  87. package/dist/projects/graph.d.ts.map +1 -0
  88. package/dist/projects/graph.js +775 -0
  89. package/dist/projects/graph.js.map +1 -0
  90. package/dist/projects/routes.d.ts +7 -0
  91. package/dist/projects/routes.d.ts.map +1 -1
  92. package/dist/projects/routes.js +122 -0
  93. package/dist/projects/routes.js.map +1 -1
  94. package/dist/studio/assets/index-8p8uwCxG.js +530 -0
  95. package/dist/studio/assets/index-D6S9zUtO.css +32 -0
  96. package/dist/studio/index.html +5 -3
  97. package/package.json +3 -3
  98. package/dist/studio/assets/index-CCwXa1cn.js +0 -428
  99. package/dist/studio/assets/index-HWxo0h41.css +0 -32
@@ -0,0 +1,241 @@
1
+ /**
2
+ * The first-class deliver phase (crew#293) — a run opens its own PR, opt-in.
3
+ *
4
+ * Productizes the operator-side `feature-pr` overlay proven during the DES-MERGE-001 campaign:
5
+ * a Tool phase appended after the workflow's last phase that COMMITS the run's work, pushes the
6
+ * run's branch and opens a PR via `gh`. What was data on one machine becomes a launch option
7
+ * (`deliver: "pr"` on `POST /runs`), composed PER RUN — the shared workflow def is never mutated.
8
+ *
9
+ * Field-proven hardening, replicated here:
10
+ * (a) the branch is derived from the run worktree's basename (`wicked/<run-id>`), falling back
11
+ * to the current branch when that ref does not exist;
12
+ * (b) the script REFUSES to push `main`/`master` (or an empty/detached branch name) — the
13
+ * deliver phase only ever pushes run branches;
14
+ * (c) it STAGES AND COMMITS the run's work, then rebases onto origin's default branch before
15
+ * pushing, and a conflicting rebase FAILS the phase visibly (aborting the rebase, pushing
16
+ * nothing) rather than pushing a conflicted tree;
17
+ * (d) `git push -u origin <branch>`;
18
+ * (e) `gh pr create --head <branch> --fill`, with gh's output and exit status captured
19
+ * SEPARATELY so a gh failure fails the phase carrying gh's own message;
20
+ * (f) the PR URL is the last line of the phase output.
21
+ *
22
+ * One deliberate change from the field version: NO gh account is baked into crew code (the
23
+ * overlay guarded a personal account). Instead, when the `GH_ACCOUNT` env var is set the script
24
+ * compares it against `gh api user -q .login` and runs
25
+ * `gh auth switch --hostname github.com --user "$GH_ACCOUNT"` only when they differ.
26
+ *
27
+ * Merge stays human: the phase opens the PR, never merges it.
28
+ *
29
+ * ## crew#317 — "pushed an empty branch and reported success"
30
+ *
31
+ * Run `d1bc72c2` (wicked-studio) delivered nothing while reporting `completed`. The persisted
32
+ * unit is the evidence, and it names the cause precisely. Its `tool_cmd` was NOT this script —
33
+ * it was the operator's hand-written `feature-pr` OVERLAY def, which begins `set -e` with **no
34
+ * `pipefail`**, so `gh pr create … | tail -1` reported `tail`'s status (0) and the phase passed
35
+ * with gh's error text where the PR URL belongs:
36
+ *
37
+ * ```text
38
+ * could not compute title or body defaults: could not find any commits between origin/main and
39
+ * wicked/d1bc72c2-…
40
+ * ```
41
+ *
42
+ * So the masking mechanism the issue hypothesised is real, but it belonged to the overlay, not
43
+ * here: `pipefail` IS in force for this executor (it is line 1 of this script, `bash -lc` runs it
44
+ * verbatim, and core's `run_tool_cmd` maps any non-zero exit to `StepStatus::Failed`). The three
45
+ * defects this script genuinely shared with the overlay are fixed below:
46
+ *
47
+ * 1. **No commit.** Agents write files and do not commit, so the pushed branch equalled the
48
+ * default branch. The script now stages and commits the run's work itself, and REFUSES to
49
+ * push when there is nothing to deliver.
50
+ * 2. **A masked result.** `| tail -1` discarded everything gh said except one line and made the
51
+ * phase's verdict depend on a pipe option. gh's output and status are now captured
52
+ * separately, and success is re-derived from a real PR URL rather than from an exit code.
53
+ * 3. **Ungoverned.** The phase shipped `verified_evidence: false` / `validator_pin: null`, so
54
+ * nothing re-derived what it claimed. It now declares `verified_evidence: true` — see
55
+ * {@link deliverPrPhase}.
56
+ */
57
+ /** The id of the appended phase — also the collision probe when a def already delivers. */
58
+ export const DELIVER_PHASE_ID = 'deliver';
59
+ /** How much of the run's intent rides in the commit subject before it is truncated. */
60
+ const INTENT_SUBJECT_CAP = 72;
61
+ /**
62
+ * The run's intent, reduced to something safe to embed in a single-quoted shell assignment and
63
+ * to use as a one-line commit subject.
64
+ *
65
+ * The intent is caller-supplied free text off `POST /runs`, and it is being spliced into a bash
66
+ * script — so this is a containment boundary, not cosmetics. Control characters (newlines
67
+ * included) and the single quote are REMOVED: with no `'` left, the value cannot escape the
68
+ * single-quoted assignment the script wraps it in, and with no control characters it cannot add
69
+ * a line. Everything else (unicode, `$`, backticks, backslashes) is inert inside single quotes
70
+ * and is kept, so the subject still reads like the intent it came from.
71
+ */
72
+ function commitSubjectIntent(intent) {
73
+ return (intent ?? '')
74
+ .replace(/[\u0000-\u001f\u007f]+/g, ' ')
75
+ .replace(/'/g, '')
76
+ .replace(/\s+/g, ' ')
77
+ .trim()
78
+ .slice(0, INTENT_SUBJECT_CAP)
79
+ .trim();
80
+ }
81
+ /**
82
+ * The hardened deliver script, run as `bash -lc <script>` (login shell so the operator's PATH —
83
+ * where `gh` lives — is loaded, same as the field overlay).
84
+ *
85
+ * `set -euo pipefail` is load-bearing and verified in force for this executor (crew#317): the
86
+ * engine spawns `bash -lc` with this text verbatim, and `run_tool_cmd` turns a non-zero exit into
87
+ * `StepStatus::Failed`. It is no longer the ONLY thing standing between a failed `gh` and a green
88
+ * phase, though — the gh result is captured explicitly and success is re-derived from evidence.
89
+ *
90
+ * `intent` (the run's problem statement) rides in the commit subject; it is sanitised by
91
+ * {@link commitSubjectIntent} before it is spliced in.
92
+ */
93
+ export function deliverPrScript(intent) {
94
+ return [
95
+ 'set -euo pipefail',
96
+ // The engine concatenates the child's stdout and THEN its stderr, so anything git writes to
97
+ // stderr would land after the PR URL and break "(f) the URL is the last line". Folding stderr
98
+ // into stdout for the whole phase keeps the output in true chronological order and makes the
99
+ // final `echo "$URL"` genuinely last.
100
+ 'exec 2>&1',
101
+ // Account guard — env-driven, never a name baked into crew code. Unset ⇒ whatever account
102
+ // gh already holds is used as-is.
103
+ 'if [ -n "${GH_ACCOUNT:-}" ]; then L=$(gh api user -q .login); [ "$L" = "$GH_ACCOUNT" ] || gh auth switch --hostname github.com --user "$GH_ACCOUNT"; fi',
104
+ // (a) The run branch: wicked/<worktree-basename> (the engine names run worktrees by run id),
105
+ // falling back to the currently checked-out branch when that ref does not exist.
106
+ 'R=$(basename "$PWD")',
107
+ 'B="wicked/$R"',
108
+ 'git rev-parse --verify "$B" >/dev/null 2>&1 || B=$(git branch --show-current)',
109
+ // Derive origin's default branch FIRST — the refusal below must cover a repo whose
110
+ // default is trunk/develop/anything, not just main/master (Copilot on #303).
111
+ 'git fetch origin',
112
+ 'D=$(git symbolic-ref -q --short refs/remotes/origin/HEAD || echo origin/main)',
113
+ 'DEF="${D#origin/}"',
114
+ // (b) Refuse the repo's own default branch (by derived name), the classic names, and an
115
+ // empty name (detached HEAD), which would otherwise turn the push into a garbage ref.
116
+ 'case "$B" in ""|main|master|"$DEF") echo "deliver: refusing to push branch \'$B\' — the deliver phase only pushes run branches, never the default branch"; exit 1;; esac',
117
+ // The commit below writes to whatever HEAD is, while the push sends $B. When those differ
118
+ // (a `wicked/<run-id>` ref exists but is NOT what this worktree has checked out) committing
119
+ // would put one branch's work on another and push a branch that never saw it. Refuse instead.
120
+ 'C=$(git branch --show-current)',
121
+ '[ "$C" = "$B" ] || { echo "deliver: the worktree is on \'$C\' but the run branch is \'$B\' — refusing to commit one branch\'s work onto another; nothing was pushed"; exit 1; }',
122
+ // (c1) COMMIT THE RUN'S WORK (crew#317). Agents write files; they do not commit — which is
123
+ // the premise of core#291 and the reason `d1bc72c2` pushed a branch identical to origin/main.
124
+ // Author identity is deliberately NOT set here: the run worktree belongs to the operator's
125
+ // own clone, so `git commit` uses the repo/user config that already exists (and fails loudly,
126
+ // pushing nothing, if that config is missing). `git add -A` respects .gitignore.
127
+ `I='${commitSubjectIntent(intent)}'`,
128
+ 'if [ -n "$I" ]; then M="wicked-crew run $R: $I"; else M="wicked-crew run $R"; fi',
129
+ 'git add -A',
130
+ // Only commit when something is staged — a run that committed incrementally (core#280's
131
+ // liveness contract) leaves a clean tree and must not gain an empty commit here.
132
+ 'git diff --cached --quiet || git commit -q -m "$M"',
133
+ // (c2) NOTHING TO DELIVER — no staged work AND no commits of its own. Fail LOUDLY before the
134
+ // remote is touched: an empty ref pushed under a run id is worse than a failed phase.
135
+ 'A=$(git rev-list --count "$D..$B")',
136
+ '[ "$A" -ge 1 ] || { echo "deliver: nothing to deliver — the run produced no committed change ($B is not ahead of $D); nothing was pushed"; exit 1; }',
137
+ // (c3) Rebase onto origin's default branch so the PR opens mergeable. A conflict must fail
138
+ // the phase VISIBLY with nothing pushed — the abort leaves the worktree on the pre-rebase
139
+ // branch tip instead of mid-rebase.
140
+ 'git rebase "$D" "$B" || { git rebase --abort >/dev/null 2>&1 || true; echo "deliver: rebase of $B onto $D failed (conflicts) — resolve on the branch and re-run; nothing was pushed"; exit 1; }',
141
+ // Re-derive after the rebase: it drops commits already upstream (patch-id equal), so a branch
142
+ // that WAS ahead can come out of a rebase carrying nothing of its own.
143
+ 'A=$(git rev-list --count "$D..$B")',
144
+ '[ "$A" -ge 1 ] || { echo "deliver: nothing to deliver — the run produced no committed change (after rebasing onto $D, $B carries no commit of its own); nothing was pushed"; exit 1; }',
145
+ // (d) Push.
146
+ 'git push -u origin "$B"',
147
+ // (e) Open the PR with gh's OUTPUT and EXIT STATUS captured separately (crew#317). The old
148
+ // `| tail -1` threw away everything gh said but one line and made the phase's verdict a
149
+ // property of a shell option; a gh failure now fails the phase carrying gh's own message.
150
+ 'if ! OUT=$(gh pr create --head "$B" --fill 2>&1); then echo "$OUT"; echo "deliver: gh pr create failed for $B — no PR was opened"; exit 1; fi',
151
+ 'echo "$OUT"',
152
+ // (f) DONE IS RE-DERIVED, NOT ASSERTED — twice, from two independent facts, before the phase
153
+ // is allowed to report a delivery:
154
+ // 1. gh actually produced a PR URL (an exit code alone is a claim, not evidence);
155
+ // 2. the ref ON THE REMOTE is ahead of origin's default branch by at least one commit.
156
+ "URL=$(printf '%s\\n' \"$OUT\" | grep -Eo 'https://[^[:space:]]+/pull/[0-9]+' | tail -1 || true)",
157
+ '[ -n "$URL" ] || { echo "deliver: gh pr create exited 0 but produced no PR URL for $B — refusing to report a delivery nothing can be pointed at"; exit 1; }',
158
+ 'P=$(git rev-list --count "$D..origin/$B")',
159
+ '[ "$P" -ge 1 ] || { echo "deliver: $B is not ahead of $D on the remote after the push — refusing to report a delivery with no commits"; exit 1; }',
160
+ 'echo "$URL"',
161
+ ].join('\n');
162
+ }
163
+ /**
164
+ * The deliver phase definition — the PhaseDef JSON shape core accepts, fully spelled out so the
165
+ * composed def round-trips through `registerWorkflow` (core's serde) and crew's own `WorkflowDef`
166
+ * type without casts. `gate: 'auto'` + `executes_code: false`: the phase is deterministic tooling,
167
+ * not governed agent work — its failure surface is the exit code + output, which core reports as
168
+ * a failed unit.
169
+ *
170
+ * ## Why `verified_evidence: true` and `validator_pin: null` (crew#317)
171
+ *
172
+ * The phase that touches the remote was the one phase nothing re-derived. The engine's phase model
173
+ * DOES let a Tool-executor phase carry a deterministic floor, and the mechanism is the flag rather
174
+ * than a pin crew mints itself:
175
+ *
176
+ * - a pin is a CONTENT ADDRESS into core's validator vault, and `attach_pinned_validators` is
177
+ * fail-closed on one that does not resolve — it BAILS the run at plan time. Authoring and
178
+ * approving a validator is `wicked-core provision-validator` + `approve-validator`, neither of
179
+ * which is exposed through the napi surface crew drives, so a pin invented here would fail
180
+ * every run of every deliver-composed workflow on a machine that had not been seeded by hand;
181
+ * - `verified_evidence: true` with no pin of its own is armed AT REGISTRATION by
182
+ * `enforce_verified_evidence` with the built-in evidence floor (`EVIDENCE_FLOOR_PIN`,
183
+ * criterion: "the run left a change in its worktree (done is re-derived from the diff, never
184
+ * asserted)"), which `pre_distribute` seeds on the plan path so it always resolves. Same
185
+ * mechanism `feature/test`, `bug/verify` and `migration/verify` reach it by.
186
+ *
187
+ * The floor then re-runs against the run's worktree at the gate, INDEPENDENTLY of anything this
188
+ * script printed, and denies the phase when the run left no change. Layer 2 (the agent judge)
189
+ * stays out of it: core hands the Tool path `agent_verdict: None`, so a tool phase's floor is
190
+ * deterministic and costs no LLM call. The PR-URL and branch-ahead assertions stay in the script
191
+ * because no vaulted floor can see the remote.
192
+ */
193
+ export function deliverPrPhase(dependsOn = [], intent) {
194
+ return {
195
+ id: DELIVER_PHASE_ID,
196
+ kind: 'build',
197
+ executor: { type: 'tool', cmd: ['bash', '-lc', deliverPrScript(intent)] },
198
+ gate_type: null,
199
+ gate: 'auto',
200
+ executes_code: false,
201
+ verified_evidence: true,
202
+ required_deliverables: [],
203
+ depends_on: dependsOn,
204
+ role: 'neutral',
205
+ skill_ref: null,
206
+ allowed_skills: [],
207
+ validator_pin: null,
208
+ };
209
+ }
210
+ /**
211
+ * Compose a PER-RUN workflow def: `base`'s phases (untouched — the shared def is never mutated)
212
+ * plus the deliver phase appended last, under a run-scoped id. The caller registers the result
213
+ * with the engine for THIS run only; nothing is written to the overlay dir and the composed id
214
+ * never enters the user-workflow registry, so the catalog (`GET /workflows`) stays clean.
215
+ *
216
+ * `intent` is the run's problem statement — it names WHAT was delivered in the commit subject
217
+ * (`wicked-crew run <run-id>: <intent>`); omit it and the subject carries the run id alone.
218
+ *
219
+ * Throws when `base` already carries a `deliver` phase — appending a second phase with the same
220
+ * id would be ambiguous at best; the caller launches such a def as-is instead (see
221
+ * `CoreAdapter.launchRun`).
222
+ */
223
+ export function composeDeliverWorkflow(base, runId, intent) {
224
+ if (base.phases.some((p) => p.id === DELIVER_PHASE_ID)) {
225
+ throw new Error(`workflow '${base.id}' already has a '${DELIVER_PHASE_ID}' phase — launch it without deliver: "pr"`);
226
+ }
227
+ const last = base.phases[base.phases.length - 1];
228
+ // Run ids are UUIDs from the route, but the CLI path accepts caller-supplied ids — keep the
229
+ // composed id inside the same safe charset `registerWorkflow` enforces for user defs.
230
+ const safeRunId = runId.replace(/[^a-zA-Z0-9._-]/g, '_');
231
+ // registerWorkflow enforces id.length <= 128; a caller-supplied CLI session id can be long.
232
+ // Truncate the run-id TAIL, keeping the base+marker prefix intact (Copilot on #303).
233
+ const composedId = `${base.id}-deliver-${safeRunId}`.slice(0, 128);
234
+ return {
235
+ // No `is_system` on purpose: core's overlay/register schema rejects unknown fields, and the
236
+ // composed def is engine-input, not catalog data.
237
+ id: composedId,
238
+ phases: [...base.phases, deliverPrPhase(last !== undefined ? [last.id] : [], intent)],
239
+ };
240
+ }
241
+ //# sourceMappingURL=deliver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deliver.js","sourceRoot":"","sources":["../../src/core/deliver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * THE DELIVERABLE FLOOR (crew#311) — "done" is re-derived from the artifact, never asserted.
3
+ *
4
+ * ## The defect
5
+ *
6
+ * A governed unit that produced NOTHING still passed its execution gate on the strength of a
7
+ * prose reply. The engine's only universal floor is the SUBSTANCE floor
8
+ * (wicked-core `actor.rs`, "phase produced no reviewable substance"): a governed
9
+ * Creator/Neutral unit is rejected only when its output carries BOTH under 200 trimmed chars
10
+ * of prose AND no worktree change. So ~200 characters of narration — "I'll read the design
11
+ * spec, let me check the API types…" — clears it, with no file anywhere. Prose length stood in
12
+ * for evidence.
13
+ *
14
+ * The engine has two real evidence instruments, and neither reaches a run of this shape:
15
+ *
16
+ * 1. `validator_pin` → the built-in EVIDENCE floor (`builtin_floors::EVIDENCE_FLOOR_PIN`,
17
+ * criterion "the run left a change in its worktree (done is re-derived from the diff, never
18
+ * asserted)"). It re-verifies a git DIFF, and is fail-closed on a run with no worktree — so
19
+ * an UNBOUND run (`repoRef` omitted, `workdir: null`) can never satisfy it. Every crew
20
+ * interactive seam launches unbound on purpose (wicked-core#293/#294), and their deliverable
21
+ * is a FILE in a declared write root, invisible to a diff.
22
+ * 2. `required_deliverables` → enforced by wicked-core as of FINDING-101, but only in the
23
+ * WRAPPED-CLI runner (`execute_wrapped.rs`), only against the unit's own cwd, and any
24
+ * absolute or `..`-escaping path is counted MISSING by construction. The ACP runner — the
25
+ * path a real seat takes — never consults it. So for a run whose deliverable is an absolute
26
+ * path under `extraWriteRoots`, declaring it there would fail every run on one runner and
27
+ * check nothing on the other. That gap is wicked-core's to close
28
+ * (wicked-core#297, items 1 and 3); once it is, this phase can retire in favour of the
29
+ * engine field. Crew must not paper over it meanwhile by declaring something unverifiable.
30
+ *
31
+ * ## What this module does
32
+ *
33
+ * It gives crew the instrument it can honestly own: a deterministic TOOL phase, appended to a
34
+ * PER-RUN copy of the workflow def (the exact mechanism `core/deliver.ts` proved for
35
+ * `deliver: "pr"` — the shared def is never mutated, nothing lands in the overlay dir, the
36
+ * catalog never grows a per-run entry), which asserts that the artifacts the launcher declared
37
+ * EXIST and are non-empty. A Tool phase's failure surface is its exit code: wicked-core's
38
+ * `run_tool_cmd` maps a non-zero exit to `StepStatus::Failed`, which fails the unit and the run
39
+ * through the unchanged completion path. No LLM, no worktree, no judgement about the content —
40
+ * only "the phase promised this file; is it there".
41
+ *
42
+ * That is deliberately a FLOOR and not a review, in exactly the sense `builtin_floors` documents:
43
+ * it proves an artifact exists. It says nothing about whether the artifact is correct, or even
44
+ * related to the task. What it removes is the failure mode crew#311 recorded — a unit whose
45
+ * `Write` was policy-denied, which therefore produced no file at all, reporting done.
46
+ *
47
+ * ## The report
48
+ *
49
+ * The script prints what was EXPECTED and what was FOUND before it exits, on both branches, so
50
+ * the failure is legible from the unit output alone: which paths were declared, which exist
51
+ * (with their size), and which are missing and why (absent / empty file / empty directory).
52
+ * An operator reading a failed run must never have to guess what the phase was supposed to
53
+ * produce.
54
+ */
55
+ import type { PhaseDef, WorkflowDef } from './types.js';
56
+ /** The id of the appended floor phase — also the collision probe when a def already carries one. */
57
+ export declare const DELIVERABLE_FLOOR_PHASE_ID = "verify-deliverables";
58
+ /** The marker line the failing branch prints. Asserted by tests and greppable in a unit output. */
59
+ export declare const DELIVERABLE_FLOOR_FAILURE_MARKER = "[wicked-crew] DELIVERABLE FLOOR FAILED";
60
+ /**
61
+ * The floor program, run as `node -e <script> <path...>`.
62
+ *
63
+ * Node rather than a shell: this must work identically on macOS, Linux, and Windows, and the
64
+ * daemon already IS node, so `process.execPath` is a guaranteed-present absolute interpreter
65
+ * (see {@link deliverableFloorPhase}). `-e` runs CommonJS, so `require` is available; the
66
+ * declared paths arrive as `process.argv.slice(1)`, passed as argv rather than interpolated
67
+ * into a shell string so a path containing a space, a quote, or a `$` cannot be re-parsed.
68
+ *
69
+ * A path counts as PRODUCED when it exists AND carries bytes: a non-empty file, or a directory
70
+ * with at least one entry (a phase may declare a directory of outputs). A zero-byte file is
71
+ * NOT evidence — it is the same "nothing was produced" this exists to catch, and the draft/chat
72
+ * seams already treated an empty deliverable as a failure at their own post-hoc check.
73
+ */
74
+ export declare function deliverableFloorScript(): string;
75
+ /**
76
+ * The floor PhaseDef for `paths`.
77
+ *
78
+ * `cmd[0]` is `process.execPath` — the ABSOLUTE path of the node binary already running the
79
+ * daemon — not the bare name `node`. wicked-core preflights every Tool phase at launch
80
+ * (`workflow::preflight_tool_phases`) and REFUSES to start a run whose tool binary does not
81
+ * resolve; a bare `node` resolves only if the engine's PATH happens to carry one, which is
82
+ * exactly the kind of environment-dependent gate that fails in production and passes in tests.
83
+ * The composed def is per-run and hot-registered only, so baking a machine-local path into it
84
+ * costs nothing: it never reaches the catalog or the overlay dir.
85
+ *
86
+ * `role: 'neutral'` + `executes_code: false` + `governed`-free Tool dispatch: this phase is
87
+ * deterministic tooling, so the substance floor, the agent judge, and the input-governance fold
88
+ * do not apply to it — its verdict IS its exit code.
89
+ */
90
+ export declare function deliverableFloorPhase(paths: readonly string[], dependsOn?: string[]): PhaseDef;
91
+ /**
92
+ * Compose a PER-RUN def: `base`'s phases (untouched — the shared def is never mutated) plus the
93
+ * deliverable floor appended last, under a run-scoped id. Mirrors `composeDeliverWorkflow`'s
94
+ * contract exactly, including the id charset/length rules `registerWorkflow` enforces and the
95
+ * deliberate absence of `is_system` (core's register schema rejects unknown fields on this path,
96
+ * and a composed def is engine input, not catalog data).
97
+ *
98
+ * Throws on an empty `paths` list — a floor over nothing would pass vacuously, which is the
99
+ * defect, not the fix. Throws on a def that already carries the floor phase, for the same
100
+ * ambiguity reason `composeDeliverWorkflow` does.
101
+ */
102
+ export declare function composeDeliverableFloor(base: WorkflowDef, runId: string, paths: readonly string[]): WorkflowDef;
103
+ //# sourceMappingURL=deliverable-floor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deliverable-floor.d.ts","sourceRoot":"","sources":["../../src/core/deliverable-floor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAExD,oGAAoG;AACpG,eAAO,MAAM,0BAA0B,wBAAwB,CAAC;AAEhE,mGAAmG;AACnG,eAAO,MAAM,gCAAgC,2CACH,CAAC;AAE3C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CA0B/C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,SAAS,GAAE,MAAM,EAAO,GACvB,QAAQ,CA0BV;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,WAAW,CAuBb"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * THE DELIVERABLE FLOOR (crew#311) — "done" is re-derived from the artifact, never asserted.
3
+ *
4
+ * ## The defect
5
+ *
6
+ * A governed unit that produced NOTHING still passed its execution gate on the strength of a
7
+ * prose reply. The engine's only universal floor is the SUBSTANCE floor
8
+ * (wicked-core `actor.rs`, "phase produced no reviewable substance"): a governed
9
+ * Creator/Neutral unit is rejected only when its output carries BOTH under 200 trimmed chars
10
+ * of prose AND no worktree change. So ~200 characters of narration — "I'll read the design
11
+ * spec, let me check the API types…" — clears it, with no file anywhere. Prose length stood in
12
+ * for evidence.
13
+ *
14
+ * The engine has two real evidence instruments, and neither reaches a run of this shape:
15
+ *
16
+ * 1. `validator_pin` → the built-in EVIDENCE floor (`builtin_floors::EVIDENCE_FLOOR_PIN`,
17
+ * criterion "the run left a change in its worktree (done is re-derived from the diff, never
18
+ * asserted)"). It re-verifies a git DIFF, and is fail-closed on a run with no worktree — so
19
+ * an UNBOUND run (`repoRef` omitted, `workdir: null`) can never satisfy it. Every crew
20
+ * interactive seam launches unbound on purpose (wicked-core#293/#294), and their deliverable
21
+ * is a FILE in a declared write root, invisible to a diff.
22
+ * 2. `required_deliverables` → enforced by wicked-core as of FINDING-101, but only in the
23
+ * WRAPPED-CLI runner (`execute_wrapped.rs`), only against the unit's own cwd, and any
24
+ * absolute or `..`-escaping path is counted MISSING by construction. The ACP runner — the
25
+ * path a real seat takes — never consults it. So for a run whose deliverable is an absolute
26
+ * path under `extraWriteRoots`, declaring it there would fail every run on one runner and
27
+ * check nothing on the other. That gap is wicked-core's to close
28
+ * (wicked-core#297, items 1 and 3); once it is, this phase can retire in favour of the
29
+ * engine field. Crew must not paper over it meanwhile by declaring something unverifiable.
30
+ *
31
+ * ## What this module does
32
+ *
33
+ * It gives crew the instrument it can honestly own: a deterministic TOOL phase, appended to a
34
+ * PER-RUN copy of the workflow def (the exact mechanism `core/deliver.ts` proved for
35
+ * `deliver: "pr"` — the shared def is never mutated, nothing lands in the overlay dir, the
36
+ * catalog never grows a per-run entry), which asserts that the artifacts the launcher declared
37
+ * EXIST and are non-empty. A Tool phase's failure surface is its exit code: wicked-core's
38
+ * `run_tool_cmd` maps a non-zero exit to `StepStatus::Failed`, which fails the unit and the run
39
+ * through the unchanged completion path. No LLM, no worktree, no judgement about the content —
40
+ * only "the phase promised this file; is it there".
41
+ *
42
+ * That is deliberately a FLOOR and not a review, in exactly the sense `builtin_floors` documents:
43
+ * it proves an artifact exists. It says nothing about whether the artifact is correct, or even
44
+ * related to the task. What it removes is the failure mode crew#311 recorded — a unit whose
45
+ * `Write` was policy-denied, which therefore produced no file at all, reporting done.
46
+ *
47
+ * ## The report
48
+ *
49
+ * The script prints what was EXPECTED and what was FOUND before it exits, on both branches, so
50
+ * the failure is legible from the unit output alone: which paths were declared, which exist
51
+ * (with their size), and which are missing and why (absent / empty file / empty directory).
52
+ * An operator reading a failed run must never have to guess what the phase was supposed to
53
+ * produce.
54
+ */
55
+ /** The id of the appended floor phase — also the collision probe when a def already carries one. */
56
+ export const DELIVERABLE_FLOOR_PHASE_ID = 'verify-deliverables';
57
+ /** The marker line the failing branch prints. Asserted by tests and greppable in a unit output. */
58
+ export const DELIVERABLE_FLOOR_FAILURE_MARKER = '[wicked-crew] DELIVERABLE FLOOR FAILED';
59
+ /**
60
+ * The floor program, run as `node -e <script> <path...>`.
61
+ *
62
+ * Node rather than a shell: this must work identically on macOS, Linux, and Windows, and the
63
+ * daemon already IS node, so `process.execPath` is a guaranteed-present absolute interpreter
64
+ * (see {@link deliverableFloorPhase}). `-e` runs CommonJS, so `require` is available; the
65
+ * declared paths arrive as `process.argv.slice(1)`, passed as argv rather than interpolated
66
+ * into a shell string so a path containing a space, a quote, or a `$` cannot be re-parsed.
67
+ *
68
+ * A path counts as PRODUCED when it exists AND carries bytes: a non-empty file, or a directory
69
+ * with at least one entry (a phase may declare a directory of outputs). A zero-byte file is
70
+ * NOT evidence — it is the same "nothing was produced" this exists to catch, and the draft/chat
71
+ * seams already treated an empty deliverable as a failure at their own post-hoc check.
72
+ */
73
+ export function deliverableFloorScript() {
74
+ return [
75
+ 'const fs=require("node:fs");',
76
+ 'const want=process.argv.slice(1);',
77
+ 'const found=[],missing=[];',
78
+ 'for(const p of want){',
79
+ 'let s=null;',
80
+ 'try{s=fs.statSync(p)}catch(e){s=null}',
81
+ 'if(s===null){missing.push(p+" (does not exist)");continue}',
82
+ 'if(s.isDirectory()){',
83
+ 'let n=0;try{n=fs.readdirSync(p).length}catch(e){n=0}',
84
+ 'if(n===0){missing.push(p+" (directory is empty)")}else{found.push(p+" (directory, "+n+" entries)")}',
85
+ 'continue}',
86
+ 'if(s.size===0){missing.push(p+" (file is empty, 0 bytes)");continue}',
87
+ 'found.push(p+" ("+s.size+" bytes)");',
88
+ '}',
89
+ 'console.log("[wicked-crew] deliverable floor: this phase declared "+want.length+" artifact(s).");',
90
+ 'console.log("[wicked-crew] EXPECTED: "+(want.length?want.join(", "):"(none)"));',
91
+ 'console.log("[wicked-crew] FOUND: "+(found.length?found.join(", "):"(nothing)"));',
92
+ 'if(missing.length===0){',
93
+ 'console.log("[wicked-crew] every declared deliverable exists and carries bytes — done is re-derived from the artifact, not asserted.");',
94
+ 'process.exit(0)}',
95
+ 'console.log("[wicked-crew] MISSING: "+missing.join(", "));',
96
+ `console.log(${JSON.stringify(DELIVERABLE_FLOOR_FAILURE_MARKER)}+" — the run reported done without producing the artifact(s) it was launched to produce. A prose reply is not a deliverable (crew#311).");`,
97
+ 'process.exit(1);',
98
+ ].join('');
99
+ }
100
+ /**
101
+ * The floor PhaseDef for `paths`.
102
+ *
103
+ * `cmd[0]` is `process.execPath` — the ABSOLUTE path of the node binary already running the
104
+ * daemon — not the bare name `node`. wicked-core preflights every Tool phase at launch
105
+ * (`workflow::preflight_tool_phases`) and REFUSES to start a run whose tool binary does not
106
+ * resolve; a bare `node` resolves only if the engine's PATH happens to carry one, which is
107
+ * exactly the kind of environment-dependent gate that fails in production and passes in tests.
108
+ * The composed def is per-run and hot-registered only, so baking a machine-local path into it
109
+ * costs nothing: it never reaches the catalog or the overlay dir.
110
+ *
111
+ * `role: 'neutral'` + `executes_code: false` + `governed`-free Tool dispatch: this phase is
112
+ * deterministic tooling, so the substance floor, the agent judge, and the input-governance fold
113
+ * do not apply to it — its verdict IS its exit code.
114
+ */
115
+ export function deliverableFloorPhase(paths, dependsOn = []) {
116
+ return {
117
+ id: DELIVERABLE_FLOOR_PHASE_ID,
118
+ kind: 'test',
119
+ executor: {
120
+ type: 'tool',
121
+ cmd: [process.execPath, '-e', deliverableFloorScript(), ...paths],
122
+ },
123
+ gate_type: 'execution',
124
+ gate: 'auto',
125
+ executes_code: false,
126
+ // NOT `verified_evidence: true`: wicked-core arms any `verified_evidence` phase that names no
127
+ // pin of its own with the worktree-DIFF floor (FINDING-055), which is fail-closed on the
128
+ // repo-less runs this phase exists to serve — it would deny every one of them for the wrong
129
+ // reason. This phase carries its own re-verification in its exit code.
130
+ verified_evidence: false,
131
+ // NOT the declared paths either: core checks `required_deliverables` relative to the unit's
132
+ // cwd and counts every absolute path as missing (see the module doc; wicked-core#297).
133
+ // Declaring them here would fail the run on the wrapped-CLI path for the wrong reason.
134
+ required_deliverables: [],
135
+ depends_on: dependsOn,
136
+ role: 'neutral',
137
+ skill_ref: null,
138
+ allowed_skills: [],
139
+ validator_pin: null,
140
+ };
141
+ }
142
+ /**
143
+ * Compose a PER-RUN def: `base`'s phases (untouched — the shared def is never mutated) plus the
144
+ * deliverable floor appended last, under a run-scoped id. Mirrors `composeDeliverWorkflow`'s
145
+ * contract exactly, including the id charset/length rules `registerWorkflow` enforces and the
146
+ * deliberate absence of `is_system` (core's register schema rejects unknown fields on this path,
147
+ * and a composed def is engine input, not catalog data).
148
+ *
149
+ * Throws on an empty `paths` list — a floor over nothing would pass vacuously, which is the
150
+ * defect, not the fix. Throws on a def that already carries the floor phase, for the same
151
+ * ambiguity reason `composeDeliverWorkflow` does.
152
+ */
153
+ export function composeDeliverableFloor(base, runId, paths) {
154
+ if (paths.length === 0) {
155
+ throw new Error('requireDeliverables: at least one path must be declared — a floor over nothing passes vacuously');
156
+ }
157
+ for (const p of paths) {
158
+ if (p.trim().length === 0) {
159
+ throw new Error('requireDeliverables: a declared deliverable path must not be blank');
160
+ }
161
+ }
162
+ if (base.phases.some((p) => p.id === DELIVERABLE_FLOOR_PHASE_ID)) {
163
+ throw new Error(`workflow '${base.id}' already has a '${DELIVERABLE_FLOOR_PHASE_ID}' phase — launch it without requireDeliverables`);
164
+ }
165
+ const last = base.phases[base.phases.length - 1];
166
+ const safeRunId = runId.replace(/[^a-zA-Z0-9._-]/g, '_');
167
+ const composedId = `${base.id}-verified-${safeRunId}`.slice(0, 128);
168
+ return {
169
+ id: composedId,
170
+ phases: [...base.phases, deliverableFloorPhase(paths, last !== undefined ? [last.id] : [])],
171
+ };
172
+ }
173
+ //# sourceMappingURL=deliverable-floor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deliverable-floor.js","sourceRoot":"","sources":["../../src/core/deliverable-floor.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,8 @@ type ExecOpts = {
18
18
  timeout?: number;
19
19
  cwd?: string;
20
20
  env?: NodeJS.ProcessEnv;
21
+ /** Suppress the console window a child would open on Windows (git, etc.). */
22
+ windowsHide?: boolean;
21
23
  /** `number | undefined` on purpose: `exactOptionalPropertyTypes` would otherwise reject the very
22
24
  * shape this module defends against, making the guard below untypeable and untestable. */
23
25
  maxBuffer?: number | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/core/exec.ts"],"names":[],"mappings":"AA+BA;;sFAEsF;AACtF,eAAO,MAAM,qBAAqB,QAAmB,CAAC;AAUtD;;;;oDAIoD;AACpD,qBAAa,kBAAmB,SAAQ,KAAK;IAEzC,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM;gBADlB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM;CAS9B;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAMtD;AAED,KAAK,QAAQ,GAAG;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB;+FAC2F;IAC3F,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF;;kFAEkF;AAClF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAEvD;AAED;;kEAEkE;AAClE,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,GAAE,QAAa,GAClB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAoB7C"}
1
+ {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/core/exec.ts"],"names":[],"mappings":"AA+BA;;sFAEsF;AACtF,eAAO,MAAM,qBAAqB,QAAmB,CAAC;AAUtD;;;;oDAIoD;AACpD,qBAAa,kBAAmB,SAAQ,KAAK;IAEzC,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM;gBADlB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM;CAS9B;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAMtD;AAED,KAAK,QAAQ,GAAG;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;+FAC2F;IAC3F,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF;;kFAEkF;AAClF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAEvD;AAED;;kEAEkE;AAClE,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,GAAE,QAAa,GAClB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAoB7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/core/exec.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,EAAE;AACF,eAAe;AACf,EAAE;AACF,oGAAoG;AACpG,iGAAiG;AACjG,gGAAgG;AAChG,2FAA2F;AAC3F,EAAE;AACF,kGAAkG;AAClG,kGAAkG;AAClG,qCAAqC;AACrC,EAAE;AACF,wDAAwD;AACxD,EAAE;AACF,gGAAgG;AAChG,8FAA8F;AAC9F,mGAAmG;AACnG,0EAA0E;AAC1E,EAAE;AACF,0BAA0B;AAC1B,EAAE;AACF,8FAA8F;AAC9F,6FAA6F;AAC7F,0BAA0B;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C;;sFAEsF;AACtF,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEtD;kFACkF;AAClF,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,CAAC,IAAI,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC;IACpE,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IACpD,OAAO,GAAG,CAAC,QAAQ,CAAC;AACtB,CAAC;AAED;;;;oDAIoD;AACpD,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAEhC;IACA;IAFX,YACW,IAAY,EACZ,UAAkB;QAE3B,KAAK,CACH,GAAG,IAAI,uBAAuB,UAAU,CAAC,UAAU,CAAC,wCAAwC;YAC1F,0CAA0C,IAAI,8CAA8C;YAC5F,wDAAwD,CAC3D,CAAC;QAPO,SAAI,GAAJ,IAAI,CAAQ;QACZ,eAAU,GAAV,UAAU,CAAQ;QAO3B,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,iEAAiE;AACjE,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACX,GAA0B,CAAC,IAAI,KAAK,mCAAmC,CACzE,CAAC;AACJ,CAAC;AAWD;;kFAEkF;AAClF,MAAM,UAAU,gBAAgB,CAAC,IAAc;IAC7C,OAAO,IAAI,CAAC,SAAS,IAAI,qBAAqB,CAAC;AACjD,CAAC;AAED;;kEAEkE;AAClE,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,IAAc,EACd,OAAiB,EAAE;IAEnB,gGAAgG;IAChG,6FAA6F;IAC7F,2FAA2F;IAC3F,iCAAiC;IACjC,EAAE;IACF,sFAAsF;IACtF,6EAA6E;IAC7E,8DAA8D;IAC9D,EAAE;IACF,8FAA8F;IAC9F,uFAAuF;IACvF,4CAA4C;IAC5C,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC;QACH,OAAO,MAAM,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IACjE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,gBAAgB,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,kBAAkB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACzE,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/core/exec.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,EAAE;AACF,eAAe;AACf,EAAE;AACF,oGAAoG;AACpG,iGAAiG;AACjG,gGAAgG;AAChG,2FAA2F;AAC3F,EAAE;AACF,kGAAkG;AAClG,kGAAkG;AAClG,qCAAqC;AACrC,EAAE;AACF,wDAAwD;AACxD,EAAE;AACF,gGAAgG;AAChG,8FAA8F;AAC9F,mGAAmG;AACnG,0EAA0E;AAC1E,EAAE;AACF,0BAA0B;AAC1B,EAAE;AACF,8FAA8F;AAC9F,6FAA6F;AAC7F,0BAA0B;AAE1B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C;;sFAEsF;AACtF,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEtD;kFACkF;AAClF,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,CAAC,IAAI,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC;IACpE,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IACpD,OAAO,GAAG,CAAC,QAAQ,CAAC;AACtB,CAAC;AAED;;;;oDAIoD;AACpD,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAEhC;IACA;IAFX,YACW,IAAY,EACZ,UAAkB;QAE3B,KAAK,CACH,GAAG,IAAI,uBAAuB,UAAU,CAAC,UAAU,CAAC,wCAAwC;YAC1F,0CAA0C,IAAI,8CAA8C;YAC5F,wDAAwD,CAC3D,CAAC;QAPO,SAAI,GAAJ,IAAI,CAAQ;QACZ,eAAU,GAAV,UAAU,CAAQ;QAO3B,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,iEAAiE;AACjE,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACX,GAA0B,CAAC,IAAI,KAAK,mCAAmC,CACzE,CAAC;AACJ,CAAC;AAaD;;kFAEkF;AAClF,MAAM,UAAU,gBAAgB,CAAC,IAAc;IAC7C,OAAO,IAAI,CAAC,SAAS,IAAI,qBAAqB,CAAC;AACjD,CAAC;AAED;;kEAEkE;AAClE,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,IAAc,EACd,OAAiB,EAAE;IAEnB,gGAAgG;IAChG,6FAA6F;IAC7F,2FAA2F;IAC3F,iCAAiC;IACjC,EAAE;IACF,sFAAsF;IACtF,6EAA6E;IAC7E,8DAA8D;IAC9D,EAAE;IACF,8FAA8F;IAC9F,uFAAuF;IACvF,4CAA4C;IAC5C,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,CAAC;QACH,OAAO,MAAM,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;IACjE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,gBAAgB,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,kBAAkB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACzE,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}