@zq-silk/yui 0.6.16 → 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 (69) hide show
  1. package/dist/cli/commandCatalog.js +3 -7
  2. package/dist/cli.js +12 -33
  3. package/dist/commands/executionAuditCommands.js +19 -0
  4. package/dist/commands/globalRoleCommands.js +70 -0
  5. package/dist/commands/taskActor.js +3 -2
  6. package/dist/commands/taskCommands.js +160 -41
  7. package/dist/commands/taskContextCommand.js +1 -1
  8. package/dist/commands/taskInputCommands.js +3 -2
  9. package/dist/commands/taskRoleRuntimeStatus.js +3 -3
  10. package/dist/context/contextSnapshot.js +228 -0
  11. package/dist/context/roleSessionContext.js +3 -1
  12. package/dist/context/runContextContract.js +162 -0
  13. package/dist/context/runContextPack.js +322 -0
  14. package/dist/context/sessionBootstrapManifest.js +81 -0
  15. package/dist/context/sessionProtocolIdentity.js +23 -0
  16. package/dist/controller/agentRuntimeObserver.js +6 -1
  17. package/dist/controller/controller.js +4 -3
  18. package/dist/controller/fileSchedulerStoreAdapter.js +446 -145
  19. package/dist/controller/jobControl.js +2 -1
  20. package/dist/controller/runtime.js +83 -0
  21. package/dist/controller/runtimeHookRunFence.js +6 -2
  22. package/dist/controller/sessionOwnerReconciliation.js +5 -0
  23. package/dist/executor/agentAdapter.js +7 -2
  24. package/dist/executor/agentExecutor.js +23 -0
  25. package/dist/executor/effectiveLaunch.js +24 -0
  26. package/dist/executor/executorRegistry.js +7 -1
  27. package/dist/executor/fileRoleLaunchPlanner.js +73 -27
  28. package/dist/lifecycle/exactRunTerminalization.js +2 -3
  29. package/dist/lifecycle/providerErrorClass.js +8 -3
  30. package/dist/observability/executionAudit.js +87 -2
  31. package/dist/repository/taskWorkspacePreparer.js +2 -2
  32. package/dist/run/agentRun.js +101 -16
  33. package/dist/run/providerRetry.js +167 -56
  34. package/dist/run/providerRetryConfig.js +5 -1
  35. package/dist/run/runControlRequest.js +50 -0
  36. package/dist/runtime/agentDriver.js +47 -0
  37. package/dist/runtime/agentHost.js +327 -0
  38. package/dist/runtime/builtinAgentDrivers.js +23 -1
  39. package/dist/runtime/builtinTranscriptObserver.js +4 -0
  40. package/dist/runtime/builtinTranscriptUsage.js +2 -0
  41. package/dist/runtime/exactControlPlane.js +2 -2
  42. package/dist/runtime/globalProcessExitStore.js +38 -0
  43. package/dist/runtime/launchBroker.js +95 -0
  44. package/dist/runtime/processExitObservation.js +60 -0
  45. package/dist/runtime/runtimeBinding.js +6 -0
  46. package/dist/runtime/runtimeObservation.js +27 -6
  47. package/dist/runtime/runtimeProjection.js +6 -3
  48. package/dist/runtime/runtimeStopReceipt.js +42 -0
  49. package/dist/runtime/sessionTerminationGuard.js +13 -0
  50. package/dist/runtime/tmuxAdapters.js +203 -220
  51. package/dist/scheduler/activeRoleRunDelivery.js +24 -3
  52. package/dist/scheduler/leaderWakeupProcessor.js +18 -60
  53. package/dist/scheduler/roleRunLiveness.js +61 -27
  54. package/dist/storage/migration/productionRegistry.js +264 -0
  55. package/dist/storage/sqliteSchema.js +23 -2
  56. package/dist/storage/sqliteStore.js +39 -2
  57. package/dist/storage/taskStore.js +54 -5
  58. package/dist/storage/upgrade/recordVersions.js +3 -1
  59. package/dist/storage/upgrade/sqliteStateMigration.js +10 -0
  60. package/dist/task/taskRecordReference.js +1 -0
  61. package/dist/tmux/tmuxManager.js +15 -4
  62. package/dist/web/assets/client/components.js +1 -1
  63. package/package.json +1 -1
  64. package/skills/yui-leader/SKILL.md +10 -5
  65. package/skills/yui-operator/SKILL.md +4 -0
  66. package/skills/yui-reviewer/SKILL.md +4 -0
  67. package/skills/yui-runtime/SKILL.md +61 -0
  68. package/skills/yui-worker/SKILL.md +82 -218
  69. package/dist/executor/managedClaudeRunner.js +0 -121
