@lucascouts/claude-agent-acp-plus 0.27.0 → 0.29.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/acp-agent.d.ts +80 -28
- package/dist/acp-agent.d.ts.map +1 -1
- package/dist/acp-agent.js +303 -74
- package/dist/tools.d.ts +8 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +73 -13
- package/dist/ultracode.d.ts +138 -72
- package/dist/ultracode.d.ts.map +1 -1
- package/dist/ultracode.js +208 -75
- package/dist/usage-markdown.d.ts.map +1 -1
- package/dist/usage-markdown.js +57 -0
- package/package.json +1 -1
package/dist/acp-agent.js
CHANGED
|
@@ -19,7 +19,7 @@ import { filterSupersededModels } from "./model-recency.js";
|
|
|
19
19
|
import { SettingsManager } from "./settings.js";
|
|
20
20
|
import { ContextCompactionLifecycle, contextCompactionMetadataFromBoundary, } from "./context-compaction.js";
|
|
21
21
|
import { createThinkingConfigOption, effectiveThinkingConfig, resolveThinkingSelection, THINKING_CONFIG_ID, } from "./thinking-option.js";
|
|
22
|
-
import {
|
|
22
|
+
import { applyLegacyUltracodeEffort, applyUltracodeReadback, applyUltracodeToggle, effortFlagSettings, isLegacyUltracodeEffort, isUltracodeAvailable, readUltracodeState, resolveUltracodeRequested, ULTRACODE_CONFIG_ID, ultracodeConfigOption, } from "./ultracode.js";
|
|
23
23
|
import { handleRewindCommand, parseRewindInvocation } from "./rewind-command.js";
|
|
24
24
|
import { resolvePermissionMode, sessionAllowsBypass } from "./permissions/modes.js";
|
|
25
25
|
import { normalizeDurablePermissionChangeSet } from "./permissions/normalization.js";
|
|
@@ -174,6 +174,14 @@ export const USAGE_CAPABILITY_VERSION = 1;
|
|
|
174
174
|
* and a sample most of an interval old is exactly what the poll already
|
|
175
175
|
* showed them. */
|
|
176
176
|
export const USAGE_REFRESH_MAX_SAMPLE_AGE_MS = 5_000;
|
|
177
|
+
/** Parity item 106 (upstream issue #1284): how long a turn held for its
|
|
178
|
+
* background subagents (see `Turn.deferredSettle`) waits, once none of them is
|
|
179
|
+
* live and Claude Code is idle, for the followup cycle a task_notification
|
|
180
|
+
* would start. A notification that is lost starts none, and with no further
|
|
181
|
+
* idle nothing else would ever answer the prompt. A followup starts within
|
|
182
|
+
* milliseconds of its notification (the CLI flushes them together), so the
|
|
183
|
+
* bound only ever expires on a lost one. */
|
|
184
|
+
export const HELD_TURN_DRAIN_GRACE_MS = 5_000;
|
|
177
185
|
/** The SDK's own text for a rejected control request, passed through to the
|
|
178
186
|
* client as the internal error's message (R2.4). */
|
|
179
187
|
function errorMessage(error) {
|
|
@@ -284,7 +292,11 @@ export function quotaPollIntervalMs(raw = process.env.CLAUDE_ACP_QUOTA_POLL_MS)
|
|
|
284
292
|
* (the result is skipped, its trailing idle absorbed as owed, so the
|
|
285
293
|
* #825 detector can't fire); misrouting an autonomous result into the
|
|
286
294
|
* user lane is the bounded misattribution class this set exists to
|
|
287
|
-
* reduce.
|
|
295
|
+
* reduce.
|
|
296
|
+
*
|
|
297
|
+
* Exception: a result from one of these origins that names a pending prompt
|
|
298
|
+
* in `user_message_uuids` consumed that folded prompt and takes the user
|
|
299
|
+
* lane (see the result handler). */
|
|
288
300
|
const AUTONOMOUS_RESULT_ORIGINS = new Set([
|
|
289
301
|
"task-notification",
|
|
290
302
|
"peer",
|
|
@@ -2221,6 +2233,40 @@ export class ClaudeAcpAgent {
|
|
|
2221
2233
|
};
|
|
2222
2234
|
/** The unsettled in-flight turn owning this prompt uuid, if any. */
|
|
2223
2235
|
const findUnsettledTurn = (uuid) => (session.turnQueue ?? []).find((t) => t.promptUuid === uuid && !t.settled);
|
|
2236
|
+
/** Whether this result is the answer to a prompt that is still waiting.
|
|
2237
|
+
*
|
|
2238
|
+
* Claude Code can start a turn on its own, for example when a background
|
|
2239
|
+
* task finishes. If the user sends a prompt while that turn runs, Claude
|
|
2240
|
+
* Code adds the prompt to the running turn. The turn's result is still
|
|
2241
|
+
* marked as a background result, but it lists the uuids of the prompts it
|
|
2242
|
+
* answered.
|
|
2243
|
+
*
|
|
2244
|
+
* A turn held open for its background subagents already has its result,
|
|
2245
|
+
* so a result that names it does not answer it. */
|
|
2246
|
+
const answersPendingPrompt = (message) => {
|
|
2247
|
+
// Newer CLIs list every prompt the turn answered. Older ones name only
|
|
2248
|
+
// the last one.
|
|
2249
|
+
let answeredPromptUuids = [];
|
|
2250
|
+
if (Array.isArray(message.user_message_uuids)) {
|
|
2251
|
+
answeredPromptUuids = message.user_message_uuids;
|
|
2252
|
+
}
|
|
2253
|
+
else if (typeof message.user_message_uuid === "string") {
|
|
2254
|
+
answeredPromptUuids = [message.user_message_uuid];
|
|
2255
|
+
}
|
|
2256
|
+
for (const promptUuid of answeredPromptUuids) {
|
|
2257
|
+
const turn = findUnsettledTurn(promptUuid);
|
|
2258
|
+
if (turn === undefined) {
|
|
2259
|
+
// Not a prompt of this session, or it was answered already.
|
|
2260
|
+
continue;
|
|
2261
|
+
}
|
|
2262
|
+
if (isHeldOpen(turn)) {
|
|
2263
|
+
// This turn already has its result and only waits for its subagents.
|
|
2264
|
+
continue;
|
|
2265
|
+
}
|
|
2266
|
+
return true;
|
|
2267
|
+
}
|
|
2268
|
+
return false;
|
|
2269
|
+
};
|
|
2224
2270
|
/** The first queued turn still awaiting its outcome, if any — the single
|
|
2225
2271
|
* spelling of "a prompt is pending" shared by the head promotion and
|
|
2226
2272
|
* the autonomous stretch-close guard. */
|
|
@@ -2291,6 +2337,34 @@ export class ClaudeAcpAgent {
|
|
|
2291
2337
|
* while true, the turn's settlement stays deferred so the subagent's
|
|
2292
2338
|
* output and permission requests land inside it (see
|
|
2293
2339
|
* Turn.deferredSettle). */
|
|
2340
|
+
/** Ends the display terminal of a command that went to the background,
|
|
2341
|
+
* once its task ends (see `Session.backgroundTerminals`). The code is the
|
|
2342
|
+
* one Claude Code's summary names, else 1 for a failed or stopped task —
|
|
2343
|
+
* a known failure never goes out as null — and null for a completion
|
|
2344
|
+
* that names none. */
|
|
2345
|
+
const endBackgroundTerminal = async (taskId, exitCode) => {
|
|
2346
|
+
const terminal = session.backgroundTerminals?.get(taskId);
|
|
2347
|
+
if (!terminal)
|
|
2348
|
+
return;
|
|
2349
|
+
session.backgroundTerminals.delete(taskId);
|
|
2350
|
+
await sendUpdate({
|
|
2351
|
+
sessionId: params.sessionId,
|
|
2352
|
+
update: {
|
|
2353
|
+
sessionUpdate: "tool_call_update",
|
|
2354
|
+
toolCallId: terminal.toolCallId,
|
|
2355
|
+
_meta: {
|
|
2356
|
+
...(terminal.parentToolUseId
|
|
2357
|
+
? { claudeCode: { parentToolUseId: terminal.parentToolUseId } }
|
|
2358
|
+
: {}),
|
|
2359
|
+
terminal_exit: {
|
|
2360
|
+
terminal_id: terminal.toolCallId,
|
|
2361
|
+
exit_code: exitCode,
|
|
2362
|
+
signal: null,
|
|
2363
|
+
},
|
|
2364
|
+
},
|
|
2365
|
+
},
|
|
2366
|
+
});
|
|
2367
|
+
};
|
|
2294
2368
|
const turnAwaitingSubagents = (turn) => {
|
|
2295
2369
|
if (!turn.spawnedTaskIds?.size) {
|
|
2296
2370
|
return false;
|
|
@@ -2318,6 +2392,33 @@ export class ClaudeAcpAgent {
|
|
|
2318
2392
|
settleActive(turn.deferredSettle);
|
|
2319
2393
|
}
|
|
2320
2394
|
};
|
|
2395
|
+
/** Item 106: arms the drain grace (see `HELD_TURN_DRAIN_GRACE_MS`) when a
|
|
2396
|
+
* prune leaves the held turn with no live subagent while Claude Code is
|
|
2397
|
+
* idle — the state in which a lost task_notification parks the turn. At
|
|
2398
|
+
* expiry the turn settles only if nothing moved: same turn, still held,
|
|
2399
|
+
* still drained, still idle. A followup that started meanwhile (state
|
|
2400
|
+
* `running`) settles the turn itself at its result or idle. */
|
|
2401
|
+
let drainGrace;
|
|
2402
|
+
const armDrainGrace = () => {
|
|
2403
|
+
const turn = session.activeTurn;
|
|
2404
|
+
if (drainGrace !== undefined ||
|
|
2405
|
+
!isHeldOpen(turn) ||
|
|
2406
|
+
turnAwaitingSubagents(turn) ||
|
|
2407
|
+
session.lastSessionState !== "idle") {
|
|
2408
|
+
return;
|
|
2409
|
+
}
|
|
2410
|
+
drainGrace = setTimeout(() => {
|
|
2411
|
+
drainGrace = undefined;
|
|
2412
|
+
if (session.activeTurn === turn &&
|
|
2413
|
+
isHeldOpen(turn) &&
|
|
2414
|
+
!turnAwaitingSubagents(turn) &&
|
|
2415
|
+
session.lastSessionState === "idle") {
|
|
2416
|
+
this.logger.log(`[held-turn] settled after the drain grace: no followup came (task_notification lost?) session=${params.sessionId}`);
|
|
2417
|
+
settleDeferredIfDrained();
|
|
2418
|
+
}
|
|
2419
|
+
}, HELD_TURN_DRAIN_GRACE_MS);
|
|
2420
|
+
drainGrace.unref?.();
|
|
2421
|
+
};
|
|
2321
2422
|
/** Settle the active turn with `outcome` now — unless subagents it
|
|
2322
2423
|
* spawned are still live, in which case store the outcome and hold the
|
|
2323
2424
|
* turn open (see Turn.deferredSettle). Every result-time settle of a
|
|
@@ -3270,6 +3371,8 @@ export class ClaudeAcpAgent {
|
|
|
3270
3371
|
// The task settled — no further tool calls can originate
|
|
3271
3372
|
// from it, so its registry entry can be dropped.
|
|
3272
3373
|
session.liveBackgroundTasks.delete(message.task_id);
|
|
3374
|
+
await endBackgroundTerminal(message.task_id, backgroundExitCode(message.status, message.summary));
|
|
3375
|
+
armDrainGrace();
|
|
3273
3376
|
if (session.taskFeed && session.taskFeedPublisher) {
|
|
3274
3377
|
const readable = await endingOutputReadable(session, message.task_id, message.output_file);
|
|
3275
3378
|
const change = session.taskFeed.onNotification(message);
|
|
@@ -3289,6 +3392,10 @@ export class ClaudeAcpAgent {
|
|
|
3289
3392
|
message.patch.status === "failed" ||
|
|
3290
3393
|
message.patch.status === "killed") {
|
|
3291
3394
|
session.liveBackgroundTasks.delete(message.task_id);
|
|
3395
|
+
// Usually first: the notification with its summary follows
|
|
3396
|
+
// but is not guaranteed, so the terminal ends here.
|
|
3397
|
+
await endBackgroundTerminal(message.task_id, backgroundExitCode(message.patch.status, message.patch.error));
|
|
3398
|
+
armDrainGrace();
|
|
3292
3399
|
}
|
|
3293
3400
|
if (session.taskFeed && session.taskFeedPublisher) {
|
|
3294
3401
|
// The CLI queues the terminal patch BEFORE the
|
|
@@ -3488,6 +3595,7 @@ export class ClaudeAcpAgent {
|
|
|
3488
3595
|
session.liveBackgroundTasks.delete(taskId);
|
|
3489
3596
|
}
|
|
3490
3597
|
}
|
|
3598
|
+
armDrainGrace();
|
|
3491
3599
|
}
|
|
3492
3600
|
// The same level, forwarded: once the turn has settled the
|
|
3493
3601
|
// client reads the thread as idle, and a background shell or
|
|
@@ -3509,7 +3617,10 @@ export class ClaudeAcpAgent {
|
|
|
3509
3617
|
// the user's prompt's. Autonomous results must never touch the
|
|
3510
3618
|
// user-turn lifecycle (stop reason, settles, failActive,
|
|
3511
3619
|
// slash-command output forwarding), though their cost is real.
|
|
3512
|
-
|
|
3620
|
+
// The exception: the user's prompt was added to that turn while it
|
|
3621
|
+
// ran, so its result answers the prompt (see answersPendingPrompt).
|
|
3622
|
+
const startedByClaudeCode = message.origin != null && AUTONOMOUS_RESULT_ORIGINS.has(message.origin.kind);
|
|
3623
|
+
const isAutonomousResult = startedByClaudeCode && !answersPendingPrompt(message);
|
|
3513
3624
|
const pendingExitPlanModeInterruption = session.pendingExitPlanModeInterruption;
|
|
3514
3625
|
const pendingExitPlanContextReset = session.pendingExitPlanContextReset;
|
|
3515
3626
|
try {
|
|
@@ -4427,6 +4538,19 @@ export class ClaudeAcpAgent {
|
|
|
4427
4538
|
// Before toAcpNotifications, which prunes the tool_use cache entry
|
|
4428
4539
|
// that says the result is a Bash call's.
|
|
4429
4540
|
observeBackgroundBashResult(message, content, session);
|
|
4541
|
+
// The command's terminal runs until its task ends, unless the task
|
|
4542
|
+
// has ended already (a fast command can end before its result).
|
|
4543
|
+
const runningTerminal = this.clientCapabilities?._meta?.["terminal_output"] === true
|
|
4544
|
+
? backgroundBashTerminal(message, content, session)
|
|
4545
|
+
: undefined;
|
|
4546
|
+
if (runningTerminal && session.liveBackgroundTasks.has(runningTerminal.taskId)) {
|
|
4547
|
+
(session.backgroundTerminals ??= new Map()).set(runningTerminal.taskId, {
|
|
4548
|
+
toolCallId: runningTerminal.toolCallId,
|
|
4549
|
+
...(message.parent_tool_use_id
|
|
4550
|
+
? { parentToolUseId: message.parent_tool_use_id }
|
|
4551
|
+
: {}),
|
|
4552
|
+
});
|
|
4553
|
+
}
|
|
4430
4554
|
for (const notification of toAcpNotifications(content, message.message.role, params.sessionId, session.toolUseCache, this.client, this.logger, {
|
|
4431
4555
|
clientCapabilities: this.clientCapabilities,
|
|
4432
4556
|
parentToolUseId: message.parent_tool_use_id,
|
|
@@ -4454,7 +4578,9 @@ export class ClaudeAcpAgent {
|
|
|
4454
4578
|
// filtered out of `content` above; blocks that do pass through
|
|
4455
4579
|
// (e.g. a subagent image) carry the stamped parentToolUseId
|
|
4456
4580
|
// meta and are excluded there.
|
|
4457
|
-
await sendUpdate(acceptedPlanToolResult(notification, acceptedPlanToolUseId))
|
|
4581
|
+
await sendUpdate(withRunningTerminal(acceptedPlanToolResult(notification, acceptedPlanToolUseId), runningTerminal && session.backgroundTerminals?.has(runningTerminal.taskId)
|
|
4582
|
+
? runningTerminal.toolCallId
|
|
4583
|
+
: undefined));
|
|
4458
4584
|
}
|
|
4459
4585
|
break;
|
|
4460
4586
|
}
|
|
@@ -5068,6 +5194,18 @@ export class ClaudeAcpAgent {
|
|
|
5068
5194
|
await this.applyFastMode(session, resolveFastModeEnabled(params));
|
|
5069
5195
|
return { configOptions: session.configOptions };
|
|
5070
5196
|
}
|
|
5197
|
+
// Ultracode is a boolean too, and bypasses the same validation. The legacy
|
|
5198
|
+
// `effort = "ultracode"` (the retired notch) is accepted for one release.
|
|
5199
|
+
const useBoolean = clientSupportsBooleanConfigOptions(this.clientCapabilities);
|
|
5200
|
+
if (params.configId === ULTRACODE_CONFIG_ID) {
|
|
5201
|
+
await applyUltracodeToggle(session, resolveUltracodeRequested(params), useBoolean);
|
|
5202
|
+
return { configOptions: session.configOptions };
|
|
5203
|
+
}
|
|
5204
|
+
if (params.configId === EFFORT_CONFIG_ID &&
|
|
5205
|
+
isLegacyUltracodeEffort(params.value) &&
|
|
5206
|
+
(await applyLegacyUltracodeEffort(session, useBoolean))) {
|
|
5207
|
+
return { configOptions: session.configOptions };
|
|
5208
|
+
}
|
|
5071
5209
|
// The Thinking toggle only records the session's intent — the SDK query
|
|
5072
5210
|
// swap is deferred to the next prompt() start (lazy recreate, sub-task
|
|
5073
5211
|
// 1.3), so there is no SDK call to fail here and the config option is
|
|
@@ -5696,6 +5834,13 @@ export class ClaudeAcpAgent {
|
|
|
5696
5834
|
* Not written to `contextWindowCache` — that stays keyed to the
|
|
5697
5835
|
* `result.modelUsage` spellings — and a result still overwrites it.
|
|
5698
5836
|
* Ported from upstream #1186.
|
|
5837
|
+
*
|
|
5838
|
+
* Asks for the `summary` detail (parity item 97, upstream #1258): the
|
|
5839
|
+
* default `full` breakdown issues one `messages/count_tokens` call per
|
|
5840
|
+
* category, and only `rawMaxTokens` is read here. The two other callers
|
|
5841
|
+
* (`readResumedLiveModel`, `fetchContextUsedTokens`) read `totalTokens`,
|
|
5842
|
+
* which `summary` takes from the last response's usage plus local
|
|
5843
|
+
* estimates instead of counting — not the same number, so they keep `full`.
|
|
5699
5844
|
*/
|
|
5700
5845
|
refreshContextWindowInBackground(sessionId, session) {
|
|
5701
5846
|
if (session.contextWindowAuthoritative)
|
|
@@ -5707,7 +5852,7 @@ export class ClaudeAcpAgent {
|
|
|
5707
5852
|
session.models.currentModelId === modelId;
|
|
5708
5853
|
// A synchronous throw must not fail the caller either.
|
|
5709
5854
|
Promise.resolve()
|
|
5710
|
-
.then(() => query.getContextUsage())
|
|
5855
|
+
.then(() => query.getContextUsage({ detail: "summary" }))
|
|
5711
5856
|
.then((usage) => {
|
|
5712
5857
|
if (!stillCurrent() || session.contextWindowAuthoritative)
|
|
5713
5858
|
return;
|
|
@@ -5753,7 +5898,10 @@ export class ClaudeAcpAgent {
|
|
|
5753
5898
|
if (session.fastModeDisabledReason === "model_not_allowed") {
|
|
5754
5899
|
session.fastModeDisabledReason = undefined;
|
|
5755
5900
|
}
|
|
5756
|
-
// Rebuild config options since effort levels depend on the selected model
|
|
5901
|
+
// Rebuild config options since effort levels depend on the selected model.
|
|
5902
|
+
// The new model decides whether Ultracode is shown (heuristic now, the
|
|
5903
|
+
// CLI's readback below); the retained intent decides its value.
|
|
5904
|
+
session.ultracodeAvailable = isUltracodeAvailable(newModelInfo?.supportsEffort ? (newModelInfo.supportedEffortLevels ?? []) : [], { disableWorkflows: session.workflowsDisabled });
|
|
5757
5905
|
const effortOpt = session.configOptions.find((o) => o.id === EFFORT_CONFIG_ID);
|
|
5758
5906
|
const currentEffort = typeof effortOpt?.currentValue === "string" ? effortOpt.currentValue : undefined;
|
|
5759
5907
|
session.configOptions = buildConfigOptions(session.modes, session.models, session.modelInfos, currentEffort, session.agents, session.currentAgent, {
|
|
@@ -5772,15 +5920,7 @@ export class ClaudeAcpAgent {
|
|
|
5772
5920
|
// (R1.6).
|
|
5773
5921
|
session.thinkingEnabled ??
|
|
5774
5922
|
effectiveThinkingConfig(undefined, process.env.MAX_THINKING_TOKENS, this.logger) !==
|
|
5775
|
-
undefined, {
|
|
5776
|
-
// The new model decides whether the entry renders at all; the session's
|
|
5777
|
-
// retained intent decides whether it renders selected. A model without
|
|
5778
|
-
// `xhigh` drops the entry, and `validEffort` then falls back for it the
|
|
5779
|
-
// same way it does for any unsupported level.
|
|
5780
|
-
available: isUltracodeAvailable(newModelInfo?.supportsEffort ? (newModelInfo.supportedEffortLevels ?? []) : [], { disableWorkflows: session.workflowsDisabled }),
|
|
5781
|
-
enabled: session.ultracode,
|
|
5782
|
-
}, {
|
|
5783
|
-
disableWorkflows: session.workflowsDisabled,
|
|
5923
|
+
undefined, this.ultracodeState(session, session.ultracodeAvailable), {
|
|
5784
5924
|
// Threaded for the same reason Thinking is (R1.7): an option not
|
|
5785
5925
|
// passed through this rebuild silently drops from the picker on
|
|
5786
5926
|
// every model switch. The account is model-independent, so the row
|
|
@@ -5792,8 +5932,7 @@ export class ClaudeAcpAgent {
|
|
|
5792
5932
|
const newEffortOpt = session.configOptions.find((o) => o.id === EFFORT_CONFIG_ID);
|
|
5793
5933
|
const newEffort = typeof newEffortOpt?.currentValue === "string" ? newEffortOpt.currentValue : undefined;
|
|
5794
5934
|
if (newEffort !== currentEffort) {
|
|
5795
|
-
await session.query.applyFlagSettings(
|
|
5796
|
-
session.ultracode = isUltracodeValue(newEffort);
|
|
5935
|
+
await session.query.applyFlagSettings(effortFlagSettings(newEffort, session.ultracodeRequested));
|
|
5797
5936
|
}
|
|
5798
5937
|
// Emit current_mode_update only after session.modes AND
|
|
5799
5938
|
// session.configOptions have been fully reconciled. This way, a failure
|
|
@@ -5805,8 +5944,10 @@ export class ClaudeAcpAgent {
|
|
|
5805
5944
|
await this.sessionModes.publishFallbackState(sessionId, session);
|
|
5806
5945
|
}
|
|
5807
5946
|
// Last, so the switch's own control requests don't queue behind it.
|
|
5808
|
-
if (modelChanged)
|
|
5947
|
+
if (modelChanged) {
|
|
5809
5948
|
this.refreshContextWindowInBackground(sessionId, session);
|
|
5949
|
+
this.refreshUltracodeInBackground(sessionId, session, false);
|
|
5950
|
+
}
|
|
5810
5951
|
}
|
|
5811
5952
|
else if (configId === AGENT_CONFIG_ID) {
|
|
5812
5953
|
// Live agent switch — no subprocess restart needed. Apply the SDK flag
|
|
@@ -5843,11 +5984,9 @@ export class ClaudeAcpAgent {
|
|
|
5843
5984
|
else {
|
|
5844
5985
|
session.configOptions = session.configOptions.map((o) => o.id === configId && typeof o.currentValue === "string" ? { ...o, currentValue: value } : o);
|
|
5845
5986
|
if (configId === EFFORT_CONFIG_ID) {
|
|
5846
|
-
//
|
|
5847
|
-
//
|
|
5848
|
-
|
|
5849
|
-
await session.query.applyFlagSettings(ultracodeFlagSettings(value));
|
|
5850
|
-
session.ultracode = isUltracodeValue(value);
|
|
5987
|
+
// An effort change without `ultracode` turns it off, so the intent
|
|
5988
|
+
// rides along — see `effortFlagSettings`.
|
|
5989
|
+
await session.query.applyFlagSettings(effortFlagSettings(value, session.ultracodeRequested));
|
|
5851
5990
|
}
|
|
5852
5991
|
}
|
|
5853
5992
|
}
|
|
@@ -5900,6 +6039,50 @@ export class ClaudeAcpAgent {
|
|
|
5900
6039
|
session.fastModeEnabled = enabled;
|
|
5901
6040
|
this.refreshFastModeOption(session, enabled);
|
|
5902
6041
|
}
|
|
6042
|
+
/** The Ultracode display state for `buildConfigOptions`. */
|
|
6043
|
+
ultracodeState(session, available) {
|
|
6044
|
+
return {
|
|
6045
|
+
available,
|
|
6046
|
+
requested: session.ultracodeRequested,
|
|
6047
|
+
useBooleanOption: clientSupportsBooleanConfigOptions(this.clientCapabilities),
|
|
6048
|
+
};
|
|
6049
|
+
}
|
|
6050
|
+
/**
|
|
6051
|
+
* Replace the Ultracode heuristic with the CLI's `applied` report, without
|
|
6052
|
+
* blocking the caller — never inline, because control requests queue ahead
|
|
6053
|
+
* of interrupt and close (upstream #1216). `seedIntent` at session start; a
|
|
6054
|
+
* model switch keeps its intent and only re-reads availability. Deferred a
|
|
6055
|
+
* tick so a resulting `config_option_update` follows the session/new reply.
|
|
6056
|
+
*/
|
|
6057
|
+
refreshUltracodeInBackground(sessionId, session, seedIntent) {
|
|
6058
|
+
const { query } = session;
|
|
6059
|
+
const modelId = session.models.currentModelId;
|
|
6060
|
+
const requestedAtStart = session.ultracodeRequested;
|
|
6061
|
+
const stillCurrent = () => this.sessions[sessionId] === session &&
|
|
6062
|
+
session.query === query &&
|
|
6063
|
+
session.models.currentModelId === modelId;
|
|
6064
|
+
setTimeout(() => {
|
|
6065
|
+
void readUltracodeState(query, (error) => {
|
|
6066
|
+
this.logger.log(`[ultracode] get_settings failed session=${sessionId}: ${String(error)}`);
|
|
6067
|
+
})
|
|
6068
|
+
.then(async (readback) => {
|
|
6069
|
+
if (!readback || !stillCurrent())
|
|
6070
|
+
return;
|
|
6071
|
+
// A toggle that landed while the read was in flight is newer than it.
|
|
6072
|
+
const seed = seedIntent && session.ultracodeRequested === requestedAtStart;
|
|
6073
|
+
const useBoolean = clientSupportsBooleanConfigOptions(this.clientCapabilities);
|
|
6074
|
+
if (!applyUltracodeReadback(session, readback, seed, useBoolean))
|
|
6075
|
+
return;
|
|
6076
|
+
await this.client.sessionUpdate({
|
|
6077
|
+
sessionId,
|
|
6078
|
+
update: { sessionUpdate: "config_option_update", configOptions: session.configOptions },
|
|
6079
|
+
});
|
|
6080
|
+
})
|
|
6081
|
+
.catch((error) => {
|
|
6082
|
+
this.logger.error(`[ultracode] readback failed session=${sessionId}:`, error);
|
|
6083
|
+
});
|
|
6084
|
+
}, 0);
|
|
6085
|
+
}
|
|
5903
6086
|
/** Lazily swap a session's SDK query for a fresh one so a Thinking change
|
|
5904
6087
|
* takes effect on the next turn (R1.3): thinking has no live flag-settings
|
|
5905
6088
|
* path in the SDK, so mid-session application goes through query recreation
|
|
@@ -6021,14 +6204,16 @@ export class ClaudeAcpAgent {
|
|
|
6021
6204
|
// await is already included.
|
|
6022
6205
|
const effortOpt = session.configOptions.find((o) => o.id === EFFORT_CONFIG_ID);
|
|
6023
6206
|
const effortValue = typeof effortOpt?.currentValue === "string" ? effortOpt.currentValue : undefined;
|
|
6024
|
-
const
|
|
6025
|
-
// Only the positive
|
|
6207
|
+
const effortFlags = effortFlagSettings(effortValue, session.ultracodeRequested);
|
|
6208
|
+
// Only the positive cases are re-applied: the replacement's flag layer
|
|
6026
6209
|
// starts empty, so clearing a key that was never set would be a control
|
|
6027
|
-
// request that says nothing.
|
|
6028
|
-
//
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6210
|
+
// request that says nothing. The Ultracode intent is replayed even at
|
|
6211
|
+
// Default effort.
|
|
6212
|
+
if (effortFlags.effortLevel !== null) {
|
|
6213
|
+
await replacement.applyFlagSettings(effortFlags);
|
|
6214
|
+
}
|
|
6215
|
+
else if (effortFlags.ultracode) {
|
|
6216
|
+
await replacement.applyFlagSettings({ ultracode: true });
|
|
6032
6217
|
}
|
|
6033
6218
|
const supportsFastMode = session.modelInfos.find((m) => m.value === session.models.currentModelId)
|
|
6034
6219
|
?.supportsFastMode ?? false;
|
|
@@ -6810,6 +6995,7 @@ export class ClaudeAcpAgent {
|
|
|
6810
6995
|
disabledReason: fastModeDisabledReason,
|
|
6811
6996
|
};
|
|
6812
6997
|
const workflowsDisabled = settingsManager.getSettings().disableWorkflows === true;
|
|
6998
|
+
const ultracodeRequested = settingsManager.getSettings().ultracode === true;
|
|
6813
6999
|
const configOptions = buildConfigOptions(modes, models,
|
|
6814
7000
|
// Catalog-based (see `modelInfos` above), matching the model-switch
|
|
6815
7001
|
// rebuild (which passes `session.modelInfos`): `buildConfigOptions`
|
|
@@ -6823,31 +7009,24 @@ export class ClaudeAcpAgent {
|
|
|
6823
7009
|
// effectiveThinkingConfig(undefined, MAX_THINKING_TOKENS) from above, so
|
|
6824
7010
|
// reusing it avoids re-parsing (and re-logging an invalid) env var —
|
|
6825
7011
|
// exactly one error log per query creation.
|
|
6826
|
-
thinking !== undefined,
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
available: isUltracodeAvailable(currentModelInfo?.supportsEffort ? (currentModelInfo.supportedEffortLevels ?? []) : [], { disableWorkflows: workflowsDisabled }),
|
|
6831
|
-
enabled: settingsManager.getSettings().ultracode === true,
|
|
6832
|
-
}, {
|
|
6833
|
-
disableWorkflows: workflowsDisabled,
|
|
7012
|
+
thinking !== undefined,
|
|
7013
|
+
// Seeded from settings and the heuristic; the CLI's own report replaces
|
|
7014
|
+
// both in the background (`refreshUltracodeInBackground`, below).
|
|
7015
|
+
this.ultracodeState({ ultracodeRequested }, isUltracodeAvailable(currentModelInfo?.supportsEffort ? (currentModelInfo.supportedEffortLevels ?? []) : [], { disableWorkflows: workflowsDisabled })), {
|
|
6834
7016
|
// Both halves of the selector, resolved above alongside the env they
|
|
6835
7017
|
// produced — so the row the client renders and the configuration
|
|
6836
7018
|
// directory the query was actually started with cannot disagree.
|
|
6837
7019
|
accounts: declaredAccounts,
|
|
6838
7020
|
currentAccount: accountEntry?.value,
|
|
6839
7021
|
});
|
|
6840
|
-
// Apply the initial effort level to the SDK so it matches the UI default
|
|
7022
|
+
// Apply the initial effort level to the SDK so it matches the UI default.
|
|
7023
|
+
// It carries the Ultracode intent: an effort change without the key would
|
|
7024
|
+
// turn off an `ultracode: true` the session was started with.
|
|
6841
7025
|
const initialEffort = configOptions.find((o) => o.id === EFFORT_CONFIG_ID);
|
|
6842
|
-
// The picker's resolved value, not the raw setting: `buildConfigOptions`
|
|
6843
|
-
// has already dropped Ultracode if this model cannot reach `xhigh`, and the
|
|
6844
|
-
// session must track what is displayed rather than what was requested.
|
|
6845
|
-
const initialUltracode = typeof initialEffort?.currentValue === "string" &&
|
|
6846
|
-
isUltracodeValue(initialEffort.currentValue);
|
|
6847
7026
|
if (initialEffort &&
|
|
6848
7027
|
typeof initialEffort.currentValue === "string" &&
|
|
6849
7028
|
initialEffort.currentValue !== "default") {
|
|
6850
|
-
await q.applyFlagSettings(
|
|
7029
|
+
await q.applyFlagSettings(effortFlagSettings(initialEffort.currentValue, ultracodeRequested));
|
|
6851
7030
|
}
|
|
6852
7031
|
// Seed the context window WITHOUT any extra IPC on the session/new path.
|
|
6853
7032
|
// On session/load, the resumed session's own `getContextUsage` report — a
|
|
@@ -6912,7 +7091,8 @@ export class ClaudeAcpAgent {
|
|
|
6912
7091
|
configOptions,
|
|
6913
7092
|
agents,
|
|
6914
7093
|
currentAgent,
|
|
6915
|
-
|
|
7094
|
+
ultracodeRequested,
|
|
7095
|
+
ultracodeAvailable: configOptions.some((o) => o.id === ULTRACODE_CONFIG_ID),
|
|
6916
7096
|
workflowsDisabled,
|
|
6917
7097
|
declaredAccounts,
|
|
6918
7098
|
currentAccount: accountEntry?.value,
|
|
@@ -6960,6 +7140,7 @@ export class ClaudeAcpAgent {
|
|
|
6960
7140
|
// A guessed window seed (text heuristic / default) is refined the same way,
|
|
6961
7141
|
// unawaited; a resumed session's authoritative seed makes it a no-op.
|
|
6962
7142
|
this.refreshContextWindowInBackground(sessionId, this.sessions[sessionId]);
|
|
7143
|
+
this.refreshUltracodeInBackground(sessionId, this.sessions[sessionId], true);
|
|
6963
7144
|
return {
|
|
6964
7145
|
sessionId,
|
|
6965
7146
|
modes,
|
|
@@ -7293,16 +7474,11 @@ export function buildConfigOptions(modes, models, modelInfos, currentEffortLevel
|
|
|
7293
7474
|
* Both session call sites always supply it (R1.1); `undefined` (direct
|
|
7294
7475
|
* callers/tests) omits the row. */
|
|
7295
7476
|
thinkingEnabled,
|
|
7296
|
-
/** Display state for the Ultracode
|
|
7297
|
-
* direct callers/tests, in which case
|
|
7298
|
-
* `settings` and the entry renders unselected. */
|
|
7477
|
+
/** Display state for the Ultracode option, placed after effort. Omitted by
|
|
7478
|
+
* direct callers/tests, in which case the option is not shown. */
|
|
7299
7479
|
ultracode,
|
|
7300
|
-
/**
|
|
7301
|
-
*
|
|
7302
|
-
* declared accounts plus the one in force, which decide whether an account
|
|
7303
|
-
* selector is advertised at all (R6.1/R6.2). `accounts` is not a field of
|
|
7304
|
-
* the SDK's `Settings`, so it is carried beside them rather than picked
|
|
7305
|
-
* from them. */
|
|
7480
|
+
/** The declared accounts plus the one in force, which decide whether an
|
|
7481
|
+
* account selector is advertised at all (R6.1/R6.2). */
|
|
7306
7482
|
settings) {
|
|
7307
7483
|
const options = [
|
|
7308
7484
|
SessionModeManager.configOption(modes),
|
|
@@ -7336,11 +7512,6 @@ settings) {
|
|
|
7336
7512
|
? (currentModelInfo.supportedEffortLevels ?? [])
|
|
7337
7513
|
: [];
|
|
7338
7514
|
if (supportedLevels.length > 0) {
|
|
7339
|
-
// Ultracode rides the effort picker as one extra entry past the last level,
|
|
7340
|
-
// which is where the VS Code extension draws it too. It is NOT a level (see
|
|
7341
|
-
// `ultracode.ts`): the entry stands for `xhigh` plus workflow orchestration,
|
|
7342
|
-
// and it is offered only when both halves are reachable.
|
|
7343
|
-
const ultracodeAvailable = ultracode?.available ?? isUltracodeAvailable(supportedLevels, settings);
|
|
7344
7515
|
const effortOptions = [
|
|
7345
7516
|
{ value: "default", name: "Default" },
|
|
7346
7517
|
...supportedLevels.map((level) => ({
|
|
@@ -7350,21 +7521,9 @@ settings) {
|
|
|
7350
7521
|
.map((part) => (part ? part.charAt(0).toUpperCase() + part.slice(1) : part))
|
|
7351
7522
|
.join(" "),
|
|
7352
7523
|
})),
|
|
7353
|
-
...(ultracodeAvailable
|
|
7354
|
-
? [{ value: ULTRACODE_OPTION_VALUE, name: ULTRACODE_OPTION_NAME }]
|
|
7355
|
-
: []),
|
|
7356
7524
|
];
|
|
7357
|
-
const includes = (l) => l === "default" ||
|
|
7358
|
-
|
|
7359
|
-
(ultracodeAvailable && l === ULTRACODE_OPTION_VALUE);
|
|
7360
|
-
// `effortOptionValue` resolves the flag against the level BEFORE validation,
|
|
7361
|
-
// so an Ultracode session on a model that dropped `xhigh` falls back to
|
|
7362
|
-
// "Default" through the same path any unsupported level does.
|
|
7363
|
-
const displayedEffort = effortOptionValue(currentEffortLevel, {
|
|
7364
|
-
available: ultracodeAvailable,
|
|
7365
|
-
enabled: ultracode?.enabled ?? false,
|
|
7366
|
-
});
|
|
7367
|
-
const validEffort = displayedEffort && includes(displayedEffort) ? displayedEffort : "default";
|
|
7525
|
+
const includes = (l) => l === "default" || supportedLevels.includes(l);
|
|
7526
|
+
const validEffort = currentEffortLevel && includes(currentEffortLevel) ? currentEffortLevel : "default";
|
|
7368
7527
|
options.push({
|
|
7369
7528
|
id: EFFORT_CONFIG_ID,
|
|
7370
7529
|
name: "Effort",
|
|
@@ -7375,6 +7534,11 @@ settings) {
|
|
|
7375
7534
|
options: effortOptions,
|
|
7376
7535
|
});
|
|
7377
7536
|
}
|
|
7537
|
+
// Ultracode: a toggle beside effort, not an effort level (`ultracode.ts`).
|
|
7538
|
+
const ultracodeOption = ultracodeConfigOption(ultracode);
|
|
7539
|
+
if (ultracodeOption) {
|
|
7540
|
+
options.push(ultracodeOption);
|
|
7541
|
+
}
|
|
7378
7542
|
// Surface the Fast mode toggle only when the current model supports it. The
|
|
7379
7543
|
// option renders as a native boolean toggle for Clients that opted in, and a
|
|
7380
7544
|
// two-value select otherwise.
|
|
@@ -9005,6 +9169,71 @@ function getMatchingModelUsage(modelUsage, currentModel) {
|
|
|
9005
9169
|
return { key: bestKey, usage: modelUsage[bestKey] };
|
|
9006
9170
|
}
|
|
9007
9171
|
}
|
|
9172
|
+
/**
|
|
9173
|
+
* Parity item 92: the Bash tool call and task of a command this result sent to
|
|
9174
|
+
* the background — the structured `BashOutput` carries `backgroundTaskId`, and
|
|
9175
|
+
* the message holds exactly one tool_result, of a Bash call.
|
|
9176
|
+
*/
|
|
9177
|
+
function backgroundBashTerminal(message, content, session) {
|
|
9178
|
+
if (message.type !== "user" || !Array.isArray(content))
|
|
9179
|
+
return undefined;
|
|
9180
|
+
const result = message.tool_use_result;
|
|
9181
|
+
if (typeof result !== "object" || result === null || !("backgroundTaskId" in result)) {
|
|
9182
|
+
return undefined;
|
|
9183
|
+
}
|
|
9184
|
+
const taskId = result.backgroundTaskId;
|
|
9185
|
+
if (typeof taskId !== "string" || taskId === "")
|
|
9186
|
+
return undefined;
|
|
9187
|
+
const blocks = content.filter((c) => typeof c === "object" && c !== null && c.type === "tool_result");
|
|
9188
|
+
if (blocks.length !== 1)
|
|
9189
|
+
return undefined;
|
|
9190
|
+
const toolCallId = blocks[0].tool_use_id;
|
|
9191
|
+
if (session.toolUseCache[toolCallId]?.name !== "Bash")
|
|
9192
|
+
return undefined;
|
|
9193
|
+
return { taskId, toolCallId };
|
|
9194
|
+
}
|
|
9195
|
+
/**
|
|
9196
|
+
* Drops `terminal_exit` from the tool result update of `toolCallId`: the Bash
|
|
9197
|
+
* call returned as soon as its command detached, and the exit would mark the
|
|
9198
|
+
* terminal as ended while the command still runs.
|
|
9199
|
+
*/
|
|
9200
|
+
export function withRunningTerminal(notification, toolCallId) {
|
|
9201
|
+
const update = notification.update;
|
|
9202
|
+
if (toolCallId === undefined ||
|
|
9203
|
+
update.sessionUpdate !== "tool_call_update" ||
|
|
9204
|
+
update.toolCallId !== toolCallId ||
|
|
9205
|
+
!update._meta ||
|
|
9206
|
+
!("terminal_exit" in update._meta)) {
|
|
9207
|
+
return notification;
|
|
9208
|
+
}
|
|
9209
|
+
const meta = { ...update._meta };
|
|
9210
|
+
delete meta.terminal_exit;
|
|
9211
|
+
const next = { ...update, _meta: meta };
|
|
9212
|
+
if (Object.keys(meta).length === 0)
|
|
9213
|
+
delete next._meta;
|
|
9214
|
+
return { ...notification, update: next };
|
|
9215
|
+
}
|
|
9216
|
+
/**
|
|
9217
|
+
* The exit code of a background command whose task ended, from what the task's
|
|
9218
|
+
* ending says. Claude Code's summary reads `Background command "<d>" completed
|
|
9219
|
+
* (exit code N[: note])` or `… failed with exit code N` (CLI 2.1.285); an
|
|
9220
|
+
* ending names a code only at its end, so a description holding the words
|
|
9221
|
+
* cannot be mistaken for it. A completion with a non-zero code is one Claude
|
|
9222
|
+
* Code accepted as a success (grep's "No matches found"), so it goes out as
|
|
9223
|
+
* null; a failure or stop that names no code goes out as 1, never null.
|
|
9224
|
+
*/
|
|
9225
|
+
export function backgroundExitCode(status, text) {
|
|
9226
|
+
const failed = status === "failed" || status === "killed" || status === "stopped";
|
|
9227
|
+
const said = typeof text === "string" ? text : "";
|
|
9228
|
+
if (failed) {
|
|
9229
|
+
const match = /exit code (\d+)\s*$/.exec(said);
|
|
9230
|
+
return match ? Number(match[1]) : 1;
|
|
9231
|
+
}
|
|
9232
|
+
const match = /\(exit code (\d+)(?::[^)]*)?\)\s*$/.exec(said);
|
|
9233
|
+
if (match && Number(match[1]) === 0)
|
|
9234
|
+
return 0;
|
|
9235
|
+
return null;
|
|
9236
|
+
}
|
|
9008
9237
|
/**
|
|
9009
9238
|
* Story 041 (R1.1, R1.6): a backgrounded Bash call's result names the file the
|
|
9010
9239
|
* CLI writes its output to. When the structured `BashOutput` carries
|
package/dist/tools.d.ts
CHANGED
|
@@ -23,7 +23,8 @@ interface ToolUpdate {
|
|
|
23
23
|
};
|
|
24
24
|
terminal_exit?: {
|
|
25
25
|
terminal_id: string;
|
|
26
|
-
|
|
26
|
+
/** Null when the code is not known (as in `TerminalExitStatus`). */
|
|
27
|
+
exit_code: number | null;
|
|
27
28
|
signal: string | null;
|
|
28
29
|
};
|
|
29
30
|
};
|
|
@@ -40,6 +41,12 @@ export type ClaudePlanEntry = {
|
|
|
40
41
|
status: "pending" | "in_progress" | "completed";
|
|
41
42
|
activeForm: string;
|
|
42
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* The exit code the text of a failed command names. Claude Code starts the text
|
|
46
|
+
* of a command that exited with a failing code with `Exit code N`; other
|
|
47
|
+
* failures, such as a denial or a command that could not start, name none.
|
|
48
|
+
*/
|
|
49
|
+
export declare function failureExitCode(text: string): number | undefined;
|
|
43
50
|
export declare function planEntries(input: {
|
|
44
51
|
todos: ClaudePlanEntry[];
|
|
45
52
|
} | undefined): PlanEntry[];
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACT,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAaL,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,gBAAgB,EAKjB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAGL,oBAAoB,EAEpB,6BAA6B,EAE9B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,yCAAyC,EAGzC,qCAAqC,EAGrC,kCAAkC,EAGlC,+CAA+C,EAI/C,wBAAwB,EACxB,kCAAkC,EAIlC,gCAAgC,EAEhC,iCAAiC,EAClC,MAAM,sCAAsC,CAAC;AA2B9C,UAAU,QAAQ;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED,UAAU,UAAU;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,KAAK,CAAC,EAAE;QACN,aAAa,CAAC,EAAE;YACd,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,eAAe,CAAC,EAAE;YAChB,WAAW,EAAE,MAAM,CAAC;YACpB,IAAI,EAAE,MAAM,CAAC;SACd,CAAC;QACF,aAAa,CAAC,EAAE;YACd,WAAW,EAAE,MAAM,CAAC;YACpB,SAAS,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|