github-router 0.3.229 → 0.3.238
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 +12 -0
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/{engine-v9-pEKoD.js → engine-5VxiBAdY.js} +4 -4
- package/dist/{lifecycle-D-1CYr1Y.js → lifecycle-C-9_vhyM.js} +30 -3
- package/dist/lifecycle-C-9_vhyM.js.map +1 -0
- package/dist/{lifecycle-bPdiXjYB.js → lifecycle-Cuuj40CW.js} +2 -2
- package/dist/{lifecycle-bPdiXjYB.js.map → lifecycle-Cuuj40CW.js.map} +1 -1
- package/dist/{lifecycle-Ci81s6eL.js → lifecycle-DF2ygqz8.js} +2 -2
- package/dist/{lifecycle-CJV1XBFP.js → lifecycle-wIIt0wGo.js} +2 -2
- package/dist/main.js +175 -37
- package/dist/main.js.map +1 -1
- package/dist/{paths-B5k78n0d.js → paths-C75DZ_Y3.js} +1 -1
- package/dist/{paths-BO22pMUb.js → paths-Srxs-aR-.js} +30 -4
- package/dist/{paths-BO22pMUb.js.map → paths-Srxs-aR-.js.map} +1 -1
- package/dist/{peer-mcp-personas-BKwMCOsl.js → peer-mcp-personas-CDja7arT.js} +152 -36
- package/dist/{peer-mcp-personas-BKwMCOsl.js.map → peer-mcp-personas-CDja7arT.js.map} +1 -1
- package/package.json +1 -1
- package/dist/lifecycle-D-1CYr1Y.js.map +0 -1
package/dist/main.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as searchWeb, $t as
|
|
3
|
-
import { a as isUnderClaudeConfigMirror, d as writeRuntimeFileSecure, i as ensurePaths, o as removeOwnClaudeConfigMirror, r as ensureClaudeConfigMirror, t as PATHS, u as writeArtifactCredsToMirror } from "./paths-
|
|
4
|
-
import { c as killManagedTree, d as
|
|
5
|
-
import { a as sweepRegistry } from "./lifecycle-
|
|
2
|
+
import { $ as searchWeb, $t as DEFAULT_CLAUDE_MODEL_FALLBACKS, A as trustRepo, An as state, At as getTokenCount, Bt as hasSupportedBrowserInstalled, C as fileLastPromptStore, Cn as fetchWithTransientRetry, Ct as scoutModel, D as repoRoot, Dn as copilotBaseUrl, Dt as shimDefaultsToXhigh, E as repoFingerprint, En as GITHUB_API_BASE_URL, Et as workerToolsEnabled, Ft as createChatCompletions, G as buildEnv, Gt as CONDENSED_OPERATING_SEQUENCE, Ht as extractTarGzMember, It as MAX_RESPONSE_BODY_BYTES, J as toolbeltEnabled, Jt as ArtifactClient, K as availableToolCommands, Kt as DEFINITION_OF_GREATNESS, Lt as readResponseBodyCapped, M as resolveSealedGate, Mt as resolveMcpToolTimeoutMs, Nt as pickEndpoint, O as stopGateEnabledForRepo, On as copilotHeaders, Ot as countTokens, Pt as createResponses, Q as assetFor, Qt as toolbeltPathOverride, Rt as parseJsonOrDiagnose, S as fileFindingsStore, Sn as getGitHubUser, St as reviewerModel, T as isSubagentContext, Tn as forwardError, Tt as standInToolEnabled, Ut as extractZipMember, Vt as provisionAndIndexColbert, Wt as warmTreeSitterPool, X as vscodeRipgrepPath, Xt as buildWorkspaceHeaderJson, Y as toolbeltSkipSet, Yt as buildWorkspaceHeaderHelperCommand, Z as TOOLBELT_TOOLS, Zt as collapsePathKeys, _ as stopGateDisabled, _n as isNullish, _t as browserCompoundToolsEnabled, a as buildPeerAwarenessSnippet, an as generateRandomPort, at as buildAnthropicErrorEvent, b as stopReviewEnabled, bn as sleep$1, bt as geminiAvailable, c as personasFor, cn as withInstallLock, ct as logStreamError, d as buildStopHookCommand, dn as setupGitHubToken, dt as handleMcpDelete, en as DEFAULT_CODEX_MODEL, et as ADVISOR_INTERNAL_TOOL_NAME, f as captureLaunchBaseline, fn as tryRefreshAndRetry, ft as handleMcpPost, g as launchBaselineKey, gn as filterBetaHeader, gt as browseAgentEnabled, h as injectStopHookIntoSettingsFile, hn as cacheVSCodeVersion, ht as brainstormModel, i as buildAgentPrompt, in as UPSTREAM_INACTIVITY_TIMEOUT_MS, it as isAdvisorRequested, j as liveExec, jt as assembleResponsesPayload, k as stopReviewStateDir, kn as githubHeaders, kt as createMessages, l as buildArtifactOpenHookCommand, ln as setupCopilotToken, lt as readIteratorWithTimeout, m as fileBlockBudget, mn as cacheModels, mt as artifactToolsEnabled, n as MCP_GROUPS, nn as DEFAULT_PORT, nt as buildAdvisorStream, o as buildPeerAwarenessSummary, on as pickClaudeDefault, ot as buildOpenAIErrorEvent, p as decideStopHook, pn as cacheCopilotVersion, pt as agentToolsEnabled, q as buildToolbeltAwareness, qt as shouldUseInsecureTls, r as assertMcpToolSurfaceConsistent, rn as UPSTREAM_FETCH_TIMEOUT_MS, rt as injectAdvisorTool, s as enumerateInjectedMcpToolNames, sn as getPackageVersion, st as isControllerClosedError, t as GROUP_META, tn as DEFAULT_CODEX_MODEL_FALLBACKS, tt as ADVISOR_TOOL_INSTRUCTIONS, u as buildSessionBindHookCommand, un as setupGitHubAgentToken, ut as relayAnthropicStream, v as stopGateId, vn as resolveCodexModel, vt as browserToolsEnabled, w as fileReviewDebounce, wn as HTTPError, wt as scribeModel, x as fileBaselineStore, xn as getModels, xt as nativeSubagentModel, y as stopGatePlanMode, yn as resolveModel, yt as fleetToolsEnabled, zt as provisionBrowserAssets } from "./peer-mcp-personas-CDja7arT.js";
|
|
3
|
+
import { a as isUnderClaudeConfigMirror, d as writeRuntimeFileSecure, i as ensurePaths, o as removeOwnClaudeConfigMirror, r as ensureClaudeConfigMirror, t as PATHS, u as writeArtifactCredsToMirror } from "./paths-Srxs-aR-.js";
|
|
4
|
+
import { c as killManagedTree, d as resolveExecutable, f as runCommandCapture, l as parseBoolEnv, p as runCommandVoid, s as killChildProcessTree, u as parseIntEnv } from "./lifecycle-C-9_vhyM.js";
|
|
5
|
+
import { a as sweepRegistry } from "./lifecycle-Cuuj40CW.js";
|
|
6
6
|
import { defineCommand, runMain } from "citty";
|
|
7
7
|
import consola from "consola";
|
|
8
8
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
@@ -979,7 +979,7 @@ function dispatcherDescription(mode) {
|
|
|
979
979
|
return `${{
|
|
980
980
|
explore: "Non-blocking `explore` worker: dispatches a read-only autonomous worker (its own context) in the background and delivers its summary as a completion notification.",
|
|
981
981
|
implement: "Non-blocking `implement` worker: dispatches an autonomous coding worker (read/write/bash) that ALWAYS runs in an isolated git worktree and returns the diff (for in-place edits use the `implementer` subagent), in the background, and delivers its result as a completion notification.",
|
|
982
|
-
review: "Non-blocking `review` worker:
|
|
982
|
+
review: "Non-blocking `review` worker: the backgrounded counterpart of the `reviewer` subagent, running a cross-lab model. In a git workspace it takes an isolated worktree and can therefore VERIFY rather than only read: reproduce a failure, run the build or suite to check a claim, and author a throwaway probe test. Outside git it degrades to read-only rather than failing. Returns severity-ranked findings with file:line and a go/no-go, as a completion notification. Use `explore` instead when you just need to find or understand something.",
|
|
983
983
|
plan: "Non-blocking `plan` worker: dispatches a read-only planner that returns an ordered implementation plan, in the background, and delivers it as a completion notification.",
|
|
984
984
|
test: "Non-blocking `test` worker: dispatches an independent test author (in an isolated git worktree) that writes tests trying to break the implementation, in the background, and delivers pass/fail as a completion notification.",
|
|
985
985
|
browse: "Non-blocking `browse` worker: dispatches an autonomous browser agent in the background and delivers its result as a completion notification."
|
|
@@ -1243,6 +1243,75 @@ const BUILTIN_SUBAGENT_DEFINITIONS = {
|
|
|
1243
1243
|
prompt: "You are a planning agent. Read the codebase (read-only — do not modify files) to design a concrete, ordered implementation plan for the task: the approach, the specific files to change, reuse of existing utilities, risks, and how the result will be verified. Return the plan as your final message."
|
|
1244
1244
|
}
|
|
1245
1245
|
};
|
|
1246
|
+
/** Empty-string-safe read of an optional model id. */
|
|
1247
|
+
function nonEmptyModel(id) {
|
|
1248
|
+
return id && id.length > 0 ? id : void 0;
|
|
1249
|
+
}
|
|
1250
|
+
/**
|
|
1251
|
+
* The shared "prefer the dedicated tools over shell" steer, appended to every
|
|
1252
|
+
* native subagent prompt. `bashUses` names the work that legitimately belongs in
|
|
1253
|
+
* Bash for that agent (`builds` for a coder, `repros` for an investigator), the
|
|
1254
|
+
* only token that ever differed across the three hand-copied variants this
|
|
1255
|
+
* replaces.
|
|
1256
|
+
*
|
|
1257
|
+
* Deliberately NOT merged with `FILE_TOOL_GUIDANCE` in
|
|
1258
|
+
* `anthropic-translate/anthropic-request.ts`: that one is injected at the shim
|
|
1259
|
+
* boundary and therefore only reaches shim-routed (non-Claude) models. When a
|
|
1260
|
+
* native falls back to the lead's Claude model the shim is bypassed entirely, so
|
|
1261
|
+
* this prompt-level copy is the only coverage that survives. Two layers, two
|
|
1262
|
+
* different reasons to exist.
|
|
1263
|
+
*/
|
|
1264
|
+
function fileToolSteer(bashUses) {
|
|
1265
|
+
return `Use the dedicated Edit/Write/Read tools for file changes and Grep/Glob for search; reserve Bash for running ${bashUses}, tests, and git. Do not shell out (sed/awk/python/here-docs) to read or edit files.`;
|
|
1266
|
+
}
|
|
1267
|
+
/** The read-only half of `fileToolSteer`, for agents that never write. */
|
|
1268
|
+
function readOnlyToolSteer() {
|
|
1269
|
+
return "Use Read to read files and Grep/Glob plus the semantic code search tool to find them; Bash is for read-only inspection such as git log, git blame, and git show. Do not modify any file, and do not run mutating commands.";
|
|
1270
|
+
}
|
|
1271
|
+
/**
|
|
1272
|
+
* `tools:` allowlist for the read-only natives (`scout`, `brainstorm`), modelled
|
|
1273
|
+
* on Claude Code's own `Explore`/`Plan` built-ins, which run with every tool
|
|
1274
|
+
* EXCEPT Agent / Artifact / ExitPlanMode / Edit / Write / NotebookEdit — note
|
|
1275
|
+
* that Anthropic's own read-only agent keeps Bash, which is what makes `git log`
|
|
1276
|
+
* and `git blame` reachable.
|
|
1277
|
+
*
|
|
1278
|
+
* Two deliberate deviations, both forced by the frontmatter format:
|
|
1279
|
+
*
|
|
1280
|
+
* 1. `tools:` is a POSITIVE allowlist with no "all except" form, so the
|
|
1281
|
+
* complement has to be spelled out. Rather than enumerate every harness tool
|
|
1282
|
+
* (which varies by Claude Code version, and would silently drop anything
|
|
1283
|
+
* added later), this lists the read / search / shell core that a read-only
|
|
1284
|
+
* agent actually uses. Tools added by a future release are NOT inherited by
|
|
1285
|
+
* these two agents; that is the price of real enforcement over a prompt that
|
|
1286
|
+
* merely asks nicely.
|
|
1287
|
+
* 2. The workers and orchestrate MCP groups are excluded on the same reasoning
|
|
1288
|
+
* that makes `Explore` drop `Agent`: both spawn further agents, so leaving
|
|
1289
|
+
* them in would reintroduce exactly the recursion that exclusion prevents.
|
|
1290
|
+
*
|
|
1291
|
+
* NOT A SANDBOX. `Bash` is retained because Anthropic's own read-only built-in
|
|
1292
|
+
* retains it, and without it an explorer cannot run `git log` / `git blame` /
|
|
1293
|
+
* `git show`, which is most of what repository archaeology needs. A shell is a
|
|
1294
|
+
* general write primitive, so "read-only" here means the agent has no dedicated
|
|
1295
|
+
* mutation tool and is instructed not to mutate, NOT that mutation is
|
|
1296
|
+
* impossible. Dropping Edit/Write still removes the path a model reaches for by
|
|
1297
|
+
* default. If a future change needs a hard guarantee, this allowlist is not
|
|
1298
|
+
* where it can be made.
|
|
1299
|
+
*
|
|
1300
|
+
* `searchKey` is the RESOLVED group key, not the bare literal: a user-side
|
|
1301
|
+
* `mcpServers` collision renames the group (`gh-router-search`, …), and a
|
|
1302
|
+
* hardcoded `mcp__search__*` would then grant nothing at all.
|
|
1303
|
+
*/
|
|
1304
|
+
function readOnlyToolAllowlist(searchKey) {
|
|
1305
|
+
return [
|
|
1306
|
+
"Read",
|
|
1307
|
+
"Grep",
|
|
1308
|
+
"Glob",
|
|
1309
|
+
"Bash",
|
|
1310
|
+
"WebFetch",
|
|
1311
|
+
"WebSearch",
|
|
1312
|
+
`mcp__${searchKey}__*`
|
|
1313
|
+
];
|
|
1314
|
+
}
|
|
1246
1315
|
/**
|
|
1247
1316
|
* Build the JSON payload for `claude --agents <path>`.
|
|
1248
1317
|
*
|
|
@@ -1275,22 +1344,42 @@ function buildPeerAgentDefinitions(opts) {
|
|
|
1275
1344
|
}),
|
|
1276
1345
|
...peersMcp
|
|
1277
1346
|
};
|
|
1278
|
-
const nativeModel = opts.nativeSubagentModel
|
|
1347
|
+
const nativeModel = nonEmptyModel(opts.nativeSubagentModel);
|
|
1348
|
+
const reviewerModel$1 = nonEmptyModel(opts.reviewerModel);
|
|
1349
|
+
const brainstormModel$1 = nonEmptyModel(opts.brainstormModel);
|
|
1350
|
+
const scoutModel$1 = nonEmptyModel(opts.scoutModel);
|
|
1351
|
+
const scribeModel$1 = nonEmptyModel(opts.scribeModel);
|
|
1279
1352
|
const modelField = nativeModel ? { model: nativeModel } : {};
|
|
1353
|
+
const searchKey = opts.groupKeys.search ?? GROUP_META.search.preferredKey;
|
|
1354
|
+
const searchMcp = opts.serverUrl ? { mcpServers: { [searchKey]: httpEntryFor(opts.serverUrl, "search", opts.nonce, opts.workspaceHeaderCmd) } } : {};
|
|
1280
1355
|
out.implementer = {
|
|
1281
1356
|
description: nativeModel ? `Bounded implementation subagent running ${nativeModel} (strong non-Claude coder, maximum reasoning). Use proactively for well-scoped coding tasks — edits, small features, fixes — to keep the lead's context focused; runs in its own context. Model is overridable at spawn.` : `Bounded implementation subagent (native tools, runs on the lead's model in its own context). Use proactively for well-scoped coding tasks — edits, small features, fixes — to keep the lead's context focused. Model is overridable at spawn.`,
|
|
1282
|
-
prompt: "You are a bounded implementation subagent for well-scoped coding tasks. Implement the requested change surgically, matching the surrounding code style and minimizing unrelated churn.
|
|
1357
|
+
prompt: "You are a bounded implementation subagent for well-scoped coding tasks. Implement the requested change surgically, matching the surrounding code style and minimizing unrelated churn. " + fileToolSteer("builds") + " Verify with the project's build or tests where applicable. Do the work yourself — do not spawn further subagents. Report exactly what changed and any risks.",
|
|
1283
1358
|
...modelField
|
|
1284
1359
|
};
|
|
1285
|
-
out.
|
|
1286
|
-
description:
|
|
1287
|
-
prompt: "You are a
|
|
1288
|
-
...
|
|
1360
|
+
out.reviewer = {
|
|
1361
|
+
description: reviewerModel$1 ? `Feedback subagent running ${reviewerModel$1}, a DIFFERENT lab from both the lead and the implementer, so its blind spots are decorrelated from whoever produced the work. Use proactively when something already exists and you want it assessed: a diff, a plan, a document, a failing test. Unlike the stateless peer critics, it reads the repo and can RUN things, so prefer it whenever the assessment needs execution or repo context (reproduce a failure, run the suite, bisect); prefer a peer critic when you already hold the artifact and want a fresh-context opinion on it. Model is overridable at spawn.` : `Feedback subagent (native tools, runs on the lead's model in its own context). Use proactively when something already exists and you want it assessed: a diff, a plan, a document, a failing test. Unlike the stateless peer critics, it reads the repo and can RUN things, so prefer it whenever the assessment needs execution or repo context; prefer a peer critic when you already hold the artifact and want a fresh-context opinion on it. Model is overridable at spawn.`,
|
|
1362
|
+
prompt: "You are a feedback subagent. Your job is to tell the caller what is actually true about the artifact you are given — code, a plan, a document, a failure report — and what is wrong with it. Verify against the ACTUAL code by reading it; never assume. Do whatever the assessment requires: reproduce a failure end to end as close to how a real user hits it as you can, form hypotheses and test them against the code and runtime, and isolate the true root cause rather than a symptom. Where the change warrants it, author tests that try to BREAK the implementation (edge cases, error paths, and the acceptance criteria as executable checks), run them, and report which pass and which fail; do NOT modify production code just to make tests pass. " + fileToolSteer("builds") + " Do the work yourself — do not spawn further subagents. Report severity-ranked findings with `file:line` citations, the evidence behind each, and end with a clear go/no-go.",
|
|
1363
|
+
...reviewerModel$1 ? { model: reviewerModel$1 } : {}
|
|
1289
1364
|
};
|
|
1290
|
-
out
|
|
1291
|
-
description:
|
|
1292
|
-
prompt: "You are a
|
|
1293
|
-
|
|
1365
|
+
out.brainstorm = {
|
|
1366
|
+
description: brainstormModel$1 ? `Divergent-options subagent running ${brainstormModel$1} (third lab, for approaches the lead would not generate). Use proactively BEFORE an approach is chosen. Pass the decision, the constraints, what you have already ruled out, and the cost of being wrong; pass your current leading approach too if you have one, and it will try to beat it rather than restate it. Read-only; it proposes, then hands off to implementer. Model is overridable at spawn.` : `Divergent-options subagent (runs on the lead's model in its own context). Use proactively BEFORE an approach is chosen. Pass the decision, the constraints, what you have already ruled out, and the cost of being wrong; pass your current leading approach too if you have one, and it will try to beat it rather than restate it. Read-only; it proposes, then hands off to implementer. Model is overridable at spawn.`,
|
|
1367
|
+
prompt: "You are a divergent-options subagent: the lead's sounding board while an approach is still open. Your job is to surface the option the lead would not have reached on its own. If the caller states its current leading approach, your job is to try to beat it, and you close with one verdict: `replace`, `retain`, or `insufficient evidence`. `replace` requires naming a concrete alternative that dominates it and the evidence that decides between them. `retain` is a real answer and a useful one: say it plainly when the approach survives a genuine attempt to beat it. Manufactured disagreement is as useless as agreement; do neither. If the caller states no leading approach, generate independently and let the lead compare. Return 3 to 5 approaches that differ in MECHANISM, not in phrasing. For each: how it works, what it costs, what would have to be true for it to be the right answer, and the failure mode that would kill it. Near-duplicate options are the failure mode to avoid — if only one real approach exists, say so plainly and explain why the alternatives are dead, because one honest option beats four padded ones. Screen EVERY candidate against this repository and this environment before you rank them, then verify the one you are about to recommend can actually run here: read the code path it depends on, the guard that would refuse it, the artifact it assumes exists. A recommendation that cannot execute is worse than no recommendation. If checking kills your front-runner, rerank and say so. Ground every option in what the repository actually contains, and prefer reusing what is already there over inventing something new. " + readOnlyToolSteer() + " Do the work yourself — do not spawn further subagents.",
|
|
1368
|
+
tools: readOnlyToolAllowlist(searchKey),
|
|
1369
|
+
...brainstormModel$1 ? { model: brainstormModel$1 } : {},
|
|
1370
|
+
...searchMcp
|
|
1371
|
+
};
|
|
1372
|
+
if (scoutModel$1) out.scout = {
|
|
1373
|
+
description: `Read-only exploration subagent running ${scoutModel$1} (fast and cheap, so repository lookups do not run at the lead's model rates). Use proactively to find or understand something in the codebase: it sweeps widely and returns conclusions with file:line references rather than file dumps. Model is overridable at spawn.`,
|
|
1374
|
+
prompt: "You are a read-only exploration subagent. Answer the question by investigating the repository: cast a wide net, then narrow. Return the conclusion, not the raw material — cite `file:line` for anything load-bearing and quote only the lines that matter. If the answer is that something does not exist, say so explicitly and describe where you looked. " + readOnlyToolSteer() + " Do the work yourself — do not spawn further subagents.",
|
|
1375
|
+
tools: readOnlyToolAllowlist(searchKey),
|
|
1376
|
+
model: scoutModel$1,
|
|
1377
|
+
...searchMcp
|
|
1378
|
+
};
|
|
1379
|
+
out.scribe = {
|
|
1380
|
+
description: scribeModel$1 ? `Documentation subagent running ${scribeModel$1}. Use proactively for prose that trails the code: docs, ADRs, CLAUDE.md sections, changelog entries, and README updates that have gone stale. Keeps low-glamour upkeep off the lead's context. Model is overridable at spawn.` : `Documentation subagent (runs on the lead's model in its own context). Use proactively for prose that trails the code: docs, ADRs, CLAUDE.md sections, changelog entries, and README updates that have gone stale. Model is overridable at spawn.`,
|
|
1381
|
+
prompt: "You are a documentation subagent. Write and maintain the prose that trails the code: docs, ADRs, CLAUDE.md sections, changelog entries, README rows. Read the code before describing it — every claim you write must be checkable against the repository as it is now, not as a summary said it was. Match the surrounding document's voice, structure, and level of detail. Prefer updating an existing document over adding a new one, and delete what has become false rather than layering a correction on top of it. " + fileToolSteer("builds") + " Do the work yourself — do not spawn further subagents. Report which documents changed and any claim you could not verify.",
|
|
1382
|
+
...scribeModel$1 ? { model: scribeModel$1 } : {}
|
|
1294
1383
|
};
|
|
1295
1384
|
if (opts.workerToolsAvailable) {
|
|
1296
1385
|
const workersKey = workersKeyOf(opts.groupKeys);
|
|
@@ -1628,6 +1717,10 @@ async function writePeerMcpRuntimeFiles(serverUrl, opts) {
|
|
|
1628
1717
|
workerToolsAvailable: opts.workerToolsAvailable,
|
|
1629
1718
|
browseAvailable: opts.browseAvailable,
|
|
1630
1719
|
nativeSubagentModel: opts.nativeSubagentModel,
|
|
1720
|
+
reviewerModel: opts.reviewerModel,
|
|
1721
|
+
brainstormModel: opts.brainstormModel,
|
|
1722
|
+
scoutModel: opts.scoutModel,
|
|
1723
|
+
scribeModel: opts.scribeModel,
|
|
1631
1724
|
nonce,
|
|
1632
1725
|
codexHome,
|
|
1633
1726
|
serverUrl,
|
|
@@ -2894,7 +2987,7 @@ async function discoverGateCommands(cwd, opts) {
|
|
|
2894
2987
|
if (files.length === 0) return null;
|
|
2895
2988
|
let result;
|
|
2896
2989
|
try {
|
|
2897
|
-
const { runWorkerAgent } = await import("./engine-
|
|
2990
|
+
const { runWorkerAgent } = await import("./engine-5VxiBAdY.js");
|
|
2898
2991
|
result = await runWorkerAgent({
|
|
2899
2992
|
mode: "explore",
|
|
2900
2993
|
workspace: root,
|
|
@@ -4079,7 +4172,7 @@ const STYLE_DIRECTIVE = "Write concisely without losing detail. Use a natural hu
|
|
|
4079
4172
|
* Self-referentially compliant with the style directive: no em dashes, no
|
|
4080
4173
|
* Claude / Anthropic attribution.
|
|
4081
4174
|
*/
|
|
4082
|
-
const OPERATING_DEFAULTS_DIRECTIVE = "## Operating defaults (apply when the user has not specified otherwise; the user's explicit direction and the domain's own standards always override)\n\nOrchestrate. Delegate research, implementation, review, and large reads to the right subagent, worker, or model
|
|
4175
|
+
const OPERATING_DEFAULTS_DIRECTIVE = "## Operating defaults (apply when the user has not specified otherwise; the user's explicit direction and the domain's own standards always override)\n\nOrchestrate. Delegate research, implementation, review, and large reads to the right subagent, worker, or model. Reach for `implementer` when you know what to build, `reviewer` when something exists and you want it assessed (including reproducing and root-causing a failure), `brainstorm` when you do not yet know which approach to take, `scout` to find or understand something in the repo, and `scribe` for docs and ADRs that trail the code; worker-* agents for background non-blocking runs; Task subagents for parallel work; peer critics for review. That keeps your own context free to reason and collaborate with the user. Prefer parallel delegation for independent work. Do trivial, surgical, and last-mile work directly; delegate the rest rather than doing it yourself and filling your own context. Delegate to a subagent by default whenever one can do the work without loss of quality: the main thread is where you think with and respond to the user, and its context window is a finite shared resource, so protect it by pushing heavy or exploratory work outward and keeping only the conclusions.\n\nAim high. Default to radical simplicity and a relentless focus on the user's real experience: design for the person and the job to be done, not the demo. Reason about the whole system from first principles, anticipating scale and the long arc rather than patching the surface. Work backwards from the outcome the user actually needs. Question every assumption and prefer what you can derive, reproduce, or test.\n\nEngineering excellence. When making technical decisions, give little weight to development cost; prefer quality, simplicity, robustness, scalability, and long-term maintainability. Fix a bug by first reproducing it end to end, as close to how a real user hits it as you can, so you solve the real problem and not a symptom. When testing a product end to end, be picky about the UI and obsessed with pixel perfection: if something clearly looks off, even when it is unrelated to your task, get it fixed along the way. Hold that same bar for the codebase itself: a lint error, a failing test, or a flaky test is worth fixing the moment you see it, whoever introduced it. Fold it into your current work rather than letting it derail the task the user actually asked for.";
|
|
4083
4176
|
/**
|
|
4084
4177
|
* Condensed digest of OPERATING_DEFAULTS_DIRECTIVE for the spawned session's
|
|
4085
4178
|
* system prompt (--append-system-prompt). The FULL directive is prepended to
|
|
@@ -4820,8 +4913,27 @@ function keepDisplayOn() {
|
|
|
4820
4913
|
const ES_CONTINUOUS = 2147483648;
|
|
4821
4914
|
const ES_SYSTEM_REQUIRED = 1;
|
|
4822
4915
|
const ES_DISPLAY_REQUIRED = 2;
|
|
4823
|
-
/** Default time to wait for the helper's `OK` readiness line.
|
|
4824
|
-
|
|
4916
|
+
/** Default time to wait for the helper's `OK` readiness line.
|
|
4917
|
+
*
|
|
4918
|
+
* Sized for the slowest LEGITIMATE path, not the typical one. The script's
|
|
4919
|
+
* `Add-Type -MemberDefinition` compiles a C# P/Invoke shim through csc.exe on
|
|
4920
|
+
* first use, and that compile happens BEFORE the `OK` line is printed. On a
|
|
4921
|
+
* cold machine (a fresh CI runner, a laptop that just booted, a host with
|
|
4922
|
+
* aggressive on-access AV scanning) it routinely takes well over five seconds.
|
|
4923
|
+
*
|
|
4924
|
+
* CORRECTION to the rationale this constant shipped with. An earlier version of
|
|
4925
|
+
* this comment (and the commit that raised the value) claimed a short timeout
|
|
4926
|
+
* made the user "silently lose keep-awake". That is wrong, and a cross-lab
|
|
4927
|
+
* reviewer caught it: `startKeepAwake` does nothing with `ready` but
|
|
4928
|
+
* `consola.debug` it (`index.ts:128`). The handle is retained and the child
|
|
4929
|
+
* keeps running, so the assertion is still set, just later than we observed it.
|
|
4930
|
+
*
|
|
4931
|
+
* The real cost of a tight value is therefore a LYING LOG, not a lost feature:
|
|
4932
|
+
* we report "inactive" for a helper that is about to work. That is still worth
|
|
4933
|
+
* fixing, because a false negative in a diagnostic is how you lose an afternoon
|
|
4934
|
+
* chasing a working feature. Waiting longer costs nothing either way, since the
|
|
4935
|
+
* readiness promise is awaited in the background and never blocks launch. */
|
|
4936
|
+
const DEFAULT_READY_TIMEOUT_MS = 2e4;
|
|
4825
4937
|
/**
|
|
4826
4938
|
* The execution-state flags to assert. Always `ES_CONTINUOUS |
|
|
4827
4939
|
* ES_SYSTEM_REQUIRED` (machine stays awake); adds `ES_DISPLAY_REQUIRED`
|
|
@@ -5222,7 +5334,7 @@ function initProxyFromEnv() {
|
|
|
5222
5334
|
//#endregion
|
|
5223
5335
|
//#region package.json
|
|
5224
5336
|
var name = "github-router";
|
|
5225
|
-
var version$1 = "0.3.
|
|
5337
|
+
var version$1 = "0.3.238";
|
|
5226
5338
|
|
|
5227
5339
|
//#endregion
|
|
5228
5340
|
//#region src/lib/approval.ts
|
|
@@ -5347,7 +5459,7 @@ function detectCapabilityMismatch(info, model) {
|
|
|
5347
5459
|
* that should get a probe row added.
|
|
5348
5460
|
*
|
|
5349
5461
|
* Format (single line, deterministic-ish key order):
|
|
5350
|
-
* [fields] path=<P> body_keys=<csv> tool_field_keys=<csv> beta_values=<csv>
|
|
5462
|
+
* [fields] path=<P> body_keys=<csv> tool_field_keys=<csv> beta_values=<csv> agent=<id|->
|
|
5351
5463
|
*
|
|
5352
5464
|
* Where:
|
|
5353
5465
|
* - `body_keys` is the alphabetical union of top-level keys in the
|
|
@@ -5357,13 +5469,19 @@ function detectCapabilityMismatch(info, model) {
|
|
|
5357
5469
|
* - `beta_values` is the comma-split anthropic-beta header value as
|
|
5358
5470
|
* received (NOT filtered) — captures what the client sends, not
|
|
5359
5471
|
* what we forward
|
|
5472
|
+
* - `agent` is Claude Code's `x-claude-code-agent-id` header, or `-` for
|
|
5473
|
+
* main-loop traffic. Without it a capture cannot tell a subagent request
|
|
5474
|
+
* from a main-loop one, which is exactly the question you need answered
|
|
5475
|
+
* when reasoning about per-agent request shape (does a subagent send a
|
|
5476
|
+
* `thinking` block?). The header value is opaque to us and is logged
|
|
5477
|
+
* verbatim.
|
|
5360
5478
|
*/
|
|
5361
5479
|
function logRequestFields(opts) {
|
|
5362
5480
|
if (process.env.GH_ROUTER_LOG_FIELDS !== "1") return;
|
|
5363
5481
|
const bodyKeys = collectTopLevelKeys(opts.body);
|
|
5364
5482
|
const toolFieldKeys = collectToolFieldKeys(opts.body);
|
|
5365
5483
|
const betaValues = (opts.betaHeader ?? "").split(",").map((v) => v.trim()).filter(Boolean);
|
|
5366
|
-
consola.info(`[fields] path=${opts.path} body_keys=${bodyKeys.join(",")} tool_field_keys=${toolFieldKeys.join(",")} beta_values=${betaValues.join(",")}`);
|
|
5484
|
+
consola.info(`[fields] path=${opts.path} body_keys=${bodyKeys.join(",")} tool_field_keys=${toolFieldKeys.join(",")} beta_values=${betaValues.join(",")} agent=${opts.agentId && opts.agentId.length > 0 ? opts.agentId : "-"}`);
|
|
5367
5485
|
}
|
|
5368
5486
|
function collectTopLevelKeys(body) {
|
|
5369
5487
|
if (!body || typeof body !== "object" || Array.isArray(body)) return [];
|
|
@@ -6306,20 +6424,29 @@ function parseDisableParallelToolUse(toolChoice) {
|
|
|
6306
6424
|
return toolChoice.disable_parallel_tool_use === true ? false : void 0;
|
|
6307
6425
|
}
|
|
6308
6426
|
/** Default absent Anthropic `thinking` to an effort, clamped by the model.
|
|
6309
|
-
*
|
|
6310
|
-
*
|
|
6311
|
-
*
|
|
6312
|
-
*
|
|
6313
|
-
*
|
|
6314
|
-
*
|
|
6315
|
-
*
|
|
6316
|
-
*
|
|
6317
|
-
*
|
|
6318
|
-
*
|
|
6427
|
+
* Every shim model defaults to `high`, so a client level maps to the identical
|
|
6428
|
+
* provider level (low→low, medium→medium, high→high, xhigh→xhigh) and `high` is
|
|
6429
|
+
* the only value the router injects on its own. There is deliberately NO floor:
|
|
6430
|
+
* an explicit client budget that buckets to `medium` yields `medium`, because a
|
|
6431
|
+
* one-directional max() would mean the router silently overriding the level the
|
|
6432
|
+
* user chose.
|
|
6433
|
+
*
|
|
6434
|
+
* Opt in to the previous behavior (xhigh for the OpenAI frontier models when no
|
|
6435
|
+
* thinking is sent) with `GH_ROUTER_FRONTIER_XHIGH_DEFAULT=1`. This replaces the
|
|
6436
|
+
* old opt-OUT `GH_ROUTER_DISABLE_FRONTIER_XHIGH_DEFAULT`, whose meaning would
|
|
6437
|
+
* have inverted under the new default.
|
|
6438
|
+
*
|
|
6439
|
+
* Two honest limits, both pre-existing: the level is bucketed from a token
|
|
6440
|
+
* budget so the mapping is lossy at the boundaries, and `clampEffort` moves a
|
|
6441
|
+
* level the model does not advertise (gemini has no `xhigh`). Returns undefined
|
|
6442
|
+
* for a model that advertises NO `reasoning_effort` allowlist, which leaves the
|
|
6443
|
+
* provider's own default rather than `high` — forcing an effort there could 400.
|
|
6444
|
+
* An explicit client `thinking` budget is handled by parseReasoningEffort and is
|
|
6445
|
+
* NOT affected by this default. */
|
|
6319
6446
|
function defaultReasoningEffort(model) {
|
|
6320
6447
|
const supported = model?.capabilities?.supports?.reasoning_effort;
|
|
6321
6448
|
if (!(Array.isArray(supported) && supported.length > 0)) return void 0;
|
|
6322
|
-
return clampEffort(parseBoolEnv(process.env.
|
|
6449
|
+
return clampEffort(parseBoolEnv(process.env.GH_ROUTER_FRONTIER_XHIGH_DEFAULT) === true && model?.id != null && shimDefaultsToXhigh(model.id) && supported.includes("xhigh") ? "xhigh" : "high", supported);
|
|
6323
6450
|
}
|
|
6324
6451
|
/**
|
|
6325
6452
|
* Map Anthropic `thinking` to a Responses reasoning effort, clamped to the
|
|
@@ -7367,7 +7494,8 @@ async function handleCompletion(c) {
|
|
|
7367
7494
|
logRequestFields({
|
|
7368
7495
|
path: c.req.path,
|
|
7369
7496
|
body: parsedForLog,
|
|
7370
|
-
betaHeader: c.req.header("anthropic-beta")
|
|
7497
|
+
betaHeader: c.req.header("anthropic-beta"),
|
|
7498
|
+
agentId: c.req.header("x-claude-code-agent-id")
|
|
7371
7499
|
});
|
|
7372
7500
|
}
|
|
7373
7501
|
if (state.manualApprove) await awaitApproval();
|
|
@@ -9014,7 +9142,11 @@ const claude = defineCommand({
|
|
|
9014
9142
|
groupKeys,
|
|
9015
9143
|
workerToolsAvailable: workerToolsEnabled(),
|
|
9016
9144
|
browseAvailable: browseAgentEnabled(),
|
|
9017
|
-
nativeSubagentModel: nativeSubagentModel()
|
|
9145
|
+
nativeSubagentModel: nativeSubagentModel(),
|
|
9146
|
+
reviewerModel: reviewerModel(),
|
|
9147
|
+
brainstormModel: brainstormModel(),
|
|
9148
|
+
scoutModel: scoutModel(),
|
|
9149
|
+
scribeModel: scribeModel()
|
|
9018
9150
|
});
|
|
9019
9151
|
state.peerMcpNonce = runtime.nonce;
|
|
9020
9152
|
envVars.GH_ROUTER_HOOK_MCP_URL = serverUrl;
|
|
@@ -9217,6 +9349,7 @@ const claude = defineCommand({
|
|
|
9217
9349
|
powerBrowseAvailable: state.powerBrowseEnabled,
|
|
9218
9350
|
fleetAvailable: fleetToolsEnabled(),
|
|
9219
9351
|
agentToolsAvailable: agentToolsEnabled(),
|
|
9352
|
+
scoutAvailable: scoutModel() != null,
|
|
9220
9353
|
groupKeys
|
|
9221
9354
|
});
|
|
9222
9355
|
peerAwarenessSnippet = peerSnippet;
|
|
@@ -10147,7 +10280,7 @@ const internalStopHook = defineCommand({
|
|
|
10147
10280
|
} catch {}
|
|
10148
10281
|
let decision;
|
|
10149
10282
|
try {
|
|
10150
|
-
const timeoutEnv =
|
|
10283
|
+
const timeoutEnv = parseIntEnv(process.env.GH_ROUTER_STOP_GATE_TIMEOUT_MS);
|
|
10151
10284
|
const mode = dynamicMode();
|
|
10152
10285
|
decision = await decideStopHook({
|
|
10153
10286
|
stdin,
|
|
@@ -10159,7 +10292,7 @@ const internalStopHook = defineCommand({
|
|
|
10159
10292
|
baseline: fileBaselineStore(nodePath.join(tmpdir(), "gh-router-stopgate-baseline")),
|
|
10160
10293
|
isEnabledForRepo: (cwd) => stopGateEnabledForRepo(cwd),
|
|
10161
10294
|
resolveChecks: mode ? buildResolveChecks(mode) : void 0,
|
|
10162
|
-
timeoutMs:
|
|
10295
|
+
timeoutMs: timeoutEnv,
|
|
10163
10296
|
planMode: stopGatePlanMode(),
|
|
10164
10297
|
reviewDebounce: reviewEnabled ? fileReviewDebounce(stopReviewStateDir()) : void 0,
|
|
10165
10298
|
spawnReview: reviewEnabled ? (ctx) => spawnStopReview(ctx, {
|
|
@@ -11007,6 +11140,10 @@ async function provisionServeEnhancements(serverUrl, opts = {}) {
|
|
|
11007
11140
|
workerToolsAvailable: workerToolsEnabled(),
|
|
11008
11141
|
browseAvailable: browseAllowed && browseAgentEnabled(),
|
|
11009
11142
|
nativeSubagentModel: nativeSubagentModel(),
|
|
11143
|
+
reviewerModel: reviewerModel(),
|
|
11144
|
+
brainstormModel: brainstormModel(),
|
|
11145
|
+
scoutModel: scoutModel(),
|
|
11146
|
+
scribeModel: scribeModel(),
|
|
11010
11147
|
builtinSubagents: BUILTIN_SUBAGENT_DEFINITIONS
|
|
11011
11148
|
});
|
|
11012
11149
|
state.peerMcpNonce = runtime.nonce;
|
|
@@ -11025,6 +11162,7 @@ async function provisionServeEnhancements(serverUrl, opts = {}) {
|
|
|
11025
11162
|
compoundBrowseAvailable: browseAllowed && browserCompoundToolsEnabled(),
|
|
11026
11163
|
powerBrowseAvailable: browseAllowed && state.powerBrowseEnabled,
|
|
11027
11164
|
agentToolsAvailable: firstMateAllowed,
|
|
11165
|
+
scoutAvailable: scoutModel() != null,
|
|
11028
11166
|
groupKeys
|
|
11029
11167
|
})).catch((err) => consola.warn(`Peer-awareness CLAUDE.md append failed: ${String(err)}`));
|
|
11030
11168
|
await prependStyleDirectiveToMirroredClaudeMd().catch((err) => consola.warn(`Style-directive CLAUDE.md prepend failed: ${String(err)}`));
|