@@ -5,114 +5,68 @@ description: Complete one bounded WorkItem as a native subagent or Task Role Age
5
5
 
6
6
  # Yui Worker
7
7
 
8
- Complete only the supplied bounded WorkItem. The Leader brief or managed
9
- dispatch defines the objective, Profile constraints, access, context reads,
10
- workspace, validation, and return protocol.
11
-
12
- Keep the context layers distinct: Yui Core owns durable identity, lifecycle,
13
- access, workspace, and exact handoff safety; this generic Skill owns portable
14
- Worker behavior; Agent-native Project Skills and Project Policy and Knowledge own
15
- project-specific build, test, migration, release, and review rules; and the
16
- Task Contract owns the current objective, scope, acceptance, and evidence. Do
17
- not promote a Project command or convention into generic Worker policy.
18
-
19
- Treat real models, paid APIs, shared infrastructure, production systems, real
20
- account quota, and every other non-disposable external resource as user-owned
21
- authority. A generic request to implement, test, validate, run E2E, or
22
- complete work does not grant that authority; neither do available credentials,
23
- an installed provider CLI, a Project Policy, or a test label. Unless the user
24
- proactively names the concrete real-resource validation, skip it without
25
- creating an InputRequest or blocking the WorkItem. Prefer deterministic mocks
26
- and isolated resources, then report the verification gap and an optional
27
- follow-up. An explicit request authorizes only its named resource, effect, and
28
- isolation boundary; never broaden it. A real Agent may develop or review code,
29
- but that does not authorize a real provider/model test.
30
-
31
- - Preserve supplied Task, WorkItem, Role, and Run identities.
32
- - Follow the supplied Worker Profile instructions, Skills, read/write behavior intent,
33
- model/effort request, and expected evidence. Report unsupported runtime hints
34
- instead of pretending they were applied.
35
- - Read more context only through supplied `yui task context` and Project
36
- Knowledge commands. Treat those records as authoritative and do not mutate
37
- them.
38
- - Work only inside the supplied cwd and permission root. Never create, move, or
39
- delete Yui worktrees, branches, Sessions, or storage records.
40
- - Do not dispatch other agents, change Task direction, accept WorkItems, decide
41
- conflicts, or advance an integration target.
42
- - A provider `bypass` launch removes permission prompts but does not broaden
43
- the supplied Profile, WorkItem, workspace, Project scope, or
44
- behavioral authority. Treat provider permission as process capability, not
45
- authorization to write.
46
- - An `explorer` or other read-intent Profile must not modify files. A multi-Project workspace may expose
47
- all Task Projects as context, but write work may modify only the Projects
48
- explicitly named in the WorkItem write scope.
49
- - If the brief requests a mutation while the supplied Profile is read-intent,
50
- stop and report a routing mismatch to the Leader. Do
51
- not attempt the write or relax the permission yourself.
52
- - Validate in proportion to risk. Report passed, failed, and skipped checks
53
- honestly.
54
- - A Role executes in a workspace snapshot; it does not own that workspace.
55
- Develop workspaces belong to the WorkItem, review workspaces to their
56
- ReviewRound, and integration workspaces to their IntegrationAttempt. Never
57
- use a Role-keyed lookup as proof of WorkItem ownership.
58
- - Follow the unified delivery lifecycle: isolate, yield a Candidate, inspect
59
- the independent ReviewRound workspace when requested, capture ChangeSets,
60
- integrate, accept, and explicitly clean up each owner workspace. Review
61
- edits are not ChangeSet sources.
62
- - For Project-backed delivery, commit the Develop changes and leave that
63
- workspace clean before yielding; Yui records the exact frozen HEAD in the
64
- Candidate snapshot so a later ReviewRound cannot drift with Develop.
65
- - If blocked by missing intent or a semantic conflict, stop safely and identify
66
- the exact Leader decision required.
67
- - If another Project must be modified, stop and report the Project, reason, and
68
- impact to the Leader, then yield the current Run. Do not write through its
69
- Task-main context directory or expand the WorkItem scope yourself. If the
70
- Leader approves, continue only after a new dispatch names the expanded
71
- writable Project set.
72
-
73
- ## Keep one coherent implementation round
74
-
75
- On a Leader-first fast path, keep investigation, implementation, the smallest
76
- targeted check, and ordinary finding fixes in the same WorkItem and workspace.
77
- Do not create phase handoffs or split out research and testing that have no
78
- independent result. Run the minimum check needed for the changed behavior and
79
- do not repeat an unchanged successful check. Unless the brief assigns it to
80
- this Worker, leave the Project Policy's complete delivery validation to the
81
- Leader's Integration candidate and report that it was intentionally skipped.
82
-
83
- ## Hand off the useful conclusion
84
-
85
- Your Task Message or Run yield is a collaboration summary, not a transcript.
86
- Choose information by the next reader's likely judgment or action. For an
87
- implementation handoff, lead with the user-visible behavior and explain the
88
- important mechanism, boundary, tradeoff, evidence, and residual risk; point to
89
- WorkItem/Run/Review/check records instead of pasting logs or a file-by-file
90
- diff. When acting as Reviewer or Tester, report the concrete finding or
91
- disposition, minimal reproduction or evidence reference, impact, regression
92
- boundary, and verification gap. Do not turn routine dispatch, attach,
93
- heartbeat, tool/resource sampling, waiting, or repeated no-change checks into
94
- Task Messages. Do not follow a fixed four-part template or fixed title,
95
- field, section, or character limit: adapt the abstraction and amount of detail
96
- to the recipient, and produce one summary for one semantic event.
97
-
98
- For a healthy long Run, use the supported structured checkpoint path
99
- (`yui task run checkpoint <run> --note-file -`) when there is real semantic
100
- progress; the checkpoint is runtime evidence and does not replace the final
101
- yield summary.
102
-
103
- ## Native subagent
104
-
105
- A native subagent inherits the Leader Agent and ignores Task Role Agent
106
- bindings. Follow the explicit Worker Profile embedded in the child brief. Use a
107
- model or effort override only if the native child runtime actually supports it.
108
-
109
- For each requested round, return one consolidated outcome, changed paths,
110
- decisions, checks, skipped validation, residual risk, and blockers through the
111
- native child-result mechanism. Do not run Yui lifecycle commands. Do not send
112
- routine progress handoffs, poll the Leader, accept the WorkItem, or invent a
113
- child Session or Run record. The Leader reviews
114
- the result and records the actual Profile revision, runtime model/effort,
115
- round, result, and checks in the WorkItem summary.
8
+ Follow `yui-runtime` first. For a managed Run, load its exact Context Pack and
9
+ use only the returned WorkItem, refs, workspace, writable Project IDs, and
10
+ completion actions. The launch Envelope is a pointer, not an execution brief.
11
+
12
+ Complete only the assigned bounded WorkItem. The Leader owns Task direction,
13
+ decomposition, acceptance, integration, scope expansion, and conflict
14
+ decisions. A Worker must not create or rebind Yui worktrees, Sessions, Roles,
15
+ Runs, WorkItems, ReviewRounds, or integration state.
16
+
17
+ Keep the layers distinct:
18
+
19
+ - Yui Core supplies durable identity, lifecycle, authority, workspace, and
20
+ exact handoff safety.
21
+ - This Skill supplies portable Worker behavior.
22
+ - Agent-native Project Skills plus Project Policy and Knowledge supply build,
23
+ test, migration, release, and review rules.
24
+ - The exact WorkItem and Context Snapshot supply this Run's objective, scope,
25
+ acceptance, dependencies, and evidence contract.
26
+
27
+ Do not promote a Project convention into generic Worker policy or infer Task
28
+ facts by scanning the workspace. Expand only Context refs authorized by the
29
+ pack.
30
+
31
+ ## Execute within the exact boundary
32
+
33
+ - Preserve the Task, WorkItem, Role, Run, native Session, and workspace
34
+ identities supplied by Yui.
35
+ - Follow the configured Profile's responsibilities, constraints, access
36
+ intent, Skills, and expected output. Report unsupported model or effort
37
+ hints instead of claiming they were applied.
38
+ - Work only inside the supplied cwd. A multi-Project workspace may expose
39
+ context-only Projects; modify only Projects listed as writable.
40
+ - Provider `bypass` affects process prompts, not Yui authority. It never
41
+ expands WorkItem, Profile, Project, or workspace scope.
42
+ - A read-intent Profile does not authorize writes. If the WorkItem requests a
43
+ mutation under read intent, report the routing mismatch.
44
+ - Do not dispatch another agent, accept the WorkItem, decide integration, or
45
+ alter Task-wide records.
46
+ - If another Project or broader scope is required, stop safely and report the
47
+ exact Project, reason, impact, and Leader decision needed. Continue only
48
+ after a new exact dispatch authorizes it.
49
+
50
+ For Project-backed delivery, commit the Develop workspace changes and leave it
51
+ clean before handoff so Yui can freeze the exact Candidate head. ReviewRound
52
+ workspaces are diagnostic evidence owners, never ChangeSet sources. Do not
53
+ push, publish, or use shared/production resources without explicit user
54
+ authority.
55
+
56
+ ## Validate proportionately
57
+
58
+ Keep investigation, implementation, the smallest targeted check, and ordinary
59
+ finding fixes in one coherent WorkItem round. Run checks that can catch the
60
+ changed behavior; do not repeat an unchanged successful check. Follow Project
61
+ Policy for required validation and state passed, failed, and intentionally
62
+ skipped checks honestly.
63
+
64
+ Real models, paid APIs, shared infrastructure, production systems, and account
65
+ quota remain user-owned authority. A generic request to implement or test does
66
+ not authorize them. Prefer deterministic fakes and isolated resources, and
67
+ report the remaining verification gap without blocking ordinary delivery.
68
+
69
+ ## Return a useful result
116
70
 
