@zq-silk/yui 2.20.0 → 2.22.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/README.md +5 -0
- package/dist/cli/commandCatalog.js +88 -28
- package/dist/cli/dynamicCompletion.js +4 -1
- package/dist/cli/helpRenderer.js +12 -1
- package/dist/cli/interactionPolicy.js +2 -0
- package/dist/cli/invocationAuthority.js +2 -6
- package/dist/cli/invocationRouter.js +5 -5
- package/dist/cli/managedDiagnostics.js +24 -16
- package/dist/cli/roleWizard.js +5 -1
- package/dist/commands/durableJobCommands.js +2 -3
- package/dist/commands/globalRoleCommands.js +33 -8
- package/dist/commands/inboxCommands.js +39 -12
- package/dist/commands/operatorCommands.js +2 -5
- package/dist/commands/releaseCommands.js +16 -2
- package/dist/commands/roleConfiguration.js +25 -2
- package/dist/commands/sessionCommands.js +5 -2
- package/dist/commands/taskCommands.js +225 -99
- package/dist/commands/taskContextCommand.js +26 -4
- package/dist/commands/taskFactCommands.js +20 -7
- package/dist/commands/taskIntegrationCommands.js +3 -3
- package/dist/commands/taskRoleRuntimeStatus.js +15 -5
- package/dist/commands/taskUsageCommand.js +2 -6
- package/dist/commands/textInput.js +2 -2
- package/dist/context/contextFamilies.js +10 -0
- package/dist/context/currentSkills.js +6 -4
- package/dist/context/runContextPack.js +44 -5
- package/dist/context/runInputContract.js +1 -1
- package/dist/context/sessionBootstrapManifest.js +7 -5
- package/dist/context/sessionSkillNotice.js +53 -0
- package/dist/context/taskCatalog.js +4 -13
- package/dist/context/taskContext.js +135 -103
- package/dist/context/taskSearch.js +3 -7
- package/dist/controlPlaneCli.js +23 -25
- package/dist/controller/agentRuntimeObserver.js +57 -12
- package/dist/controller/clientRuntime.js +37 -8
- package/dist/controller/controller.js +3 -1
- package/dist/controller/diagnosticJournal.js +10 -2
- package/dist/controller/fileSchedulerStoreAdapter.js +72 -24
- package/dist/controller/jobClient.js +2 -2
- package/dist/controller/jobControl.js +2 -2
- package/dist/controller/jobDefinitionControl.js +5 -1
- package/dist/controller/messageHealth.js +4 -3
- package/dist/controller/providerRetryAdmission.js +15 -1
- package/dist/controller/providerRetryDelivery.js +18 -2
- package/dist/controller/runtime.js +15 -5
- package/dist/controller/runtimeEventInbox.js +107 -13
- package/dist/controller/runtimeEventProcessor.js +3 -3
- package/dist/controller/taskRunRecovery.js +153 -0
- package/dist/core/controllerClient.js +16 -2
- package/dist/core/controllerServer.js +14 -5
- package/dist/core/controllerTelemetry.js +51 -5
- package/dist/errors/cliFailure.js +14 -5
- package/dist/executor/agentAdapter.js +32 -4
- package/dist/executor/agentConfigurationFields.js +2 -0
- package/dist/executor/taskAgentCapabilities.js +2 -2
- package/dist/integration/gitIntegrationService.js +3 -2
- package/dist/integration/integrationSourceApplication.js +12 -1
- package/dist/interaction/notificationPresentation.js +11 -16
- package/dist/interaction/operatorPresentation.js +1 -1
- package/dist/message/messageContinuation.js +3 -1
- package/dist/output/boundedRead.js +36 -7
- package/dist/output/rolePresentation.js +3 -1
- package/dist/runtime/agentHost.js +12 -3
- package/dist/runtime/codexAppServerRuntime.js +110 -24
- package/dist/runtime/codexInteractiveHost.js +46 -0
- package/dist/runtime/providerRetry.js +5 -2
- package/dist/runtime/providerRuntimeIdentity.js +1 -1
- package/dist/runtime/structuredProviderHost.js +32 -34
- package/dist/scheduler/wakeupQueue.js +10 -4
- package/dist/storage/sqliteSchema.js +9 -0
- package/dist/storage/storageVersions.js +1 -1
- package/dist/task/taskAuthority.js +7 -3
- package/dist/tmux/tmuxManager.js +4 -2
- package/dist/web/webSettings.js +2 -0
- package/docs/authorization.md +18 -3
- package/docs/cli-information-contract.md +245 -6
- package/docs/cli-information-contract.zh-CN.md +107 -5
- package/docs/managed-turn-and-session-runtime.md +82 -21
- package/docs/managed-turn-and-session-runtime.zh-CN.md +56 -13
- package/docs/provider-retry.md +11 -0
- package/docs/release-workflow.md +62 -0
- package/docs/release-workflow.zh-CN.md +46 -0
- package/docs/roles-and-configuration.md +28 -0
- package/docs/roles-and-configuration.zh-CN.md +21 -0
- package/docs/storage-baseline.md +4 -1
- package/docs/storage-baseline.zh-CN.md +1 -1
- package/docs/task-delivery.md +7 -0
- package/docs/task-delivery.zh-CN.md +5 -0
- package/docs/task-discovery.md +5 -5
- package/docs/task-discovery.zh-CN.md +4 -4
- package/docs/testing/review-evaluation.md +7 -7
- package/docs/testing/review-evaluation.zh-CN.md +7 -7
- package/docs/testing/verification-levels.md +45 -2
- package/docs/testing/verification-levels.zh-CN.md +21 -2
- package/i18n/README.zh-CN.md +6 -0
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +98 -189
- package/skills/yui-leader/VERSION +1 -1
- package/skills/yui-leader/references/artifacts.md +41 -0
- package/skills/yui-leader/references/assignment-execution.md +140 -0
- package/skills/yui-leader/references/completion.md +79 -0
- package/skills/yui-leader/references/delivery-scope.md +26 -0
- package/skills/yui-leader/references/execution.md +16 -487
- package/skills/yui-leader/references/implementation.md +81 -0
- package/skills/yui-leader/references/planning.md +7 -45
- package/skills/yui-leader/references/review.md +90 -0
- package/skills/yui-leader/references/task-progress.md +23 -0
- package/skills/yui-leader/references/work-allocation.md +118 -0
- package/skills/yui-operator/SKILL.md +77 -331
- package/skills/yui-operator/VERSION +1 -1
- package/skills/yui-operator/references/body-transport.md +62 -0
- package/skills/yui-operator/references/configuration.md +47 -0
- package/skills/yui-operator/references/lifecycle.md +41 -0
- package/skills/yui-operator/references/progress.md +39 -0
- package/skills/yui-operator/references/routing.md +57 -0
- package/skills/yui-operator/references/submission.md +56 -0
- package/skills/yui-operator/references/task-delivery.md +5 -2
- package/skills/yui-operator/references/web-lifecycle.md +19 -0
- package/skills/yui-operator/scripts/verify-submission.mjs +37 -0
- package/skills/yui-reviewer/SKILL.md +4 -2
- package/skills/yui-reviewer/VERSION +1 -1
- package/skills/yui-runtime/SKILL.md +177 -505
- package/skills/yui-runtime/VERSION +1 -1
- package/skills/yui-runtime/references/archive.md +51 -0
- package/skills/yui-runtime/references/command-discovery.md +41 -0
- package/skills/yui-runtime/references/completed-followup.md +65 -0
- package/skills/yui-runtime/references/context-ordering.md +3 -34
- package/skills/yui-runtime/references/context-reads.md +61 -0
- package/skills/yui-runtime/references/dispatched-run.md +61 -0
- package/skills/yui-runtime/references/execution-failure.md +105 -0
- package/skills/yui-runtime/references/global-context.md +18 -0
- package/skills/yui-runtime/references/global-input-controls.md +44 -0
- package/skills/yui-runtime/references/host-custody.md +30 -0
- package/skills/yui-runtime/references/inbox-recovery.md +77 -0
- package/skills/yui-runtime/references/incremental-context.md +40 -0
- package/skills/yui-runtime/references/publication.md +4 -104
- package/skills/yui-runtime/references/recovery.md +32 -192
- package/skills/yui-runtime/references/session-identity.md +18 -0
- package/skills/yui-runtime/references/session-replacement.md +45 -0
- package/skills/yui-runtime/references/uncertain-execution.md +29 -0
- package/skills/yui-worker/SKILL.md +7 -4
- package/skills/yui-worker/VERSION +1 -1
|
@@ -9,6 +9,8 @@ import { nonReplayableMessageWake, isLeaderSteer, pinMessageRevisions, releasedN
|
|
|
9
9
|
import { hasRuntimeCleanupObligation, runtimeLifecycleTarget } from "../runtime/lifecycleReservation.js";
|
|
10
10
|
import { isTaskRecordRetired, retiredTaskRecordIds } from "../task/taskRecordRetirement.js";
|
|
11
11
|
import { blocksInboxOrder, inboxEntryCategory, inboxSettled } from "../message/inboxTurn.js";
|
|
12
|
+
import { recoveredMessageContinuation } from "../controller/taskRunRecovery.js";
|
|
13
|
+
import { taskWakeInspectionCommand } from "./taskCommands.js";
|
|
12
14
|
const target = (address) => ({ kind: "role", taskId: address.taskId, roleName: address.roleName });
|
|
13
15
|
const source = (address) => `inbox:${address.scope}:${address.taskId ?? ""}:${address.roleName}`;
|
|
14
16
|
const pendingId = (pending) => `pending-${readDigest(pending)}`;
|
|
@@ -38,6 +40,16 @@ function currentTurn(store, address) {
|
|
|
38
40
|
return binding?.conversations.find(c => c.epoch === binding.currentConversationEpoch)?.conversationId === address.nativeSessionId
|
|
39
41
|
? binding?.run : undefined;
|
|
40
42
|
}
|
|
43
|
+
function isRecoveredMessage(store, address, entry) {
|
|
44
|
+
if (address.scope !== "task" || address.runId === undefined || isWake(entry))
|
|
45
|
+
return false;
|
|
46
|
+
const run = store.getRun(address.taskId, address.runId);
|
|
47
|
+
return run !== null && recoveredMessageContinuation(store, entry, run);
|
|
48
|
+
}
|
|
49
|
+
function entryCategory(store, address, entry) {
|
|
50
|
+
return isRecoveredMessage(store, address, entry) ? "current"
|
|
51
|
+
: inboxEntryCategory(entry, address, currentTurn(store, address));
|
|
52
|
+
}
|
|
41
53
|
function ownsMessage(store, address, message) {
|
|
42
54
|
if (address.roleName === "leader" && message.taskId === address.taskId && isLeaderSteer(message))
|
|
43
55
|
return true;
|
|
@@ -138,7 +150,8 @@ function blocker(store, address, entry) {
|
|
|
138
150
|
}
|
|
139
151
|
else {
|
|
140
152
|
const message = entry;
|
|
141
|
-
if (message.continuation?.runId !== undefined && message.continuation.runId !== address.runId
|
|
153
|
+
if (message.continuation?.runId !== undefined && message.continuation.runId !== address.runId
|
|
154
|
+
&& !isRecoveredMessage(store, address, message)) {
|
|
142
155
|
return "continuation-already-dispatched";
|
|
143
156
|
}
|
|
144
157
|
if (!accepted && message.inputControl?.expectedSessionId !== undefined
|
|
@@ -163,7 +176,7 @@ function checkMutation(store, address) {
|
|
|
163
176
|
}
|
|
164
177
|
function summary(store, address, entry) {
|
|
165
178
|
return { id: entry.id, kind: isWake(entry) ? "notification-window" : "message",
|
|
166
|
-
category:
|
|
179
|
+
category: entryCategory(store, address, entry),
|
|
167
180
|
createdAt: entry.createdAt, summary: summaryText(isWake(entry) ? entry.reasons.join(", ") : entry.body),
|
|
168
181
|
blocked: blocker(store, address, entry) ?? null, inbox: summaryMetadata(entry.inbox ?? null),
|
|
169
182
|
handling: inboxHandlingState(entry.inbox),
|
|
@@ -178,9 +191,14 @@ function summary(store, address, entry) {
|
|
|
178
191
|
read: `yui inbox show ${entry.id}`, ...(isWake(entry)
|
|
179
192
|
? { originals: `yui task wake show ${entry.taskId} ${entry.id} --json` } : {}) };
|
|
180
193
|
}
|
|
181
|
-
function receipt(entry) {
|
|
194
|
+
function receipt(entry, requestedId) {
|
|
195
|
+
// Pending-window inspection has no fixed originals yet. An existing wake
|
|
196
|
+
// can already have been read completely through inbox show; offer refresh
|
|
197
|
+
// without implying that claim invalidated those bodies or proved a read.
|
|
198
|
+
const originalRead = isWake(entry)
|
|
199
|
+
? { [requestedId.startsWith("pending-") ? "originals" : "refreshOriginals"]: `yui task wake show ${entry.taskId} ${entry.id} --json` } : {};
|
|
182
200
|
return { id: entry.id, inbox: entry.inbox,
|
|
183
|
-
...
|
|
201
|
+
...originalRead };
|
|
184
202
|
}
|
|
185
203
|
/** Own-address command: there is deliberately no --role, --task or --session.
|
|
186
204
|
* Reads do not claim. Exact claim precedes semantic handling; exact ack follows
|
|
@@ -198,8 +216,7 @@ export function runInboxCommand(args, store, env, now = new Date()) {
|
|
|
198
216
|
const selected = address.scope === "global" ? pendingGlobalInboxMessages(store.listGlobalRoleMessages(address.roleName))
|
|
199
217
|
: entries(store, address).filter(entry => (isWake(entry) || !retired.has(entry.id))
|
|
200
218
|
&& !inboxSettled(entry.inbox));
|
|
201
|
-
const
|
|
202
|
-
const categories = selected.map(entry => ({ entry, category: inboxEntryCategory(entry, address, turn) }));
|
|
219
|
+
const categories = selected.map(entry => ({ entry, category: entryCategory(store, address, entry) }));
|
|
203
220
|
const rank = { current: 0, available: 1, history: 2 };
|
|
204
221
|
categories.sort((a, b) => rank[a.category] - rank[b.category]);
|
|
205
222
|
const items = categories.filter(item => view === "all"
|
|
@@ -230,7 +247,17 @@ export function runInboxCommand(args, store, env, now = new Date()) {
|
|
|
230
247
|
note: "Claim this exact window before processing; claim returns its durable wake and original-read command." }, `${source(address)}/${id}`, parsed.cursor);
|
|
231
248
|
}
|
|
232
249
|
const entry = getEntry(store, address, id);
|
|
233
|
-
|
|
250
|
+
if (isWake(entry)) {
|
|
251
|
+
// Own-inbox authorization above remains the boundary. Reuse the existing
|
|
252
|
+
// bounded focused originals rather than reconstructing a second view or
|
|
253
|
+
// making a claim mutation depend on a subsequent read succeeding.
|
|
254
|
+
const focused = taskWakeInspectionCommand(["show", entry.taskId, entry.id], store);
|
|
255
|
+
if (focused.kind !== "output")
|
|
256
|
+
throw new Error("Wake inspection did not return a read result.");
|
|
257
|
+
const { wake: _wake, ...originalContext } = focused.data;
|
|
258
|
+
return boundedDocument({ ...entry, originalContext }, `${source(address)}/${id}`, parsed.cursor);
|
|
259
|
+
}
|
|
260
|
+
const value = address.scope === "task"
|
|
234
261
|
? expandTaskMessageResult(entry, (task, run) => store.getRun(task, run)) : entry;
|
|
235
262
|
return boundedDocument(value, `${source(address)}/${id}`, parsed.cursor);
|
|
236
263
|
}
|
|
@@ -262,7 +289,7 @@ export function runInboxCommand(args, store, env, now = new Date()) {
|
|
|
262
289
|
if (existing.inboxPendingId !== id) {
|
|
263
290
|
throw new Error("Inbox request id was reused for a different window.");
|
|
264
291
|
}
|
|
265
|
-
return receipt(existing);
|
|
292
|
+
return receipt(existing, id);
|
|
266
293
|
}
|
|
267
294
|
const mailbox = tx.getWorkMailbox(target(current));
|
|
268
295
|
if (!mailbox?.pending || pendingId(mailbox.pending) !== id)
|
|
@@ -310,7 +337,7 @@ export function runInboxCommand(args, store, env, now = new Date()) {
|
|
|
310
337
|
if (saved.requestId !== requestId || saved.reason !== reason || !sameSession(saved.actor, current)) {
|
|
311
338
|
throw new Error("Conflicting retirement; original disposition retained.");
|
|
312
339
|
}
|
|
313
|
-
return receipt(entry);
|
|
340
|
+
return receipt(entry, id);
|
|
314
341
|
}
|
|
315
342
|
// A retained attempt in an older conversation is still evidence of
|
|
316
343
|
// submission; changing the active Session cannot erase that boundary.
|
|
@@ -336,7 +363,7 @@ export function runInboxCommand(args, store, env, now = new Date()) {
|
|
|
336
363
|
throw new Error("Claim belongs to a previous Session; read the original and prior effects, then explicitly acknowledge only after finishing its handling.");
|
|
337
364
|
if (entry.inbox.claim.requestId !== requestId)
|
|
338
365
|
throw new Error("Entry already claimed; retain the original request id.");
|
|
339
|
-
return receipt(entry);
|
|
366
|
+
return receipt(entry, id);
|
|
340
367
|
}
|
|
341
368
|
const blocked = blocker(tx, current, entry);
|
|
342
369
|
if (blocked !== undefined)
|
|
@@ -398,7 +425,7 @@ export function runInboxCommand(args, store, env, now = new Date()) {
|
|
|
398
425
|
if (entry.inbox.ack.requestId !== requestId || entry.inbox.ack.reason !== reason
|
|
399
426
|
|| !sameSession(entry.inbox.ack.actor, current))
|
|
400
427
|
throw new Error("Conflicting acknowledgement; original disposition retained.");
|
|
401
|
-
return receipt(entry);
|
|
428
|
+
return receipt(entry, id);
|
|
402
429
|
}
|
|
403
430
|
const inbox = { ...entry.inbox,
|
|
404
431
|
ack: { requestId, actor: current, at: now.toISOString(), reason: reason } };
|
|
@@ -415,7 +442,7 @@ export function runInboxCommand(args, store, env, now = new Date()) {
|
|
|
415
442
|
}
|
|
416
443
|
}
|
|
417
444
|
save(tx, current, entry);
|
|
418
|
-
return receipt(entry);
|
|
445
|
+
return receipt(entry, id);
|
|
419
446
|
});
|
|
420
447
|
if (ids.length === 1)
|
|
421
448
|
return apply(ids[0]);
|
|
@@ -136,11 +136,8 @@ function submit(rest, store, options) {
|
|
|
136
136
|
if (requestId !== undefined && requestId.length === 0) {
|
|
137
137
|
throw usageError("--request-id is required.", usage);
|
|
138
138
|
}
|
|
139
|
-
const body = readCommandText(positionals[0], bodyFile, "--body", usage);
|
|
140
|
-
return
|
|
141
|
-
kind: "output",
|
|
142
|
-
output: submitOperatorMessage(body, taskId, store, options, intent, requestId)
|
|
143
|
-
};
|
|
139
|
+
const body = readCommandText(positionals[0], bodyFile, "--body", usage, { preserveFileWhitespace: true });
|
|
140
|
+
return submitOperatorMessage(body, taskId, store, options, intent, requestId);
|
|
144
141
|
}
|
|
145
142
|
function listSessions(args, store, options) {
|
|
146
143
|
if (args.length !== 0)
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { spawn, spawnSync } from "node:child_process";
|
|
6
6
|
import { chmodSync, cpSync, existsSync, lstatSync, mkdirSync, readdirSync, rmSync, } from "node:fs";
|
|
7
7
|
import { join, resolve } from "node:path";
|
|
8
|
+
import { pathToFileURL } from "node:url";
|
|
8
9
|
import { callController, ControllerClientError } from "../core/controllerClient.js";
|
|
9
10
|
import { processGenerationIsLive } from "../core/fileLockOwner.js";
|
|
10
11
|
import { activateRelease, ControllerStartUnconfirmedError } from "../release/releaseHandover.js";
|
|
@@ -346,10 +347,23 @@ export function createReleaseActivatePorts(overrides = {}) {
|
|
|
346
347
|
}
|
|
347
348
|
}),
|
|
348
349
|
runPreflight: overrides.runPreflight ?? ((releaseDir, home) => {
|
|
349
|
-
|
|
350
|
+
assertReleaseIsNotWorktreeOrLinked(releaseDir);
|
|
351
|
+
const manifest = verifyReleaseIntegrity(releaseDir);
|
|
352
|
+
if (resolve(releaseDir) !== resolve(releaseDirectoryFor(home, manifest))
|
|
353
|
+
|| !hasMatchingSmokeReceipt(releaseDir, manifest)) {
|
|
354
|
+
throw new Error("Release preflight requires this Home's verified installed target and matching smoke receipt.");
|
|
355
|
+
}
|
|
350
356
|
// The target owns current-record and database integrity validation.
|
|
351
357
|
// Activation never migrates; a valid but older Home still blocks here.
|
|
352
|
-
|
|
358
|
+
// Invoke its read-only primitive, not an ordinary inactive CLI command:
|
|
359
|
+
// the Home's CLI fence must remain closed until handover completes.
|
|
360
|
+
const module = pathToFileURL(join(releaseDir, "dist", "storage", "upgrade", "upgradeOrchestrator.js")).href;
|
|
361
|
+
const result = spawnSync(process.execPath, ["--input-type=module", "-e", `
|
|
362
|
+
const { runStorageUpgrade } = await import(process.argv[1]);
|
|
363
|
+
const data = await runStorageUpgrade({ home: process.argv[2], mode: "update-preflight" });
|
|
364
|
+
process.stdout.write(JSON.stringify({ ok: true, data }));
|
|
365
|
+
process.exitCode = data.outcome === "update-preflight" ? 0 : 5;
|
|
366
|
+
`, module, home], {
|
|
353
367
|
env: { ...process.env, YUI_HOME: home, NO_COLOR: "1" },
|
|
354
368
|
encoding: "utf8",
|
|
355
369
|
timeout: 60_000
|
|
@@ -24,6 +24,8 @@ const AGENT_VALUE_OPTIONS = [
|
|
|
24
24
|
["--permission-strategy", "value"],
|
|
25
25
|
["--sandbox", "value"],
|
|
26
26
|
["--approval", "value"],
|
|
27
|
+
["--exclude-tmpdir-env-var", "value"],
|
|
28
|
+
["--exclude-slash-tmp", "value"],
|
|
27
29
|
["--permission-mode", "value"],
|
|
28
30
|
["--search", "value"]
|
|
29
31
|
];
|
|
@@ -37,6 +39,8 @@ const AGENT_CLEAR_OPTIONS = [
|
|
|
37
39
|
["--clear-allowed-tools", "flag"],
|
|
38
40
|
["--clear-disallowed-tools", "flag"],
|
|
39
41
|
["--clear-search", "flag"],
|
|
42
|
+
["--clear-exclude-tmpdir-env-var", "flag"],
|
|
43
|
+
["--clear-exclude-slash-tmp", "flag"],
|
|
40
44
|
["--clear-agent-config", "flag"]
|
|
41
45
|
];
|
|
42
46
|
const AGENT_CONFIG_OPTIONS = new Set([
|
|
@@ -196,6 +200,8 @@ function permissionPatch(binding, parsed) {
|
|
|
196
200
|
: undefined;
|
|
197
201
|
const nativeOptions = [
|
|
198
202
|
"--sandbox", "--approval", "--permission-mode",
|
|
203
|
+
"--exclude-tmpdir-env-var", "--exclude-slash-tmp",
|
|
204
|
+
"--clear-exclude-tmpdir-env-var", "--clear-exclude-slash-tmp",
|
|
199
205
|
"--allowed-tool", "--clear-allowed-tools",
|
|
200
206
|
"--disallowed-tool", "--clear-disallowed-tools"
|
|
201
207
|
].some((option) => parsed.has(option));
|
|
@@ -219,6 +225,19 @@ function permissionPatch(binding, parsed) {
|
|
|
219
225
|
permission.sandbox = requiredText(parsed.one("--sandbox"));
|
|
220
226
|
if (parsed.has("--approval"))
|
|
221
227
|
permission.approval = requiredText(parsed.one("--approval"));
|
|
228
|
+
for (const [option, key] of [
|
|
229
|
+
["exclude-tmpdir-env-var", "excludeTmpdirEnvVar"],
|
|
230
|
+
["exclude-slash-tmp", "excludeSlashTmp"]
|
|
231
|
+
]) {
|
|
232
|
+
if (parsed.has(`--${option}`)) {
|
|
233
|
+
const value = parsed.one(`--${option}`);
|
|
234
|
+
if (value !== "true" && value !== "false")
|
|
235
|
+
throw usageError(`--${option} requires true or false.`);
|
|
236
|
+
permission[key] = value === "true";
|
|
237
|
+
}
|
|
238
|
+
if (parsed.has(`--clear-${option}`))
|
|
239
|
+
delete permission[key];
|
|
240
|
+
}
|
|
222
241
|
}
|
|
223
242
|
else if (binding.adapterId === "acp") {
|
|
224
243
|
// An ACP Session's configured permission is exactly one mode id, matched
|
|
@@ -263,7 +282,9 @@ function assertAgentOptionConflicts(parsed) {
|
|
|
263
282
|
["--effort", "--clear-effort"],
|
|
264
283
|
["--allowed-tool", "--clear-allowed-tools"],
|
|
265
284
|
["--disallowed-tool", "--clear-disallowed-tools"],
|
|
266
|
-
["--search", "--clear-search"]
|
|
285
|
+
["--search", "--clear-search"],
|
|
286
|
+
["--exclude-tmpdir-env-var", "--clear-exclude-tmpdir-env-var"],
|
|
287
|
+
["--exclude-slash-tmp", "--clear-exclude-slash-tmp"]
|
|
267
288
|
]);
|
|
268
289
|
if (parsed.has("--clear-agent-config")
|
|
269
290
|
&& [...parsed.seen].some((option) => option !== "--clear-agent-config" && AGENT_CONFIG_OPTIONS.has(option))) {
|
|
@@ -271,7 +292,9 @@ function assertAgentOptionConflicts(parsed) {
|
|
|
271
292
|
}
|
|
272
293
|
}
|
|
273
294
|
function assertAdapterOptions(adapterId, parsed) {
|
|
274
|
-
const codex = ["--sandbox", "--approval", "--search", "--clear-search"
|
|
295
|
+
const codex = ["--sandbox", "--approval", "--search", "--clear-search",
|
|
296
|
+
"--exclude-tmpdir-env-var", "--exclude-slash-tmp",
|
|
297
|
+
"--clear-exclude-tmpdir-env-var", "--clear-exclude-slash-tmp"];
|
|
275
298
|
const tools = [
|
|
276
299
|
"--allowed-tool", "--clear-allowed-tools",
|
|
277
300
|
"--disallowed-tool", "--clear-disallowed-tools"
|
|
@@ -27,7 +27,10 @@ export async function runSessionStopCommand(input) {
|
|
|
27
27
|
// Leader dispatch. The explicit full pass settles pending runtime inbox and
|
|
28
28
|
// lifecycle work that may exist without a current Session candidate.
|
|
29
29
|
await input.runtime.drainController();
|
|
30
|
-
await input.runtime.stopController();
|
|
30
|
+
const stoppedController = await input.runtime.stopController();
|
|
31
|
+
if (stoppedController.stopped !== true && stoppedController.alreadyStopped !== true) {
|
|
32
|
+
throw new Error("Controller stop was not confirmed; no Session was stopped.");
|
|
33
|
+
}
|
|
31
34
|
// Re-read the authoritative facts after the drain because a AgentRun that was
|
|
32
35
|
// already inside a pass may have changed state meanwhile.
|
|
33
36
|
const settled = input.runtime.snapshot();
|
|
@@ -80,7 +83,7 @@ function blockedSessions(input) {
|
|
|
80
83
|
});
|
|
81
84
|
}
|
|
82
85
|
function blockedStopResult(blocked) {
|
|
83
|
-
const details = blocked.map(({ session }) => (`- ${renderSessionOwner(session)} (an active AgentRun or lifecycle operation is still pending)`));
|
|
86
|
+
const details = blocked.map(({ session }) => (`- ${renderSessionOwner(session)} (native execution, an active AgentRun or lifecycle operation is still pending)`));
|
|
84
87
|
return {
|
|
85
88
|
output: [
|
|
86
89
|
`Cannot stop managed Sessions: ${blocked.length} Session(s) are still busy.`,
|