@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.
- package/dist/cli/commandCatalog.js +3 -7
- package/dist/cli.js +12 -33
- package/dist/commands/executionAuditCommands.js +19 -0
- package/dist/commands/globalRoleCommands.js +70 -0
- package/dist/commands/taskActor.js +3 -2
- package/dist/commands/taskCommands.js +160 -41
- package/dist/commands/taskContextCommand.js +1 -1
- package/dist/commands/taskInputCommands.js +3 -2
- package/dist/commands/taskRoleRuntimeStatus.js +3 -3
- package/dist/context/contextSnapshot.js +228 -0
- package/dist/context/roleSessionContext.js +3 -1
- package/dist/context/runContextContract.js +162 -0
- package/dist/context/runContextPack.js +322 -0
- package/dist/context/sessionBootstrapManifest.js +81 -0
- package/dist/context/sessionProtocolIdentity.js +23 -0
- package/dist/controller/agentRuntimeObserver.js +6 -1
- package/dist/controller/controller.js +4 -3
- package/dist/controller/fileSchedulerStoreAdapter.js +446 -145
- package/dist/controller/jobControl.js +2 -1
- package/dist/controller/runtime.js +83 -0
- package/dist/controller/runtimeHookRunFence.js +6 -2
- package/dist/controller/sessionOwnerReconciliation.js +5 -0
- package/dist/executor/agentAdapter.js +7 -2
- package/dist/executor/agentExecutor.js +23 -0
- package/dist/executor/effectiveLaunch.js +24 -0
- package/dist/executor/executorRegistry.js +7 -1
- package/dist/executor/fileRoleLaunchPlanner.js +73 -27
- package/dist/lifecycle/exactRunTerminalization.js +2 -3
- package/dist/lifecycle/providerErrorClass.js +8 -3
- package/dist/observability/executionAudit.js +87 -2
- package/dist/repository/taskWorkspacePreparer.js +2 -2
- package/dist/run/agentRun.js +101 -16
- package/dist/run/providerRetry.js +167 -56
- package/dist/run/providerRetryConfig.js +5 -1
- package/dist/run/runControlRequest.js +50 -0
- package/dist/runtime/agentDriver.js +47 -0
- package/dist/runtime/agentHost.js +327 -0
- package/dist/runtime/builtinAgentDrivers.js +23 -1
- package/dist/runtime/builtinTranscriptObserver.js +4 -0
- package/dist/runtime/builtinTranscriptUsage.js +2 -0
- package/dist/runtime/exactControlPlane.js +2 -2
- package/dist/runtime/globalProcessExitStore.js +38 -0
- package/dist/runtime/launchBroker.js +95 -0
- package/dist/runtime/processExitObservation.js +60 -0
- package/dist/runtime/runtimeBinding.js +6 -0
- package/dist/runtime/runtimeObservation.js +27 -6
- package/dist/runtime/runtimeProjection.js +6 -3
- package/dist/runtime/runtimeStopReceipt.js +42 -0
- package/dist/runtime/sessionTerminationGuard.js +13 -0
- package/dist/runtime/tmuxAdapters.js +203 -220
- package/dist/scheduler/activeRoleRunDelivery.js +24 -3
- package/dist/scheduler/leaderWakeupProcessor.js +18 -60
- package/dist/scheduler/roleRunLiveness.js +61 -27
- package/dist/storage/migration/productionRegistry.js +264 -0
- package/dist/storage/sqliteSchema.js +23 -2
- package/dist/storage/sqliteStore.js +39 -2
- package/dist/storage/taskStore.js +54 -5
- package/dist/storage/upgrade/recordVersions.js +3 -1
- package/dist/storage/upgrade/sqliteStateMigration.js +10 -0
- package/dist/task/taskRecordReference.js +1 -0
- package/dist/tmux/tmuxManager.js +15 -4
- package/dist/web/assets/client/components.js +1 -1
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +10 -5
- package/skills/yui-operator/SKILL.md +4 -0
- package/skills/yui-reviewer/SKILL.md +4 -0
- package/skills/yui-runtime/SKILL.md +61 -0
- package/skills/yui-worker/SKILL.md +82 -218
- 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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Worker
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- Work only inside the supplied cwd
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
|
|
42
|
-
- A
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
}
|