117
71
  A native child result is best-effort until Yui externalizes it: the result
118
72
  returns through the parent Conversation, and if that Session is lost before
@@ -124,113 +78,23 @@ native subagents never own a Yui Run, receipt, or workspace.
124
78
 
125
79
  ## Task Role AgentRun
126
80
 
127
- The managed input names the current Run ID. Before ending a managed Codex or
128
- Claude Run, execute its exact:
129
-
130
- ```sh
131
- yui task run yield <current-run-id> --summary-file - <<'YUI_SUMMARY'
132
- <outcome and evidence>
133
- YUI_SUMMARY
134
- ```
135
-
136
- Every review Run is bound to one exact frozen ReviewRound scope and a separate
137
- ReviewRound-owned writable worktree. A WorkItem ReviewRound contains its exact
138
- Candidate commit; a Task-final ReviewRound contains the committed Integration
139
- heads assigned by the Leader. Do not reinterpret one scope as the other. Native
140
- Codex or Claude bypass is process capability; the exact ReviewRound workspace
141
- and brief authorize local work. You may edit source or tests, run proportionate
142
- build/test commands, and optionally commit a diagnostic evidence commit there.
143
- Never push, integrate, mutate Task records, touch the Candidate or Worker
144
- workspace, another Task/worktree, a stable checkout, or the real Yui
145
- control-plane home.
146
-
147
- For a review Run, put the complete findings, evidence, checks actually run,
148
- uncertainty, and recommended next actions in the same `--summary-file -`
149
- heredoc. Clear Markdown is sufficient. JSON is optional; when used, known
150
- `checks` and `evidenceCommit` fields become structured evidence, while the
151
- whole report is preserved. For example:
152
-
153
- ```json
154
- {
155
- "summary": "Human review outcome and findings",
156
- "checks": [
157
- {"name": "Project-specified check", "outcome": "passed", "details": "exact result"}
158
- ],
159
- "evidenceCommit": "optional exact diagnostic commit SHA"
160
- }
161
- ```
162
-
163
- Do not invent a check merely to satisfy a schema. State which relevant checks
164
- were run and which material verification remains. Omit `evidenceCommit` when
165
- no diagnostic commit exists. The CLI validates a reported commit against the managed Review workspace; it
166
- never derives one from uncommitted bytes. A dirty no-commit workspace may
167
- yield, but must remain preserved for Leader judgment and cannot be cleaned
168
- until it is clean.
169
-
170
- Invoke the exact `yui task run yield ... --summary-file -` command directly
171
- once; do not wrap it in `until`, `while`, `sh -c`, `cd ... &&`, or another
172
- compound shell command. If the direct command is denied, report the blocker and
173
- stop instead of retrying it.
174
- The exact current-Run yield command must be the final tool action. After it
175
- succeeds, stop immediately and do not inspect, poll, accept, or perform more
176
- work in the same native turn.
177
-
178
- If you cannot finally determine success, failure, completeness, or the correct
179
- disposition, do not guess, silently stop, or hide uncertainty behind a success
180
- summary. Use the exact yield path and clearly label the handoff uncertain,
181
- incomplete, blocked, or requiring Leader judgment. Report the most complete
182
- truthful evidence available and, when applicable:
183
-
184
- - exact Run, WorkItem, and native Session identity;
185
- - actions actually performed;
186
- - changed paths and commit/worktree state;
187
- - checks actually run and their outcomes;
188
- - provider, runtime, or permission errors;
189
- - the last confirmed lifecycle boundary;
190
- - work not performed;
191
- - unresolved assumptions or decisions;
192
- - residual risks;
193
- - confidence; and
194
- - bounded next options.
195
-
196
- Permission for this exact control-plane handoff does not grant repository
197
- writes, broad Bash authority, external effects, or cross-Run control. If the
198
- exact yield is denied, do not retry, broaden permissions, use a wrapper, mutate
199
- Yui state, or invent delivery evidence. Truthfully surface the blocker through
200
- the supported provider failure boundary and stop; there is no fallback
201
- protocol.
202
-
203
- Make one bounded evidence pass: inspect the relevant change and callers, run
204
- proportionate checks, and judge the core outcome. Do not repeat successful
205
- checks, rerun an unchanged complete delivery suite, or invent extra edge-case
206
- probes without concrete defect evidence. For a WorkItem ReviewRound, inspect
207
- the exact frozen Candidate assigned to that Round. For a Task-final ReviewRound,
208
- inspect the frozen committed Integration heads as one whole and do not create a
209
- second per-WorkItem approval protocol. Once the requested evidence is
210
- sufficient, yield immediately. Invoke the exact
211
- `yui task run yield ...` command directly once; do not wrap it in `until`,
212
- `while`, `sh -c`, `cd ... &&`, or another compound command. A duplicate or late
213
- review yield is obsolete; do not retry it.
214
- If the exact direct command is denied, report that blocker and stop; do not
215
- retry through a wrapper or alternate delivery path.
216
-
217
- Include the result, changed paths, review base, optional evidence commit,
218
- checks, residual risk, blockers, and any required uncertainty evidence in the
219
- stdin summary. A final response does not deliver either provider's managed Run.
220
- Execution yield ends the AgentRun and appends an immutable Candidate to the
221
- same WorkItem. Review yield ends only
222
- its exact ReviewRound and creates no Candidate, ChangeSet, Integration source,
223
- acceptance, or completion.
224
- Yield submits immutable Run evidence and a Candidate, or Review evidence only.
225
- It never implies Leader acceptance, WorkItem completion, ChangeSet capture,
226
- Integration, or Task completion. Review Runs report findings,
227
- verification gaps, and limits;
228
- the Leader decides disposition. A missing, denied, wrong-Run,
229
- stale, or duplicate yield and StopFailure never synthesize a successful
230
- Candidate or completed ReviewRound.
231
-
232
- Leave managed workspaces intact. The Leader may route a ReviewRound evidence
233
- SHA or findings back to the original Worker, which continues in its unchanged
234
- workspace and native Session. The Leader owns review selection, Review
235
- workspace preserve/cleanup, Worker redispatch, capture, integration, and
236
- acceptance; review evidence is never merged automatically.
81
+ Summarize the outcome for the Leader's next judgment, not as a transcript or
82
+ file-by-file log. Include the observable result, important mechanism and
83
+ boundary, changed paths and commit state, checks, skipped validation, blockers,
84
+ residual risk, and bounded next action. Use a checkpoint only for material
85
+ semantic progress during a long Run; it does not replace the final handoff.
86
+
87
+ For a native subagent, return one consolidated child result through the native
88
+ child-result mechanism. Do not run Yui lifecycle commands or invent a child
89
+ Yui Session/Run.
90
+
91
+ For a managed Task Role, use only the exact completion action returned by the
92
+ Run Context Pack and follow `yui-runtime`'s direct-once/final-action rule. An
93
+ execution yield creates immutable Candidate evidence but does not accept,
94
+ capture, integrate, or complete the WorkItem. A review yield creates review
95
+ evidence only; the Leader decides disposition. If the exact handoff is denied,
96
+ stale, or mismatched, report that blocker once and stop without wrappers,
97
+ permission broadening, or another Run target.
98
+
99
+ Leave managed workspaces intact after handoff. Their owner lifecycle and
100
+ cleanup belong to the Leader and Yui Core.
@@ -1,121 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- import { constants } from "node:os";
3
- const SIGKILL_GRACE_MS = 2_000;
4
- /** The documented Claude Code stream-json user-message envelope. */
5
- export function buildManagedClaudeInput(prompt) {
6
- if (typeof prompt !== "string" || prompt.includes("\0")) {
7
- throw new TypeError("Managed Claude prompt must be text without NUL bytes.");
8
- }
9
- return `${JSON.stringify({
10
- type: "user",
11
- message: {
12
- role: "user",
13
- content: [{ type: "text", text: prompt }]
14
- }
15
- })}\n`;
16
- }
17
- /**
18
- * Runs one autonomous Claude turn without exposing the prompt in argv or
19
- * depending on terminal readiness/key timing. stdout/stderr are connected
20
- * before stdin is written, so a provider startup burst cannot deadlock the
21
- * prompt pipe. EOF makes this a finite per-Run process; native continuity is
22
- * carried by Claude's --session-id/--resume arguments.
23
- */
24
- export async function runManagedClaudeProcess(input) {
25
- const command = requireProcessToken(input.command, "Managed Claude command");
26
- const args = input.args.map((value) => requireProcessToken(value, "Managed Claude argument"));
27
- const child = spawn(command, args, {
28
- ...(input.cwd === undefined ? {} : { cwd: input.cwd }),
29
- env: input.environment ?? process.env,
30
- stdio: [
31
- "pipe",
32
- input.stdout === undefined ? "inherit" : "pipe",
33
- input.stderr === undefined ? "inherit" : "pipe"
34
- ],
35
- // Linux-only package: isolate the Provider process tree so tmux/session
36
- // cancellation cannot leave Claude tool descendants behind.
37
- detached: true
38
- });
39
- if (child.stdin === null) {
40
- child.kill();
41
- throw new Error("Managed Claude stdin pipe is unavailable.");
42
- }
43
- if (input.stdout !== undefined)
44
- child.stdout.pipe(input.stdout, { end: false });
45
- if (input.stderr !== undefined)
46
- child.stderr.pipe(input.stderr, { end: false });
47
- const signals = ["SIGINT", "SIGTERM", "SIGHUP"];
48
- const handlers = new Map();
49
- let killTimer;
50
- let terminationRequested = false;
51
- let childSettled = false;
52
- const signalProcessGroup = (signal) => {
53
- if (child.pid === undefined || child.exitCode !== null || child.signalCode !== null)
54
- return;
55
- try {
56
- process.kill(-child.pid, signal);
57
- }
58
- catch (error) {
59
- if (error.code !== "ESRCH")
60
- throw error;
61
- }
62
- };
63
- const terminateProcessGroup = (signal) => {
64
- if (terminationRequested)
65
- return;
66
- terminationRequested = true;
67
- signalProcessGroup(signal);
68
- killTimer = setTimeout(() => signalProcessGroup("SIGKILL"), SIGKILL_GRACE_MS);
69
- killTimer.unref();
70
- };
71
- for (const signal of signals) {
72
- const handler = () => terminateProcessGroup(signal);
73
- handlers.set(signal, handler);
74
- process.on(signal, handler);
75
- }
76
- try {
77
- const closed = new Promise((resolve, reject) => {
78
- child.once("error", (error) => {
79
- childSettled = true;
80
- reject(error);
81
- });
82
- child.once("close", (code, signal) => {
83
- childSettled = true;
84
- resolve({ code, signal });
85
- });
86
- });
87
- try {
88
- await new Promise((resolve, reject) => {
89
- child.stdin.once("error", reject);
90
- child.stdin.end(buildManagedClaudeInput(input.prompt), "utf8", resolve);
91
- });
92
- }
93
- catch (error) {
94
- // A failed prompt pipe is not permission to orphan a Provider process or
95
- // its tools. Terminate the whole group and wait for bounded convergence.
96
- if (!childSettled) {
97
- terminateProcessGroup("SIGTERM");
98
- await closed.catch(() => undefined);
99
- }
100
- throw error;
101
- }
102
- const result = await closed;
103
- return result.code ?? (result.signal === null ? 1 : signalExitCode(result.signal));
104
- }
105
- finally {
106
- if (killTimer !== undefined)
107
- clearTimeout(killTimer);
108
- for (const [signal, handler] of handlers)
109
- process.removeListener(signal, handler);
110
- }
111
- }
112
- function requireProcessToken(value, label) {
113
- if (typeof value !== "string" || value.length === 0 || value.includes("\0")) {
114
- throw new TypeError(`${label} must be non-empty text without NUL bytes.`);
115
- }
116
- return value;
117
- }
118
- function signalExitCode(signal) {
119
- const number = constants.signals[signal];
120
- return number === undefined ? 1 : 128 + number;
121
- }