oh-my-opencode 4.5.12 → 4.6.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/.agents/skills/opencode-qa/SKILL.md +194 -0
- package/.agents/skills/opencode-qa/references/cli-commands.md +188 -0
- package/.agents/skills/opencode-qa/references/db-investigation.md +197 -0
- package/.agents/skills/opencode-qa/references/events-hooks.md +110 -0
- package/.agents/skills/opencode-qa/references/sdk.md +96 -0
- package/.agents/skills/opencode-qa/references/server-api.md +200 -0
- package/.agents/skills/opencode-qa/references/testing-harness.md +218 -0
- package/.agents/skills/opencode-qa/references/tui-tmux.md +52 -0
- package/.agents/skills/opencode-qa/scripts/db-session-by-id.sh +53 -0
- package/.agents/skills/opencode-qa/scripts/db-session-by-name.sh +57 -0
- package/.agents/skills/opencode-qa/scripts/db-session-by-text.sh +158 -0
- package/.agents/skills/opencode-qa/scripts/export-roundtrip.sh +57 -0
- package/.agents/skills/opencode-qa/scripts/lib/common.sh +216 -0
- package/.agents/skills/opencode-qa/scripts/server-smoke.sh +64 -0
- package/.agents/skills/opencode-qa/scripts/sse-hook-probe.sh +106 -0
- package/.agents/skills/opencode-qa/scripts/tui-smoke.sh +89 -0
- package/README.ja.md +13 -3
- package/README.ko.md +13 -3
- package/README.md +24 -14
- package/README.ru.md +13 -3
- package/README.zh-cn.md +13 -3
- package/bin/oh-my-opencode.js +4 -3
- package/bin/oh-my-opencode.test.ts +35 -7
- package/bin/platform.d.ts +1 -1
- package/bin/platform.js +4 -4
- package/bin/platform.test.ts +31 -9
- package/dist/cli/cleanup-command.d.ts +4 -0
- package/dist/cli/cleanup.d.ts +11 -0
- package/dist/cli/cli-program.d.ts +2 -1
- package/dist/cli/index.js +1837 -450
- package/dist/cli/install-codex/codex-cache.d.ts +1 -0
- package/dist/cli/install-codex/codex-cleanup-config.d.ts +6 -0
- package/dist/cli/install-codex/codex-cleanup.d.ts +21 -0
- package/dist/cli/install-codex/codex-config-mcp.d.ts +1 -0
- package/dist/cli/install-codex/codex-config-permissions.d.ts +1 -0
- package/dist/cli/install-codex/codex-config-reasoning.d.ts +1 -0
- package/dist/cli/install-codex/codex-config-toml.d.ts +2 -1
- package/dist/cli/install-codex/codex-installation-detection.d.ts +36 -0
- package/dist/cli/install-codex/codex-package-layout.d.ts +1 -0
- package/dist/cli/install-codex/codex-project-local-cleanup-best-effort.d.ts +7 -0
- package/dist/cli/install-codex/codex-project-local-cleanup.d.ts +35 -0
- package/dist/cli/install-codex/git-bash.d.ts +35 -0
- package/dist/cli/install-codex/index.d.ts +4 -0
- package/dist/cli/install-codex/toml-section-editor.d.ts +2 -0
- package/dist/cli/install-codex/types.d.ts +20 -0
- package/dist/cli/run/event-state.d.ts +1 -0
- package/dist/cli/run/poll-for-completion.d.ts +1 -0
- package/dist/cli/run/prompt-start.d.ts +7 -0
- package/dist/cli/star-request.d.ts +9 -0
- package/dist/config/schema/hooks.d.ts +0 -1
- package/dist/create-hooks.d.ts +0 -1
- package/dist/features/builtin-skills/skills/debugging.d.ts +2 -0
- package/dist/features/builtin-skills/skills/index.d.ts +1 -0
- package/dist/hooks/index.d.ts +0 -1
- package/dist/index.js +267 -114
- package/dist/plugin/hooks/create-core-hooks.d.ts +0 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +1 -2
- package/dist/plugin/messages-transform.d.ts +8 -1
- package/dist/plugin/user-abort-interrupted-recovery-guard.d.ts +6 -0
- package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +14 -0
- package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +7 -0
- package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +1 -0
- package/dist/shared/prompt-async-gate/timing.d.ts +1 -0
- package/dist/shared/prompt-async-gate/types.d.ts +2 -0
- package/dist/shared/prompt-async-gate.d.ts +1 -1
- package/package.json +22 -17
- package/packages/git-bash-mcp/dist/cli.js +367 -0
- package/packages/omo-codex/plugin/.mcp.json +11 -0
- package/packages/omo-codex/plugin/components/comment-checker/README.md +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +29 -0
- package/packages/omo-codex/plugin/components/git-bash/package.json +23 -0
- package/packages/omo-codex/plugin/components/git-bash/src/cli.ts +33 -0
- package/packages/omo-codex/plugin/components/git-bash/src/codex-hook.ts +180 -0
- package/packages/omo-codex/plugin/components/git-bash/src/index.ts +10 -0
- package/packages/omo-codex/plugin/components/git-bash/test/codex-hook.test.ts +195 -0
- package/packages/omo-codex/plugin/components/git-bash/tsconfig.build.json +13 -0
- package/packages/omo-codex/plugin/components/git-bash/tsconfig.json +25 -0
- package/packages/omo-codex/plugin/components/lsp/README.md +1 -1
- package/packages/omo-codex/plugin/components/lsp/src/cli.ts +5 -5
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook-cli.ts +33 -0
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +19 -27
- package/packages/omo-codex/plugin/components/lsp/test/codex-hook-cli.test.ts +28 -0
- package/packages/omo-codex/plugin/components/lsp/test/codex-hook-errors.test.ts +55 -0
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +7 -5
- package/packages/omo-codex/plugin/components/rules/README.md +1 -1
- package/packages/omo-codex/plugin/components/rules/bundled-rules/windows-git-bash.md +10 -0
- package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +3 -1
- package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +97 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +5 -4
- package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +22 -0
- package/packages/omo-codex/plugin/components/ultrawork/README.md +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/agents/codex-ultrawork-reviewer.toml +1 -0
- package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +8 -7
- package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +2 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +31 -5
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +27 -4
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +25 -0
- package/packages/omo-codex/plugin/components/ulw-loop/README.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +27 -205
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +230 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +102 -5
- package/packages/omo-codex/plugin/hooks/hooks.json +24 -2
- package/packages/omo-codex/plugin/package-lock.json +19 -0
- package/packages/omo-codex/plugin/package.json +3 -1
- package/packages/omo-codex/plugin/scripts/build-bundled-mcp-runtimes.mjs +16 -1
- package/packages/omo-codex/plugin/scripts/build-components.mjs +2 -1
- package/packages/omo-codex/plugin/scripts/sync-hook-status-messages.mjs +87 -0
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +27 -2
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +20 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +27 -205
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +230 -0
- package/packages/omo-codex/plugin/test/aggregate.test.mjs +23 -8
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +56 -11
- package/packages/omo-codex/plugin/test/install-time-build-runtime.test.mjs +34 -0
- package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +21 -0
- package/packages/omo-codex/plugin/test/node-install-surface.test.mjs +48 -0
- package/packages/omo-codex/plugin/test/subagent-guidance.test.mjs +76 -0
- package/packages/omo-codex/plugin/test/sync-hook-status-messages.test.mjs +66 -0
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +32 -2
- package/packages/omo-codex/scripts/install/cache.mjs +5 -3
- package/packages/omo-codex/scripts/install/cli-args.mjs +112 -0
- package/packages/omo-codex/scripts/install/config.mjs +36 -1
- package/packages/omo-codex/scripts/install/delegated-command.mjs +25 -0
- package/packages/omo-codex/scripts/install/git-bash.mjs +99 -0
- package/packages/omo-codex/scripts/install/git-bash.test.mjs +174 -0
- package/packages/omo-codex/scripts/install/mcp-runtime-cache.mjs +5 -1
- package/packages/omo-codex/scripts/install/multi-agent-v2-config.mjs +7 -1
- package/packages/omo-codex/scripts/install/permissions.d.mts +1 -0
- package/packages/omo-codex/scripts/install/permissions.mjs +26 -0
- package/packages/omo-codex/scripts/install/project-local-cleanup.mjs +229 -0
- package/packages/omo-codex/scripts/install/reasoning-config.mjs +14 -0
- package/packages/omo-codex/scripts/install/source-package-build.mjs +20 -0
- package/packages/omo-codex/scripts/install/toml-editor.mjs +19 -2
- package/packages/omo-codex/scripts/install-cli-args.test.mjs +146 -0
- package/packages/omo-codex/scripts/install-config-autonomous.test.mjs +48 -0
- package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +62 -0
- package/packages/omo-codex/scripts/install-config.test.mjs +206 -0
- package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +129 -0
- package/packages/omo-codex/scripts/install-local-git-bash-preflight.test.mjs +145 -0
- package/packages/omo-codex/scripts/install-local.mjs +91 -8
- package/packages/omo-codex/scripts/install-local.test.mjs +15 -0
- package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +60 -0
- package/packages/omo-codex/scripts/install-packaged-local.test.mjs +67 -0
- package/packages/omo-codex/scripts/install-project-local-cleanup.test.mjs +277 -0
- package/packages/shared-skills/skills/review-work/SKILL.md +27 -2
- package/packages/shared-skills/skills/start-work/SKILL.md +20 -0
- package/dist/hooks/context-window-monitor.d.ts +0 -19
package/dist/index.js
CHANGED
|
@@ -54030,7 +54030,7 @@ function buildTmuxAttachCommand(serverUrl, sessionId, directory = process.cwd())
|
|
|
54030
54030
|
}
|
|
54031
54031
|
function buildTmuxPlaceholderCommand(description) {
|
|
54032
54032
|
const escapedDescription = shellEscapeForDoubleQuotedCommand(description);
|
|
54033
|
-
return `${TMUX_COMMAND_SHELL} -c "printf '%s\\n%s\\n' "OMO subagent pane ready: ${escapedDescription}" "Focus this pane to attach.";
|
|
54033
|
+
return `${TMUX_COMMAND_SHELL} -c "printf '%s\\n%s\\n' "OMO subagent pane ready: ${escapedDescription}" "Focus this pane to attach."; while :; do sleep 86400; done"`;
|
|
54034
54034
|
}
|
|
54035
54035
|
var TMUX_COMMAND_SHELL = "/bin/sh";
|
|
54036
54036
|
var init_pane_command = () => {};
|
|
@@ -55033,7 +55033,7 @@ async function withDispatchTimeout(operation, dispatchTimeoutMs, operationName)
|
|
|
55033
55033
|
}
|
|
55034
55034
|
}
|
|
55035
55035
|
}
|
|
55036
|
-
var DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS = 2000, DEFAULT_PROMPT_DISPATCH_TIMEOUT_MS = 30000, DEFAULT_PROMPT_GATE_MESSAGES_FETCH_TIMEOUT_MS = 5000, DEFAULT_PROMPT_QUEUE_RETRY_MS = 250, promptGateMessagesFetchTimeoutMsForTesting;
|
|
55036
|
+
var DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS = 2000, DEFAULT_PROMPT_SEMANTIC_DEDUPE_HOLD_MS = 15000, DEFAULT_PROMPT_DISPATCH_TIMEOUT_MS = 30000, DEFAULT_PROMPT_GATE_MESSAGES_FETCH_TIMEOUT_MS = 5000, DEFAULT_PROMPT_QUEUE_RETRY_MS = 250, promptGateMessagesFetchTimeoutMsForTesting;
|
|
55037
55037
|
|
|
55038
55038
|
// src/shared/prompt-async-gate/pending-tool-turn.ts
|
|
55039
55039
|
function getPromptQuery(input) {
|
|
@@ -55146,6 +55146,45 @@ var init_pending_tool_turn = __esm(() => {
|
|
|
55146
55146
|
init_message_inspection_error();
|
|
55147
55147
|
});
|
|
55148
55148
|
|
|
55149
|
+
// src/shared/prompt-async-gate/recent-dispatches.ts
|
|
55150
|
+
function recentDispatchKey(sessionID, dedupeKey) {
|
|
55151
|
+
return `${sessionID}\x00${dedupeKey}`;
|
|
55152
|
+
}
|
|
55153
|
+
function pruneRecentPromptDispatches(now = Date.now()) {
|
|
55154
|
+
for (const [key, dispatch] of recentPromptDispatches) {
|
|
55155
|
+
if (dispatch.expiresAt <= now) {
|
|
55156
|
+
recentPromptDispatches.delete(key);
|
|
55157
|
+
}
|
|
55158
|
+
}
|
|
55159
|
+
}
|
|
55160
|
+
function getRecentPromptDispatch(sessionID, dedupeKey) {
|
|
55161
|
+
pruneRecentPromptDispatches();
|
|
55162
|
+
return recentPromptDispatches.get(recentDispatchKey(sessionID, dedupeKey));
|
|
55163
|
+
}
|
|
55164
|
+
function rememberRecentPromptDispatch(args) {
|
|
55165
|
+
pruneRecentPromptDispatches();
|
|
55166
|
+
if (args.holdMs <= 0) {
|
|
55167
|
+
return;
|
|
55168
|
+
}
|
|
55169
|
+
recentPromptDispatches.set(recentDispatchKey(args.sessionID, args.dedupeKey), {
|
|
55170
|
+
source: args.source,
|
|
55171
|
+
expiresAt: Date.now() + args.holdMs
|
|
55172
|
+
});
|
|
55173
|
+
log("[prompt-async-gate] remembered semantic prompt dispatch", {
|
|
55174
|
+
sessionID: args.sessionID,
|
|
55175
|
+
source: args.source,
|
|
55176
|
+
holdMs: args.holdMs
|
|
55177
|
+
});
|
|
55178
|
+
}
|
|
55179
|
+
function deleteRecentPromptDispatch(sessionID, dedupeKey) {
|
|
55180
|
+
recentPromptDispatches.delete(recentDispatchKey(sessionID, dedupeKey));
|
|
55181
|
+
}
|
|
55182
|
+
var recentPromptDispatches;
|
|
55183
|
+
var init_recent_dispatches = __esm(() => {
|
|
55184
|
+
init_logger();
|
|
55185
|
+
recentPromptDispatches = new Map;
|
|
55186
|
+
});
|
|
55187
|
+
|
|
55149
55188
|
// src/shared/prompt-async-gate/reservations.ts
|
|
55150
55189
|
function setExpiredReservationHandler(handler) {
|
|
55151
55190
|
expiredReservationHandler = handler;
|
|
@@ -55227,6 +55266,7 @@ async function dispatchAfterSessionIdle(args) {
|
|
|
55227
55266
|
dedupeKey,
|
|
55228
55267
|
settleMs,
|
|
55229
55268
|
postDispatchHoldMs,
|
|
55269
|
+
semanticDedupeHoldMs,
|
|
55230
55270
|
dispatchTimeoutMs,
|
|
55231
55271
|
checkStatus,
|
|
55232
55272
|
checkToolState,
|
|
@@ -55284,10 +55324,25 @@ async function dispatchAfterSessionIdle(args) {
|
|
|
55284
55324
|
log(`[prompt-async-gate] ${sessionName} dispatching`, { sessionID, source });
|
|
55285
55325
|
dispatchAttempted = true;
|
|
55286
55326
|
const response = await withDispatchTimeout(dispatch(input), dispatchTimeoutMs, `[prompt-async-gate] ${sessionName} dispatch`);
|
|
55327
|
+
rememberRecentPromptDispatch({
|
|
55328
|
+
sessionID,
|
|
55329
|
+
dedupeKey,
|
|
55330
|
+
source,
|
|
55331
|
+
holdMs: semanticDedupeHoldMs
|
|
55332
|
+
});
|
|
55287
55333
|
log(`[prompt-async-gate] ${sessionName} dispatched`, { sessionID, source });
|
|
55288
55334
|
return { status: "dispatched", response };
|
|
55289
55335
|
} catch (error) {
|
|
55290
|
-
|
|
55336
|
+
if (dispatchAttempted) {
|
|
55337
|
+
rememberRecentPromptDispatch({
|
|
55338
|
+
sessionID,
|
|
55339
|
+
dedupeKey,
|
|
55340
|
+
source,
|
|
55341
|
+
holdMs: semanticDedupeHoldMs
|
|
55342
|
+
});
|
|
55343
|
+
}
|
|
55344
|
+
const errorText = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
55345
|
+
log(`[prompt-async-gate] ${sessionName} failed`, { sessionID, source, error: errorText });
|
|
55291
55346
|
return { status: "failed", error, dispatchAttempted };
|
|
55292
55347
|
} finally {
|
|
55293
55348
|
finishPromptReservation(sessionID, reservation, dispatchAttempted, postDispatchHoldMs);
|
|
@@ -55297,6 +55352,7 @@ var init_session_idle_dispatch = __esm(() => {
|
|
|
55297
55352
|
init_logger();
|
|
55298
55353
|
init_session_idle_settle();
|
|
55299
55354
|
init_pending_tool_turn();
|
|
55355
|
+
init_recent_dispatches();
|
|
55300
55356
|
init_reservations();
|
|
55301
55357
|
});
|
|
55302
55358
|
|
|
@@ -55404,6 +55460,7 @@ async function drainPromptQueue(sessionID, awaitedEntry) {
|
|
|
55404
55460
|
dedupeKey: entry.dedupeKey,
|
|
55405
55461
|
settleMs: entry.settleMs,
|
|
55406
55462
|
postDispatchHoldMs: entry.postDispatchHoldMs,
|
|
55463
|
+
semanticDedupeHoldMs: entry.semanticDedupeHoldMs,
|
|
55407
55464
|
dispatchTimeoutMs: entry.dispatchTimeoutMs,
|
|
55408
55465
|
checkStatus: entry.checkStatus,
|
|
55409
55466
|
checkToolState: entry.checkToolState,
|
|
@@ -55487,27 +55544,119 @@ var init_queue = __esm(() => {
|
|
|
55487
55544
|
});
|
|
55488
55545
|
});
|
|
55489
55546
|
|
|
55490
|
-
// src/shared/prompt-async-gate.ts
|
|
55547
|
+
// src/shared/prompt-async-gate/semantic-dedupe.ts
|
|
55548
|
+
import { createHash } from "crypto";
|
|
55549
|
+
function isPlainRecord(value) {
|
|
55550
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
55551
|
+
return false;
|
|
55552
|
+
}
|
|
55553
|
+
const prototype = Object.getPrototypeOf(value);
|
|
55554
|
+
return prototype === Object.prototype || prototype === null;
|
|
55555
|
+
}
|
|
55556
|
+
function canonicalizePromptInputForDedupe(key, value, seen = new WeakSet, depth = 0) {
|
|
55557
|
+
if (key === "signal") {
|
|
55558
|
+
return "[AbortSignal]";
|
|
55559
|
+
}
|
|
55560
|
+
if (typeof value === "function") {
|
|
55561
|
+
return `[Function:${value.name}]`;
|
|
55562
|
+
}
|
|
55563
|
+
if (depth > MAX_PROMPT_DEDUPE_DEPTH) {
|
|
55564
|
+
return "[MaxDepth]";
|
|
55565
|
+
}
|
|
55566
|
+
if (Array.isArray(value)) {
|
|
55567
|
+
if (seen.has(value)) {
|
|
55568
|
+
return "[Circular]";
|
|
55569
|
+
}
|
|
55570
|
+
seen.add(value);
|
|
55571
|
+
try {
|
|
55572
|
+
return value.map((entry) => canonicalizePromptInputForDedupe("", entry, seen, depth + 1));
|
|
55573
|
+
} finally {
|
|
55574
|
+
seen.delete(value);
|
|
55575
|
+
}
|
|
55576
|
+
}
|
|
55577
|
+
if (!isPlainRecord(value)) {
|
|
55578
|
+
return value;
|
|
55579
|
+
}
|
|
55580
|
+
if (seen.has(value)) {
|
|
55581
|
+
return "[Circular]";
|
|
55582
|
+
}
|
|
55583
|
+
seen.add(value);
|
|
55584
|
+
try {
|
|
55585
|
+
const canonicalEntries = [];
|
|
55586
|
+
for (const entryKey of Object.keys(value).sort()) {
|
|
55587
|
+
canonicalEntries.push([
|
|
55588
|
+
entryKey,
|
|
55589
|
+
canonicalizePromptInputForDedupe(entryKey, value[entryKey], seen, depth + 1)
|
|
55590
|
+
]);
|
|
55591
|
+
}
|
|
55592
|
+
return Object.fromEntries(canonicalEntries);
|
|
55593
|
+
} finally {
|
|
55594
|
+
seen.delete(value);
|
|
55595
|
+
}
|
|
55596
|
+
}
|
|
55597
|
+
function isContinuationTextPartLike(value) {
|
|
55598
|
+
if (!isPlainRecord(value)) {
|
|
55599
|
+
return false;
|
|
55600
|
+
}
|
|
55601
|
+
if (value.type !== "text" || typeof value.text !== "string") {
|
|
55602
|
+
return false;
|
|
55603
|
+
}
|
|
55604
|
+
if (!hasInternalInitiatorMarker(value.text)) {
|
|
55605
|
+
return false;
|
|
55606
|
+
}
|
|
55607
|
+
if (!isPlainRecord(value.metadata)) {
|
|
55608
|
+
return false;
|
|
55609
|
+
}
|
|
55610
|
+
return value.metadata.compaction_continue === true;
|
|
55611
|
+
}
|
|
55612
|
+
function hasContinuationPromptIntent(input) {
|
|
55613
|
+
if (!isPlainRecord(input) || !isPlainRecord(input.body) || !Array.isArray(input.body.parts)) {
|
|
55614
|
+
return false;
|
|
55615
|
+
}
|
|
55616
|
+
return input.body.parts.some((part) => isContinuationTextPartLike(part));
|
|
55617
|
+
}
|
|
55618
|
+
function normalizePromptInputForSemanticDedupe(input) {
|
|
55619
|
+
if (hasContinuationPromptIntent(input)) {
|
|
55620
|
+
return {
|
|
55621
|
+
__omo_internal_intent: "continuation"
|
|
55622
|
+
};
|
|
55623
|
+
}
|
|
55624
|
+
return canonicalizePromptInputForDedupe("", input);
|
|
55625
|
+
}
|
|
55491
55626
|
function stringifyPromptInputForDedupe(input) {
|
|
55492
55627
|
try {
|
|
55493
|
-
const serialized = JSON.stringify(input
|
|
55494
|
-
if (key === "signal") {
|
|
55495
|
-
return "[AbortSignal]";
|
|
55496
|
-
}
|
|
55497
|
-
if (typeof value === "function") {
|
|
55498
|
-
return `[Function:${value.name}]`;
|
|
55499
|
-
}
|
|
55500
|
-
return value;
|
|
55501
|
-
});
|
|
55628
|
+
const serialized = JSON.stringify(normalizePromptInputForSemanticDedupe(input));
|
|
55502
55629
|
return serialized ?? String(input);
|
|
55503
|
-
} catch {
|
|
55504
|
-
|
|
55630
|
+
} catch (error) {
|
|
55631
|
+
const errorTag = error instanceof Error ? error.name : String(error);
|
|
55632
|
+
return `${String(input)}:[unserializable:${errorTag}]`;
|
|
55505
55633
|
}
|
|
55506
55634
|
}
|
|
55507
|
-
function
|
|
55635
|
+
function createSemanticPromptDedupeKey(input) {
|
|
55508
55636
|
const fingerprint = stringifyPromptInputForDedupe(input);
|
|
55509
|
-
|
|
55637
|
+
const digest = createHash("sha256").update(fingerprint, "utf8").digest("hex");
|
|
55638
|
+
return `semantic:${digest}`;
|
|
55510
55639
|
}
|
|
55640
|
+
function coalesceRecentSemanticPromptDispatch(args) {
|
|
55641
|
+
const recentDispatch = getRecentPromptDispatch(args.sessionID, args.dedupeKey);
|
|
55642
|
+
if (!recentDispatch) {
|
|
55643
|
+
return;
|
|
55644
|
+
}
|
|
55645
|
+
log("[prompt-async-gate] prompt coalesced with recent semantic dispatch", {
|
|
55646
|
+
sessionID: args.sessionID,
|
|
55647
|
+
source: args.source,
|
|
55648
|
+
queuedBy: recentDispatch.source
|
|
55649
|
+
});
|
|
55650
|
+
return { status: "queued", queuedBy: recentDispatch.source, position: 0 };
|
|
55651
|
+
}
|
|
55652
|
+
var MAX_PROMPT_DEDUPE_DEPTH = 64;
|
|
55653
|
+
var init_semantic_dedupe = __esm(() => {
|
|
55654
|
+
init_internal_initiator_marker();
|
|
55655
|
+
init_logger();
|
|
55656
|
+
init_recent_dispatches();
|
|
55657
|
+
});
|
|
55658
|
+
|
|
55659
|
+
// src/shared/prompt-async-gate.ts
|
|
55511
55660
|
function hasObjectSessionPath(input) {
|
|
55512
55661
|
return typeof input === "object" && input !== null && "path" in input && typeof input.path === "object" && input.path !== null && "id" in input.path && typeof input.path.id === "string";
|
|
55513
55662
|
}
|
|
@@ -55537,9 +55686,10 @@ async function dispatchInternalPrompt(args) {
|
|
|
55537
55686
|
source,
|
|
55538
55687
|
settleMs = DEFAULT_SESSION_IDLE_SETTLE_MS
|
|
55539
55688
|
} = args;
|
|
55540
|
-
const dedupeKey = args.dedupeKey ??
|
|
55689
|
+
const dedupeKey = args.dedupeKey ?? createSemanticPromptDedupeKey(input);
|
|
55541
55690
|
const queueRetryMs = args.queueRetryMs ?? DEFAULT_PROMPT_QUEUE_RETRY_MS;
|
|
55542
55691
|
const postDispatchHoldMs = args.postDispatchHoldMs ?? DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS;
|
|
55692
|
+
const semanticDedupeHoldMs = args.semanticDedupeHoldMs ?? (postDispatchHoldMs > 0 ? DEFAULT_PROMPT_SEMANTIC_DEDUPE_HOLD_MS : 0);
|
|
55543
55693
|
const dispatchTimeoutMs = args.dispatchTimeoutMs ?? DEFAULT_PROMPT_DISPATCH_TIMEOUT_MS;
|
|
55544
55694
|
const sessionName = args.mode === "async" ? "promptAsync" : "prompt";
|
|
55545
55695
|
const dispatch = (() => {
|
|
@@ -55572,6 +55722,10 @@ async function dispatchInternalPrompt(args) {
|
|
|
55572
55722
|
if (queuedBy !== undefined || isPromptQueueDraining(sessionID)) {
|
|
55573
55723
|
return { status: "reserved", reservedBy: queuedBy ?? source };
|
|
55574
55724
|
}
|
|
55725
|
+
const recentDispatchResult2 = coalesceRecentSemanticPromptDispatch({ sessionID, dedupeKey, source });
|
|
55726
|
+
if (recentDispatchResult2) {
|
|
55727
|
+
return recentDispatchResult2;
|
|
55728
|
+
}
|
|
55575
55729
|
return dispatchAfterSessionIdle({
|
|
55576
55730
|
sessionName,
|
|
55577
55731
|
client,
|
|
@@ -55581,6 +55735,7 @@ async function dispatchInternalPrompt(args) {
|
|
|
55581
55735
|
dedupeKey,
|
|
55582
55736
|
settleMs,
|
|
55583
55737
|
postDispatchHoldMs,
|
|
55738
|
+
semanticDedupeHoldMs,
|
|
55584
55739
|
dispatchTimeoutMs,
|
|
55585
55740
|
checkStatus: args.checkStatus !== false,
|
|
55586
55741
|
checkToolState: args.checkToolState !== false,
|
|
@@ -55588,6 +55743,10 @@ async function dispatchInternalPrompt(args) {
|
|
|
55588
55743
|
});
|
|
55589
55744
|
}
|
|
55590
55745
|
if (args.queue !== false) {
|
|
55746
|
+
const recentDispatchResult2 = coalesceRecentSemanticPromptDispatch({ sessionID, dedupeKey, source });
|
|
55747
|
+
if (recentDispatchResult2) {
|
|
55748
|
+
return recentDispatchResult2;
|
|
55749
|
+
}
|
|
55591
55750
|
return enqueueInternalPrompt({
|
|
55592
55751
|
id: nextPromptQueueID(),
|
|
55593
55752
|
sessionID,
|
|
@@ -55598,6 +55757,7 @@ async function dispatchInternalPrompt(args) {
|
|
|
55598
55757
|
dedupeKey,
|
|
55599
55758
|
settleMs,
|
|
55600
55759
|
postDispatchHoldMs,
|
|
55760
|
+
semanticDedupeHoldMs,
|
|
55601
55761
|
dispatchTimeoutMs,
|
|
55602
55762
|
queueRetryMs,
|
|
55603
55763
|
checkStatus: args.checkStatus !== false,
|
|
@@ -55605,6 +55765,10 @@ async function dispatchInternalPrompt(args) {
|
|
|
55605
55765
|
dispatch: async (_dispatchInput) => dispatchWithPathCompatibility(dispatch, input)
|
|
55606
55766
|
});
|
|
55607
55767
|
}
|
|
55768
|
+
const recentDispatchResult = coalesceRecentSemanticPromptDispatch({ sessionID, dedupeKey, source });
|
|
55769
|
+
if (recentDispatchResult) {
|
|
55770
|
+
return recentDispatchResult;
|
|
55771
|
+
}
|
|
55608
55772
|
return dispatchAfterSessionIdle({
|
|
55609
55773
|
sessionName,
|
|
55610
55774
|
client,
|
|
@@ -55614,6 +55778,7 @@ async function dispatchInternalPrompt(args) {
|
|
|
55614
55778
|
dedupeKey,
|
|
55615
55779
|
settleMs,
|
|
55616
55780
|
postDispatchHoldMs,
|
|
55781
|
+
semanticDedupeHoldMs,
|
|
55617
55782
|
dispatchTimeoutMs,
|
|
55618
55783
|
checkStatus: args.checkStatus !== false,
|
|
55619
55784
|
checkToolState: args.checkToolState !== false,
|
|
@@ -55638,6 +55803,7 @@ function releasePromptAsyncReservation(sessionID, source, options) {
|
|
|
55638
55803
|
return false;
|
|
55639
55804
|
}
|
|
55640
55805
|
deletePromptReservation(sessionID);
|
|
55806
|
+
deleteRecentPromptDispatch(sessionID, existing.dedupeKey);
|
|
55641
55807
|
releaseInFlightPromptMatchingDedupe(sessionID, existing.dedupeKey);
|
|
55642
55808
|
schedulePromptQueueDrain(sessionID, 0);
|
|
55643
55809
|
log("[prompt-async-gate] promptAsync reservation released", {
|
|
@@ -55651,8 +55817,10 @@ var init_prompt_async_gate = __esm(() => {
|
|
|
55651
55817
|
init_logger();
|
|
55652
55818
|
init_session_idle_settle();
|
|
55653
55819
|
init_queue();
|
|
55820
|
+
init_recent_dispatches();
|
|
55654
55821
|
init_reservations();
|
|
55655
55822
|
init_session_idle_dispatch();
|
|
55823
|
+
init_semantic_dedupe();
|
|
55656
55824
|
});
|
|
55657
55825
|
|
|
55658
55826
|
// src/shared/prompt-failure-classifier.ts
|
|
@@ -69458,80 +69626,6 @@ function createTodoContinuationEnforcer(ctx, options = {}) {
|
|
|
69458
69626
|
dispose: () => sessionStateStore.shutdown()
|
|
69459
69627
|
};
|
|
69460
69628
|
}
|
|
69461
|
-
// src/hooks/context-window-monitor.ts
|
|
69462
|
-
init_context_limit_resolver2();
|
|
69463
|
-
init_compaction_marker();
|
|
69464
|
-
init_event_session_id();
|
|
69465
|
-
init_system_directive();
|
|
69466
|
-
var CONTEXT_WARNING_THRESHOLD = 0.7;
|
|
69467
|
-
function createContextReminder(actualLimit) {
|
|
69468
|
-
const limitTokens = actualLimit.toLocaleString();
|
|
69469
|
-
return `${createSystemDirective(SystemDirectiveTypes.CONTEXT_WINDOW_MONITOR)}
|
|
69470
|
-
|
|
69471
|
-
You are using a ${limitTokens}-token context window.
|
|
69472
|
-
You still have context remaining - do NOT rush or skip tasks.
|
|
69473
|
-
Complete your work thoroughly and methodically.`;
|
|
69474
|
-
}
|
|
69475
|
-
function createContextWindowMonitorHook(_ctx, modelCacheState) {
|
|
69476
|
-
const remindedSessions = new Set;
|
|
69477
|
-
const tokenCache = new Map;
|
|
69478
|
-
const toolExecuteAfter = async (input, output) => {
|
|
69479
|
-
const { sessionID } = input;
|
|
69480
|
-
if (remindedSessions.has(sessionID))
|
|
69481
|
-
return;
|
|
69482
|
-
const cached2 = tokenCache.get(sessionID);
|
|
69483
|
-
if (!cached2)
|
|
69484
|
-
return;
|
|
69485
|
-
const actualLimit = resolveActualContextLimit(cached2.providerID, cached2.modelID, modelCacheState);
|
|
69486
|
-
if (!actualLimit)
|
|
69487
|
-
return;
|
|
69488
|
-
const lastTokens = cached2.tokens;
|
|
69489
|
-
const totalInputTokens = (lastTokens?.input ?? 0) + (lastTokens?.cache?.read ?? 0);
|
|
69490
|
-
const actualUsagePercentage = totalInputTokens / actualLimit;
|
|
69491
|
-
if (actualUsagePercentage < CONTEXT_WARNING_THRESHOLD)
|
|
69492
|
-
return;
|
|
69493
|
-
remindedSessions.add(sessionID);
|
|
69494
|
-
const clampedPercentage = Math.min(Math.max(actualUsagePercentage, 0), 1);
|
|
69495
|
-
const usedPct = (clampedPercentage * 100).toFixed(1);
|
|
69496
|
-
const remainingPct = ((1 - clampedPercentage) * 100).toFixed(1);
|
|
69497
|
-
const usedTokens = totalInputTokens.toLocaleString();
|
|
69498
|
-
const limitTokens = actualLimit.toLocaleString();
|
|
69499
|
-
output.output += `
|
|
69500
|
-
|
|
69501
|
-
${createContextReminder(actualLimit)}
|
|
69502
|
-
[Context Status: ${usedPct}% used (${usedTokens}/${limitTokens} tokens), ${remainingPct}% remaining]`;
|
|
69503
|
-
};
|
|
69504
|
-
const eventHandler = async ({ event }) => {
|
|
69505
|
-
const props = event.properties;
|
|
69506
|
-
if (event.type === "session.deleted") {
|
|
69507
|
-
const sessionID = resolveSessionEventID(props);
|
|
69508
|
-
if (sessionID) {
|
|
69509
|
-
remindedSessions.delete(sessionID);
|
|
69510
|
-
tokenCache.delete(sessionID);
|
|
69511
|
-
}
|
|
69512
|
-
}
|
|
69513
|
-
if (event.type === "message.updated") {
|
|
69514
|
-
const info = props?.info;
|
|
69515
|
-
const finish = info?.finish;
|
|
69516
|
-
if (!info || info.role !== "assistant" || !finish)
|
|
69517
|
-
return;
|
|
69518
|
-
if (isCompactionAgent(info.agent))
|
|
69519
|
-
return;
|
|
69520
|
-
const sessionID = resolveMessageEventSessionID(props);
|
|
69521
|
-
if (!sessionID || !info.providerID || !info.tokens)
|
|
69522
|
-
return;
|
|
69523
|
-
tokenCache.set(sessionID, {
|
|
69524
|
-
providerID: info.providerID,
|
|
69525
|
-
modelID: info.modelID ?? "",
|
|
69526
|
-
tokens: info.tokens
|
|
69527
|
-
});
|
|
69528
|
-
}
|
|
69529
|
-
};
|
|
69530
|
-
return {
|
|
69531
|
-
"tool.execute.after": toolExecuteAfter,
|
|
69532
|
-
event: eventHandler
|
|
69533
|
-
};
|
|
69534
|
-
}
|
|
69535
69629
|
// src/hooks/session-notification-content.ts
|
|
69536
69630
|
init_shared();
|
|
69537
69631
|
function extractMessageText(message) {
|
|
@@ -72900,7 +72994,7 @@ function findClosingDelimiter(content, openingLength) {
|
|
|
72900
72994
|
}
|
|
72901
72995
|
// packages/rules-engine/src/matcher.ts
|
|
72902
72996
|
var import_picomatch = __toESM(require_picomatch2(), 1);
|
|
72903
|
-
import { createHash } from "crypto";
|
|
72997
|
+
import { createHash as createHash2 } from "crypto";
|
|
72904
72998
|
import { basename as basename6, relative as relative8 } from "path";
|
|
72905
72999
|
var matcherCache = new Map;
|
|
72906
73000
|
var MAX_MATCHER_CACHE_ENTRIES = 256;
|
|
@@ -72929,7 +73023,7 @@ function shouldApplyRule(metadata, currentFilePath, projectRoot) {
|
|
|
72929
73023
|
return { applies: false };
|
|
72930
73024
|
}
|
|
72931
73025
|
function createContentHash(content) {
|
|
72932
|
-
return
|
|
73026
|
+
return createHash2("sha256").update(content).digest("hex").slice(0, 16);
|
|
72933
73027
|
}
|
|
72934
73028
|
function isDuplicateByRealPath(realPath, cache) {
|
|
72935
73029
|
return cache.has(realPath);
|
|
@@ -91169,6 +91263,12 @@ var initDeepSkill = {
|
|
|
91169
91263
|
template: loadSharedSkillTemplate("init-deep"),
|
|
91170
91264
|
argumentHint: "[--create-new] [--max-depth=N]"
|
|
91171
91265
|
};
|
|
91266
|
+
// src/features/builtin-skills/skills/debugging.ts
|
|
91267
|
+
var debuggingSkill = {
|
|
91268
|
+
name: "debugging",
|
|
91269
|
+
description: "MUST USE for any real runtime debugging across ANY language or binary \u2014 crashes, silent failures, wrong responses, stuck processes, memory leaks, async misbehavior, unexplained timing, reverse engineering. Runs a hypothesis-driven loop: form \u22653 hypotheses, investigate in parallel, after 2 failed rounds spawn Oracles from orthogonal angles, confirm root cause, lock with a failing test, fix minimally, QA by actually USING the system, scrub artifacts. The actual HOW lives in `references/` \u2014 READ THEM. Triggers: 'debug this', 'why is X not working', 'hanging', 'attach a debugger', 'reverse engineer', 'pwndbg', 'gdb', 'lldb', 'node inspect', 'tsx debug', 'pdb', 'dlv', 'delve', 'rust-gdb', 'set a breakpoint', 'context window exploded', 'why is the response empty', 'attach the debugger', 'debug it', 'why is this happening', 'trace this bug', 'reproduce and fix', 'silent failure', 'HTTP 200 but empty', 'why did it stop', 'inspect the binary', 'reverse engineering', 'playwright'.",
|
|
91270
|
+
template: loadSharedSkillTemplate("debugging")
|
|
91271
|
+
};
|
|
91172
91272
|
// src/features/builtin-skills/security-research/SKILL.md
|
|
91173
91273
|
var SKILL_default = `# Security Research - Team Mode Vulnerability Audit
|
|
91174
91274
|
|
|
@@ -91604,6 +91704,7 @@ function createBuiltinSkills(options = {}) {
|
|
|
91604
91704
|
reviewWorkSkill,
|
|
91605
91705
|
removeAiSlopsSkill,
|
|
91606
91706
|
initDeepSkill,
|
|
91707
|
+
debuggingSkill,
|
|
91607
91708
|
securityResearchSkill,
|
|
91608
91709
|
securityReviewSkill
|
|
91609
91710
|
];
|
|
@@ -92008,7 +92109,6 @@ var GitMasterConfigSchema = z17.object({
|
|
|
92008
92109
|
import { z as z18 } from "zod";
|
|
92009
92110
|
var HookNameSchema = z18.enum([
|
|
92010
92111
|
"todo-continuation-enforcer",
|
|
92011
|
-
"context-window-monitor",
|
|
92012
92112
|
"session-recovery",
|
|
92013
92113
|
"session-notification",
|
|
92014
92114
|
"comment-checker",
|
|
@@ -114387,7 +114487,6 @@ function createRuntimeTmuxConfig(pluginConfig) {
|
|
|
114387
114487
|
function createSessionHooks(args) {
|
|
114388
114488
|
const { ctx, pluginConfig, modelCacheState, backgroundManager, modelFallbackControllerAccessor, isHookEnabled, safeHookEnabled } = args;
|
|
114389
114489
|
const safeHook = (hookName, factory) => safeCreateHook(hookName, factory, { enabled: safeHookEnabled });
|
|
114390
|
-
const contextWindowMonitor = isHookEnabled("context-window-monitor") ? safeHook("context-window-monitor", () => createContextWindowMonitorHook(ctx, modelCacheState)) : null;
|
|
114391
114490
|
const preemptiveCompaction = isHookEnabled("preemptive-compaction") && pluginConfig.experimental?.preemptive_compaction ? safeHook("preemptive-compaction", () => createPreemptiveCompactionHook(ctx, pluginConfig, modelCacheState)) : null;
|
|
114392
114491
|
const sessionRecovery = isHookEnabled("session-recovery") ? safeHook("session-recovery", () => createSessionRecoveryHook(ctx, { experimental: pluginConfig.experimental })) : null;
|
|
114393
114492
|
let sessionNotification = null;
|
|
@@ -114485,7 +114584,6 @@ function createSessionHooks(args) {
|
|
|
114485
114584
|
})) : null;
|
|
114486
114585
|
const legacyPluginToast = isHookEnabled("legacy-plugin-toast") ? safeHook("legacy-plugin-toast", () => createLegacyPluginToastHook(ctx)) : null;
|
|
114487
114586
|
return {
|
|
114488
|
-
contextWindowMonitor,
|
|
114489
114587
|
preemptiveCompaction,
|
|
114490
114588
|
sessionRecovery,
|
|
114491
114589
|
sessionNotification,
|
|
@@ -116063,7 +116161,8 @@ class ParentWakeNotifier {
|
|
|
116063
116161
|
const role = this.getParentWakeMessageRole(message);
|
|
116064
116162
|
if (role === "assistant") {
|
|
116065
116163
|
const waiting = this.getParentWakeMessageFinish(message) === "tool-calls" || message.parts?.some((part) => this.parentWakePartIsWaitingOnTool(part)) === true;
|
|
116066
|
-
|
|
116164
|
+
const activityAt = getParentWakeMessageActivityAt(message);
|
|
116165
|
+
return waiting ? { waiting: true, activityAt } : { waiting: false, activityAt };
|
|
116067
116166
|
}
|
|
116068
116167
|
if (role === "user") {
|
|
116069
116168
|
if (isSyntheticOrInternalUserMessage(message)) {
|
|
@@ -116162,16 +116261,18 @@ class ParentWakeNotifier {
|
|
|
116162
116261
|
}
|
|
116163
116262
|
const latestToolWaitAgeMs = toolWaitState.activityAt === undefined ? 0 : now - toolWaitState.activityAt;
|
|
116164
116263
|
const deferAge = now - wake.toolCallDeferralStartedAt;
|
|
116264
|
+
const latestAssistantActivityAgeMs = toolWaitState.activityAt === undefined ? deferAge : now - toolWaitState.activityAt;
|
|
116165
116265
|
if (wake.shouldReply && toolWaitState.waiting && deferAge >= this.options.toolCallDeferMaxMs && latestToolWaitAgeMs >= this.options.toolCallDeferMaxMs) {
|
|
116166
116266
|
log("[background-agent] Sending parent wake after stale tool-call deferral window:", {
|
|
116167
116267
|
sessionID
|
|
116168
116268
|
});
|
|
116169
116269
|
return { defer: false, skipPromptGateToolStateCheck: true };
|
|
116170
116270
|
}
|
|
116171
|
-
if (!toolWaitState.waiting && deferAge >= this.options.toolCallDeferMaxMs) {
|
|
116271
|
+
if (!toolWaitState.waiting && deferAge >= this.options.toolCallDeferMaxMs && latestAssistantActivityAgeMs >= this.options.toolCallDeferMaxMs) {
|
|
116172
116272
|
log("[background-agent] Sending parent wake after stale assistant-text deferral window:", {
|
|
116173
116273
|
sessionID,
|
|
116174
|
-
deferAgeMs: deferAge
|
|
116274
|
+
deferAgeMs: deferAge,
|
|
116275
|
+
latestAssistantActivityAgeMs
|
|
116175
116276
|
});
|
|
116176
116277
|
return { defer: false, skipPromptGateToolStateCheck: true };
|
|
116177
116278
|
}
|
|
@@ -119692,13 +119793,13 @@ async function findAvailablePort2(startPort = DEFAULT_PORT) {
|
|
|
119692
119793
|
|
|
119693
119794
|
// src/features/mcp-oauth/oauth-authorization-flow.ts
|
|
119694
119795
|
import { spawn as spawn3 } from "child_process";
|
|
119695
|
-
import { createHash as
|
|
119796
|
+
import { createHash as createHash3, randomBytes as randomBytes2 } from "crypto";
|
|
119696
119797
|
import { createServer as createServer2 } from "http";
|
|
119697
119798
|
function generateCodeVerifier() {
|
|
119698
119799
|
return randomBytes2(32).toString("base64url");
|
|
119699
119800
|
}
|
|
119700
119801
|
function generateCodeChallenge(verifier) {
|
|
119701
|
-
return
|
|
119802
|
+
return createHash3("sha256").update(verifier).digest("base64url");
|
|
119702
119803
|
}
|
|
119703
119804
|
function buildAuthorizationUrl(authorizationEndpoint, options) {
|
|
119704
119805
|
const url = new URL(authorizationEndpoint);
|
|
@@ -140762,11 +140863,17 @@ init_model_normalization();
|
|
|
140762
140863
|
var ASSISTANT_PREFILL_RECOVERY_TEXT = "[internal] Continue from the previous assistant state.";
|
|
140763
140864
|
var ASSISTANT_PREFILL_UNSUPPORTED_PROVIDERS = new Set([
|
|
140764
140865
|
"anthropic",
|
|
140765
|
-
"
|
|
140866
|
+
"aws-bedrock-anthropic",
|
|
140867
|
+
"github-copilot",
|
|
140868
|
+
"github-copilot-enterprise",
|
|
140869
|
+
"google-vertex-anthropic",
|
|
140870
|
+
"opencode",
|
|
140871
|
+
"opencode-go",
|
|
140872
|
+
"opencode-zen-proxy",
|
|
140873
|
+
"vercel"
|
|
140766
140874
|
]);
|
|
140767
140875
|
var ASSISTANT_PREFILL_UNSUPPORTED_MODEL_PREFIXES = [
|
|
140768
|
-
"claude-opus-4
|
|
140769
|
-
"claude-opus-4-6",
|
|
140876
|
+
"claude-opus-4",
|
|
140770
140877
|
"claude-sonnet-4-6",
|
|
140771
140878
|
"claude-mythos"
|
|
140772
140879
|
];
|
|
@@ -140817,15 +140924,26 @@ function findLastUserModel(messages) {
|
|
|
140817
140924
|
}
|
|
140818
140925
|
return;
|
|
140819
140926
|
}
|
|
140927
|
+
function normalizeAssistantPrefillModelID(modelID) {
|
|
140928
|
+
const normalizedModelID = normalizeModelID(modelID.toLowerCase());
|
|
140929
|
+
return normalizedModelID.split(/[/.~:@]+/).find((segment) => segment.startsWith("claude-")) ?? normalizedModelID;
|
|
140930
|
+
}
|
|
140931
|
+
function hasAnthropicModelNamespace(modelID) {
|
|
140932
|
+
const normalizedModelID = normalizeModelID(modelID.toLowerCase());
|
|
140933
|
+
return /(?:^|[/.~:@])anthropic(?:$|[/.~:@])/.test(normalizedModelID);
|
|
140934
|
+
}
|
|
140935
|
+
function providerCanExposeUnsupportedAssistantPrefill(providerID, modelID) {
|
|
140936
|
+
return ASSISTANT_PREFILL_UNSUPPORTED_PROVIDERS.has(providerID) || hasAnthropicModelNamespace(modelID);
|
|
140937
|
+
}
|
|
140820
140938
|
function shouldRepairAssistantPrefillForModel(model) {
|
|
140821
140939
|
if (!model) {
|
|
140822
140940
|
return false;
|
|
140823
140941
|
}
|
|
140824
140942
|
const providerID = model.providerID.toLowerCase();
|
|
140825
|
-
if (!
|
|
140943
|
+
if (!providerCanExposeUnsupportedAssistantPrefill(providerID, model.modelID)) {
|
|
140826
140944
|
return false;
|
|
140827
140945
|
}
|
|
140828
|
-
const modelID =
|
|
140946
|
+
const modelID = normalizeAssistantPrefillModelID(model.modelID);
|
|
140829
140947
|
return ASSISTANT_PREFILL_UNSUPPORTED_MODEL_PREFIXES.some((prefix) => modelID.startsWith(prefix));
|
|
140830
140948
|
}
|
|
140831
140949
|
function isCompactionContinuationPart(part) {
|
|
@@ -140886,9 +141004,10 @@ async function runMessagesTransformHookSafely(hookName, handler, input, output)
|
|
|
140886
141004
|
try {
|
|
140887
141005
|
await Promise.resolve(handler(input, output));
|
|
140888
141006
|
} catch (error) {
|
|
141007
|
+
const hookError = error instanceof Error ? error : new Error(String(error));
|
|
140889
141008
|
log("[messages-transform] hook execution failed", {
|
|
140890
141009
|
hook: hookName,
|
|
140891
|
-
error
|
|
141010
|
+
error: hookError
|
|
140892
141011
|
});
|
|
140893
141012
|
}
|
|
140894
141013
|
}
|
|
@@ -141514,6 +141633,33 @@ function normalizeSessionStatusToIdle(input) {
|
|
|
141514
141633
|
|
|
141515
141634
|
// src/plugin/event.ts
|
|
141516
141635
|
init_event_session_id();
|
|
141636
|
+
|
|
141637
|
+
// src/plugin/user-abort-interrupted-recovery-guard.ts
|
|
141638
|
+
var USER_ABORT_ERROR_NAMES = new Set(["MessageAbortedError", "AbortError"]);
|
|
141639
|
+
function createUserAbortInterruptedRecoveryGuard() {
|
|
141640
|
+
const abortedSessions = new Set;
|
|
141641
|
+
return {
|
|
141642
|
+
noteSessionError(sessionID, errorName) {
|
|
141643
|
+
if (!errorName || !USER_ABORT_ERROR_NAMES.has(errorName)) {
|
|
141644
|
+
return false;
|
|
141645
|
+
}
|
|
141646
|
+
abortedSessions.add(sessionID);
|
|
141647
|
+
return true;
|
|
141648
|
+
},
|
|
141649
|
+
shouldSkipRecovery(sessionID) {
|
|
141650
|
+
const shouldSkip = abortedSessions.has(sessionID);
|
|
141651
|
+
if (shouldSkip) {
|
|
141652
|
+
abortedSessions.delete(sessionID);
|
|
141653
|
+
}
|
|
141654
|
+
return shouldSkip;
|
|
141655
|
+
},
|
|
141656
|
+
clear(sessionID) {
|
|
141657
|
+
abortedSessions.delete(sessionID);
|
|
141658
|
+
}
|
|
141659
|
+
};
|
|
141660
|
+
}
|
|
141661
|
+
|
|
141662
|
+
// src/plugin/event.ts
|
|
141517
141663
|
function isRecord26(value) {
|
|
141518
141664
|
return typeof value === "object" && value !== null;
|
|
141519
141665
|
}
|
|
@@ -141598,6 +141744,7 @@ function createEventHandler2(args) {
|
|
|
141598
141744
|
const lastKnownModelBySession = new Map;
|
|
141599
141745
|
const modelFallbackContinuationsInFlight = new Set;
|
|
141600
141746
|
const lastDispatchedModelFallbackContinuationKeys = new Map;
|
|
141747
|
+
const userAbortInterruptedRecoveryGuard = createUserAbortInterruptedRecoveryGuard();
|
|
141601
141748
|
const resolveFallbackProviderID = (sessionID, providerHint) => {
|
|
141602
141749
|
const normalizedProviderHint = providerHint?.trim();
|
|
141603
141750
|
if (normalizedProviderHint) {
|
|
@@ -141651,7 +141798,6 @@ function createEventHandler2(args) {
|
|
|
141651
141798
|
await runEventHookSafely("sessionNotification", hooks2.sessionNotification, input);
|
|
141652
141799
|
await runEventHookSafely("todoContinuationEnforcer", hooks2.todoContinuationEnforcer?.handler, input);
|
|
141653
141800
|
await runEventHookSafely("unstableAgentBabysitter", hooks2.unstableAgentBabysitter?.event, input);
|
|
141654
|
-
await runEventHookSafely("contextWindowMonitor", hooks2.contextWindowMonitor?.event, input);
|
|
141655
141801
|
await runEventHookSafely("preemptiveCompaction", hooks2.preemptiveCompaction?.event, input);
|
|
141656
141802
|
await runEventHookSafely("directoryAgentsInjector", hooks2.directoryAgentsInjector?.event, input);
|
|
141657
141803
|
await runEventHookSafely("directoryReadmeInjector", hooks2.directoryReadmeInjector?.event, input);
|
|
@@ -141713,6 +141859,10 @@ function createEventHandler2(args) {
|
|
|
141713
141859
|
if (!sessionID || !hooks2.sessionRecovery?.handleInterruptedToolResultsOnIdle) {
|
|
141714
141860
|
return false;
|
|
141715
141861
|
}
|
|
141862
|
+
if (userAbortInterruptedRecoveryGuard.shouldSkipRecovery(sessionID)) {
|
|
141863
|
+
log("[event] interrupted tool recovery skipped after user abort", { sessionID });
|
|
141864
|
+
return false;
|
|
141865
|
+
}
|
|
141716
141866
|
return hooks2.sessionRecovery.handleInterruptedToolResultsOnIdle(sessionID);
|
|
141717
141867
|
};
|
|
141718
141868
|
const dispatchIdleOnlyHooks = async (input) => {
|
|
@@ -141872,10 +142022,6 @@ function createEventHandler2(args) {
|
|
|
141872
142022
|
const emittedAt = recentSyntheticIdles.get(sessionID);
|
|
141873
142023
|
if (emittedAt !== undefined && now - emittedAt < DEDUP_WINDOW_MS2) {
|
|
141874
142024
|
recentSyntheticIdles.delete(sessionID);
|
|
141875
|
-
const lastAnyIdleAt = recentAnyIdles.get(sessionID);
|
|
141876
|
-
if (lastAnyIdleAt === emittedAt) {
|
|
141877
|
-
recentAnyIdles.delete(sessionID);
|
|
141878
|
-
}
|
|
141879
142025
|
}
|
|
141880
142026
|
}
|
|
141881
142027
|
const recovered = await recoverInterruptedToolResultsOnIdleEvent(input);
|
|
@@ -141964,6 +142110,7 @@ function createEventHandler2(args) {
|
|
|
141964
142110
|
lastKnownModelBySession.delete(sessionID);
|
|
141965
142111
|
modelFallbackContinuationsInFlight.delete(sessionID);
|
|
141966
142112
|
lastDispatchedModelFallbackContinuationKeys.delete(sessionID);
|
|
142113
|
+
userAbortInterruptedRecoveryGuard.clear(sessionID);
|
|
141967
142114
|
if (modelFallback) {
|
|
141968
142115
|
clearPendingModelFallback(modelFallback, sessionID);
|
|
141969
142116
|
clearSessionFallbackChain(modelFallback, sessionID);
|
|
@@ -142042,6 +142189,10 @@ function createEventHandler2(args) {
|
|
|
142042
142189
|
lastKnownModelBySession.set(sessionID, { providerID, modelID });
|
|
142043
142190
|
setSessionModel(sessionID, { providerID, modelID });
|
|
142044
142191
|
}
|
|
142192
|
+
userAbortInterruptedRecoveryGuard.clear(sessionID);
|
|
142193
|
+
}
|
|
142194
|
+
if (sessionID && role === "assistant") {
|
|
142195
|
+
userAbortInterruptedRecoveryGuard.noteSessionError(sessionID, extractErrorName3(info?.error));
|
|
142045
142196
|
}
|
|
142046
142197
|
if (sessionID && role === "assistant" && !isRuntimeFallbackEnabled && isModelFallbackEnabled) {
|
|
142047
142198
|
try {
|
|
@@ -142157,6 +142308,9 @@ function createEventHandler2(args) {
|
|
|
142157
142308
|
const errorName = extractErrorName3(error);
|
|
142158
142309
|
const errorMessage = extractErrorMessage3(error);
|
|
142159
142310
|
const errorInfo = { name: errorName, message: errorMessage };
|
|
142311
|
+
if (sessionID) {
|
|
142312
|
+
userAbortInterruptedRecoveryGuard.noteSessionError(sessionID, errorName);
|
|
142313
|
+
}
|
|
142160
142314
|
if (hooks2.sessionRecovery?.isRecoverableError(error)) {
|
|
142161
142315
|
const messageInfo = {
|
|
142162
142316
|
id: props?.messageID,
|
|
@@ -142356,7 +142510,6 @@ function createToolExecuteAfterHandler3(args) {
|
|
|
142356
142510
|
await hooks2.toolOutputTruncator?.["tool.execute.after"]?.(hookInput, output);
|
|
142357
142511
|
await hooks2.claudeCodeHooks?.["tool.execute.after"]?.(hookInput, output);
|
|
142358
142512
|
await hooks2.preemptiveCompaction?.["tool.execute.after"]?.(hookInput, output);
|
|
142359
|
-
await hooks2.contextWindowMonitor?.["tool.execute.after"]?.(hookInput, output);
|
|
142360
142513
|
await hooks2.commentChecker?.["tool.execute.after"]?.(hookInput, output);
|
|
142361
142514
|
await hooks2.directoryAgentsInjector?.["tool.execute.after"]?.(hookInput, output);
|
|
142362
142515
|
await hooks2.directoryReadmeInjector?.["tool.execute.after"]?.(hookInput, output);
|