github-router 0.3.304 → 0.3.305

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.
Files changed (28) hide show
  1. package/dist/{attribution-settings-C8iSwEAZ.js → attribution-settings-Chqw6VeK.js} +3 -3
  2. package/dist/{attribution-settings-C8iSwEAZ.js.map → attribution-settings-Chqw6VeK.js.map} +1 -1
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/{claude-Drv0roq1.js → claude-C3LWG_3H.js} +16 -7
  5. package/dist/claude-C3LWG_3H.js.map +1 -0
  6. package/dist/{codex-kgVL5OyN.js → codex-DdhBGec4.js} +4 -4
  7. package/dist/{codex-kgVL5OyN.js.map → codex-DdhBGec4.js.map} +1 -1
  8. package/dist/engine-C7DkYq2g.js +2 -0
  9. package/dist/{gate-discovery-D4-F99e_.js → gate-discovery-C6jB3bBG.js} +2 -2
  10. package/dist/{gate-discovery-D4-F99e_.js.map → gate-discovery-C6jB3bBG.js.map} +1 -1
  11. package/dist/{internal-stop-hook-D8LIWryj.js → internal-stop-hook-EPAu3tkg.js} +2 -2
  12. package/dist/{internal-stop-hook-D8LIWryj.js.map → internal-stop-hook-EPAu3tkg.js.map} +1 -1
  13. package/dist/main.js +5 -5
  14. package/dist/{peer-mcp-personas-D4bHdjOx.js → peer-mcp-personas-C9fDtu69.js} +3 -3
  15. package/dist/{peer-mcp-personas-D4bHdjOx.js.map → peer-mcp-personas-C9fDtu69.js.map} +1 -1
  16. package/dist/{provision-D3_GtXze.js → provision-Bn4FOzR4.js} +2 -2
  17. package/dist/{provision-D3_GtXze.js.map → provision-Bn4FOzR4.js.map} +1 -1
  18. package/dist/{serve-DPRZX-2j.js → serve-7q23O8hl.js} +22 -6
  19. package/dist/serve-7q23O8hl.js.map +1 -0
  20. package/dist/{server-setup-CSkdFAPP.js → server-setup-BP_JM0qb.js} +158 -192
  21. package/dist/server-setup-BP_JM0qb.js.map +1 -0
  22. package/dist/{start-C6G5tu81.js → start-wa7_DyyG.js} +3 -3
  23. package/dist/{start-C6G5tu81.js.map → start-wa7_DyyG.js.map} +1 -1
  24. package/package.json +1 -1
  25. package/dist/claude-Drv0roq1.js.map +0 -1
  26. package/dist/engine-xuIzQNV1.js +0 -2
  27. package/dist/serve-DPRZX-2j.js.map +0 -1
  28. package/dist/server-setup-CSkdFAPP.js.map +0 -1
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 3,
3
3
  "name": "github-router browser bridge",
4
4
  "short_name": "gh-router-browser",
5
- "version": "0.3.304",
5
+ "version": "0.3.305",
6
6
  "description": "Bridge between Claude (via github-router /mcp) and the browser. Implements tab control, navigation, clicks, form fill, downloads, screenshots, devtools eval. Blocks navigation to chrome://settings.",
7
7
  "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqJElxuBlonBS3TVW9FJN0mGTtShB3L1hoaYf6k39SOr1ogGYmF90EjRxy1i21k9wQQjPf26bcBu/9X67KrQjQV0uB38CaNukgiSeoLjfptN811u+PJHx6BP+jx3Qa6/3VenNPxHC8WEU0GXql8QSjIHEyCwKb6fMASXOK94JyB5Ywov2x8mt/+9ncqBBBMVzf6r5Sagy4PL1XnryLsuADD/vOEkPet8wXgH/Oj7v5tTsQQZ7U1JT51PoDs2BFnXc5v3TkVgZwd32k3ONh+nkDw1Hof+4zwUGOyJE6eMrlYzRlKM4Qxdf9JpavQvqfieAbTRWcyKeclnHeoIfE7cDBQIDAQAB",
8
8
  "background": {
@@ -1,21 +1,21 @@
1
- import { $t as warmTreeSitterPool, Ct as reviewerFastModel, D as toolbeltEnabled, Dt as standInToolEnabled, E as buildToolbeltAwareness, Et as scribeModel, Hn as validateMaxProfileLaunch, It as registerLaunch, Lt as unregisterLaunch, Nn as formatFastPrerequisiteFailure, Ot as workerToolsEnabled, Rn as profileDescriptor, St as resolveGeminiReviewModel, T as availableToolCommands, Tn as LUNA_DRIVER_ALIAS_ID, Tt as scoutModel, Vn as validateFastProfilePrerequisites, Xt as provisionAndIndexColbert, Yt as colbertDegradedWarning, _n as resolveLeadSlugArg, _t as fleetToolsEnabled, at as artifactToolsEnabled, bt as implementerFastModel, cn as DEFAULT_CLAUDE_MODEL_FALLBACKS, ct as browserCompoundToolsEnabled, dt as fastGeneralPurposeModel, ft as fastImplementerModel, gn as pickClaudeDefault, gt as fastScoutModel, hn as isBudgetClaudeLead, ht as fastReviewerModel, it as agentToolsEnabled, lt as browserToolsEnabled, mt as fastPlanModel, o as buildPeerAwarenessSnippet, ot as brainstormModel, pt as fastOracleModel, qt as provisionBrowserAssets, r as agentNamesForToolAllowlist, rn as shouldUseInsecureTls, s as buildPeerAwarenessSummary, st as browseAgentEnabled, ut as fastAdvisorModel, vt as geminiAvailable, wt as reviewerModel, xt as nativeSubagentModel, yt as generalPurposeFastModel, zn as resolveLaunchProfile } from "./peer-mcp-personas-D4bHdjOx.js";
1
+ import { $t as warmTreeSitterPool, Ct as reviewerFastModel, D as toolbeltEnabled, Dt as standInToolEnabled, E as buildToolbeltAwareness, Et as scribeModel, Hn as validateMaxProfileLaunch, It as registerLaunch, Lt as unregisterLaunch, Nn as formatFastPrerequisiteFailure, Ot as workerToolsEnabled, Rn as profileDescriptor, St as resolveGeminiReviewModel, T as availableToolCommands, Tn as LUNA_DRIVER_ALIAS_ID, Tt as scoutModel, Vn as validateFastProfilePrerequisites, Xt as provisionAndIndexColbert, Yt as colbertDegradedWarning, _n as resolveLeadSlugArg, _t as fleetToolsEnabled, at as artifactToolsEnabled, bt as implementerFastModel, cn as DEFAULT_CLAUDE_MODEL_FALLBACKS, ct as browserCompoundToolsEnabled, dt as fastGeneralPurposeModel, ft as fastImplementerModel, gn as pickClaudeDefault, gt as fastScoutModel, hn as isBudgetClaudeLead, ht as fastReviewerModel, it as agentToolsEnabled, lt as browserToolsEnabled, mt as fastPlanModel, o as buildPeerAwarenessSnippet, ot as brainstormModel, pt as fastOracleModel, qt as provisionBrowserAssets, r as agentNamesForToolAllowlist, rn as shouldUseInsecureTls, s as buildPeerAwarenessSummary, st as browseAgentEnabled, ut as fastAdvisorModel, vt as geminiAvailable, wt as reviewerModel, xt as nativeSubagentModel, yt as generalPurposeFastModel, zn as resolveLaunchProfile } from "./peer-mcp-personas-C9fDtu69.js";
2
2
  import { o as removeOwnClaudeConfigMirror, r as ensureClaudeConfigMirror, t as PATHS, u as writeArtifactCredsToMirror } from "./paths-IcZW8gZx.js";
3
3
  import { t as state } from "./state-B8adscCv.js";
4
4
  import { d as resolveModel } from "./token-CbuFyx-B.js";
5
5
  import { r as parseBoolEnv } from "./exec-y8C_MU8A.js";
6
- import { a as sharedServerArgs, c as stopKeepAwake, d as runSelfUpdate, f as checkClaudeVersion, i as setupAndServe, l as listModelsForEndpoint, o as LAUNCH_SECRET_HEADER, p as updateClaude, r as parseSharedArgs, s as startKeepAwake, t as getClaudeCodeEnvVars, u as enableFileLogging } from "./server-setup-CSkdFAPP.js";
6
+ import { a as sharedServerArgs, c as stopKeepAwake, d as enableFileLogging, f as runSelfUpdate, i as setupAndServe, l as injectModelPickerSettingsFile, m as updateClaude, o as LAUNCH_SECRET_HEADER, p as checkClaudeVersion, r as parseSharedArgs, s as startKeepAwake, t as getClaudeCodeEnvVars, u as listModelsForEndpoint } from "./server-setup-BP_JM0qb.js";
7
7
  import { t as FAST_PROFILE_ADVISOR_CLIENT_MODEL } from "./fast-profile-contract-OuZQaGif.js";
8
8
  import { c as formatMaxPrerequisiteFailure, f as maxGeminiModel, g as maxReviewerModel, i as MAX_PROFILE_MODELS, m as maxOpusModel, p as maxGrokModel } from "./max-profile-contract-CiD5wyET.js";
9
9
  import { n as hookLauncherDegradedWarning, r as resolveSelfInvocation } from "./self-invocation-BJWbA8ka.js";
10
- import { i as launchChild, r as getCodexVersion, t as provisionToolbelt } from "./provision-D3_GtXze.js";
10
+ import { i as launchChild, r as getCodexVersion, t as provisionToolbelt } from "./provision-Bn4FOzR4.js";
11
11
  import { i as captureLaunchBaseline, l as stopGateDisabled, n as buildSessionBindHookCommand, r as buildStopHookCommand, s as injectStopHookIntoSettingsFile, t as buildArtifactOpenHookCommand, u as stopGateId } from "./stop-gate-hook-CJOk28zd.js";
12
12
  import { t as liveExec } from "./orchestration-CYyp9w-t.js";
13
13
  import { c as repoRoot, d as trustRepo, l as stopGateEnabledForRepo, s as repoFingerprint, t as fileBaselineStore } from "./stop-gate-policy-zhzRIj6G.js";
14
14
  import { l as guardToolMatcher, n as activeDispatchModes, r as buildWorkerGuardHookCommand } from "./worker-dispatch-DgP5yT26.js";
15
- import { C as writePeerMcpRuntimeFiles, S as workersKeyOf, a as appendPeerAwarenessToMirroredClaudeMd, b as resolveCodexCliBackend, c as buildOperatingDefaultsDirective, d as prependStyleDirectiveToMirroredClaudeMd, f as buildArtifactReviewSkill, g as planModeAllowRules, h as injectAllowRules, i as writeInjectedSkill, l as prependArtifactPanelDirectiveToMirroredClaudeMd, o as appendToolbeltAwarenessToMirroredClaudeMd, r as injectedSkillsForLaunch, s as buildOperatingDefaultsDigest, t as injectAttributionSuppressionIntoSettingsFile, u as prependOperatingDefaultsToMirroredClaudeMd, x as resolveGroupKeysFromMirror, y as injectPeerMcpIntoMirror } from "./attribution-settings-C8iSwEAZ.js";
15
+ import { C as writePeerMcpRuntimeFiles, S as workersKeyOf, a as appendPeerAwarenessToMirroredClaudeMd, b as resolveCodexCliBackend, c as buildOperatingDefaultsDirective, d as prependStyleDirectiveToMirroredClaudeMd, f as buildArtifactReviewSkill, g as planModeAllowRules, h as injectAllowRules, i as writeInjectedSkill, l as prependArtifactPanelDirectiveToMirroredClaudeMd, o as appendToolbeltAwarenessToMirroredClaudeMd, r as injectedSkillsForLaunch, s as buildOperatingDefaultsDigest, t as injectAttributionSuppressionIntoSettingsFile, u as prependOperatingDefaultsToMirroredClaudeMd, x as resolveGroupKeysFromMirror, y as injectPeerMcpIntoMirror } from "./attribution-settings-Chqw6VeK.js";
16
16
  import { r as hookMcpRuntimeFromEnv } from "./hook-mcp-client-DBvm9608.js";
17
17
  import { i as planReviewEnabled, t as buildPlanReviewHookCommand } from "./plan-review-hook-szSNt6uU.js";
18
- import { a as checksForDescriptor, i as writeDiscoveredGate, n as readDiscoveredGate, o as descriptorHash, r as sourcesHash, s as parseGateDescriptor, t as discoverGateCommands } from "./gate-discovery-D4-F99e_.js";
18
+ import { a as checksForDescriptor, i as writeDiscoveredGate, n as readDiscoveredGate, o as descriptorHash, r as sourcesHash, s as parseGateDescriptor, t as discoverGateCommands } from "./gate-discovery-C6jB3bBG.js";
19
19
  import { t as buildPromptSubmitHookCommand } from "./prompt-submit-hook-ZUxo_jEl.js";
20
20
  import { i as assertShapingInstalled, n as buildFirstMateGuardHookCommand, t as FIRST_MATE_GUARD_MATCHER } from "./internal-first-mate-guard-Bcb5JwiO.js";
21
21
  import { r as FAST_DISPATCH_TOOL_MATCHER, t as buildFastDispatchGuardHookCommand } from "./internal-fast-dispatch-guard-BaUB-F8o.js";
@@ -345,7 +345,16 @@ const claude = defineCommand({
345
345
  }
346
346
  const banner = chosenSlug === resolvedSlug ? chosenSlug : `${chosenSlug} → ${resolvedSlug}`;
347
347
  process$1.stderr.write(`Server ready on ${serverUrl}, launching Claude Code (${banner})...\n`);
348
- const envVars = getClaudeCodeEnvVars(serverUrl, chosenSlug, launchProfileId);
348
+ let pickerModels;
349
+ try {
350
+ const settingsPath = path.join(PATHS.CLAUDE_CONFIG_DIR, "settings.json");
351
+ const picker = await injectModelPickerSettingsFile(settingsPath, launchProfileId);
352
+ pickerModels = picker.models;
353
+ if (picker.reason === "user-set") consola.info("Preserving the user-configured modelPicker for this launch; router-curated rows were not merged.");
354
+ } catch (err) {
355
+ consola.warn(`Model-picker settings injection skipped: ${err instanceof Error ? err.message : String(err)}. Use an explicit -m model if the curated rows are unavailable.`);
356
+ }
357
+ const envVars = getClaudeCodeEnvVars(serverUrl, chosenSlug, launchProfileId, pickerModels);
349
358
  let extraArgs = collectChildPassthroughArgs(rawArgs, claudeArgs);
350
359
  if (launchProfileId === "fast") extraArgs = withFixedFastAdvisorArg(extraArgs, fastAdvisorClientEnabled(process$1.env));
351
360
  if (toolbeltEnabled()) {
@@ -848,4 +857,4 @@ const claude = defineCommand({
848
857
  //#endregion
849
858
  export { claude };
850
859
 
851
- //# sourceMappingURL=claude-Drv0roq1.js.map
860
+ //# sourceMappingURL=claude-C3LWG_3H.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-C3LWG_3H.js","names":["process","nodePath","resolveMaxReviewerModel"],"sources":["../src/lib/orchestration/fast-dispatch-hook.ts","../src/lib/fast-launch-cleanup.ts","../src/lib/fast-advisor-client.ts","../src/claude.ts"],"sourcesContent":["import { buildSelfCommand, type SelfInvocation } from \"../hook-launcher/self-invocation\"\nimport { FAST_DISPATCH_TOOL_MATCHER } from \"../fast-dispatch-acl\"\n\n/** The anchored matcher Claude Code applies before invoking the guard. */\nexport { FAST_DISPATCH_TOOL_MATCHER as FAST_DISPATCH_GUARD_MATCHER } from \"../fast-dispatch-acl\"\n\n/** Sentinel preserved through claude.ts's optional codex-MCP catch. */\nexport class FastDispatchGuardInstallError extends Error {\n constructor(message: string) {\n super(message)\n this.name = \"FastDispatchGuardInstallError\"\n }\n}\n\n/** Assert fast launches never spawn without their native dispatch ACL. */\nexport function assertFastDispatchGuardInstalled(\n fastProfile: boolean,\n installationSucceeded: boolean,\n): void {\n if (fastProfile && !installationSucceeded) {\n throw new FastDispatchGuardInstallError(\n \"fast profile requires the native Task/Agent ACL hook, but it could not be installed; refusing to start an unguarded fast session.\",\n )\n }\n}\n\n/** Build the persisted command for the fast-profile native dispatch guard. */\nexport function buildFastDispatchGuardHookCommand(invocation: SelfInvocation): string {\n return buildSelfCommand(invocation, \"internal-fast-dispatch-guard\")\n}\n\n/** Install the fast-only hook through the shared settings writer. */\nexport async function installFastDispatchGuard(\n settingsPath: string,\n command: string,\n inject: (\n settingsPath: string,\n command: string,\n event: string,\n timeoutSec: number,\n matcher: string,\n ) => Promise<unknown>,\n): Promise<void> {\n await inject(settingsPath, command, \"PreToolUse\", 10, FAST_DISPATCH_TOOL_MATCHER)\n}\n\n/** This module is intentionally stateless; callers own launch cleanup. */\n","/**\n * Cleanup for a fast-profile launch that fails after setupAndServe.\n *\n * The normal launchChild path owns shutdown once the child is spawned. Before\n * that point, fast prerequisite failures must tear down the server and mirror\n * themselves because process.exit() does not await pending work. The returned\n * function is single-flight and idempotent so a fatal path and a signal cannot\n * duplicate teardown.\n */\nexport interface FastLaunchCleanupDeps {\n server?: { close(force?: boolean): Promise<unknown> }\n stopKeepAwake: () => Promise<void>\n removeMirror: () => Promise<void>\n runtimeCleanup?: () => Promise<void>\n}\n\nexport function createFastLaunchCleanup(\n deps: FastLaunchCleanupDeps,\n): () => Promise<void> {\n let cleanupPromise: Promise<void> | undefined\n return () => {\n if (cleanupPromise) return cleanupPromise\n cleanupPromise = (async () => {\n try {\n await deps.server?.close(true)\n } catch {\n /* already closed or unavailable */\n }\n try {\n await deps.stopKeepAwake()\n } catch {\n /* best-effort */\n }\n if (deps.runtimeCleanup) {\n try {\n await deps.runtimeCleanup()\n } catch {\n /* best-effort */\n }\n }\n try {\n await deps.removeMirror()\n } catch {\n /* best-effort */\n }\n })()\n return cleanupPromise\n }\n}\n","import { FAST_PROFILE_ADVISOR_CLIENT_MODEL } from \"./fast-profile-contract\"\n\nconst ADVISOR_FLAG = \"--advisor\"\n\nfunction featureEnvEnabled(value: string | undefined): boolean {\n if (value === undefined) return true\n return ![\"\", \"0\", \"false\", \"no\", \"off\"].includes(value.trim().toLowerCase())\n}\n\n/** Match Claude Code's hard-disable and experimental-enable opt-out semantics. */\nexport function fastAdvisorClientEnabled(\n env: NodeJS.ProcessEnv = process.env,\n): boolean {\n if (env.CLAUDE_CODE_DISABLE_ADVISOR_TOOL) return false\n return featureEnvEnabled(env.CLAUDE_CODE_ENABLE_EXPERIMENTAL_ADVISOR_TOOL)\n}\n\n/**\n * Remove every caller-supplied Advisor option and insert the fixed fast value.\n *\n * This parser intentionally keeps scanning after `--`: that separator marks\n * github-router-to-Claude passthrough, not an exemption from the fixed profile.\n * The fixed option is inserted before the first separator so Claude Code parses\n * it as an option rather than positional input. A separate `--advisor` consumes\n * its next token only when it is a value rather than another option; malformed\n * missing-value forms are simply removed.\n */\nexport function withFixedFastAdvisorArg(\n args: ReadonlyArray<string>,\n enabled = fastAdvisorClientEnabled(),\n): string[] {\n const sanitized: string[] = []\n for (let index = 0; index < args.length; index++) {\n const token = args[index]!\n if (token === ADVISOR_FLAG) {\n const next = args[index + 1]\n if (next !== undefined && next !== \"--\" && !next.startsWith(\"-\")) index++\n continue\n }\n if (token.startsWith(`${ADVISOR_FLAG}=`)) continue\n sanitized.push(token)\n }\n if (!enabled) return sanitized\n const separator = sanitized.indexOf(\"--\")\n const fixed = [ADVISOR_FLAG, FAST_PROFILE_ADVISOR_CLIENT_MODEL]\n if (separator < 0) return [...sanitized, ...fixed]\n return [\n ...sanitized.slice(0, separator),\n ...fixed,\n ...sanitized.slice(separator),\n ]\n}\n","import process from \"node:process\"\n\nimport { defineCommand, type ArgsDef } from \"citty\"\nimport consola from \"consola\"\n\nimport {\n checkClaudeVersion,\n updateClaude,\n} from \"./lib/claude-version-check\"\nimport { runSelfUpdate } from \"./lib/self-update\"\nimport {\n injectPeerMcpIntoMirror,\n resolveCodexCliBackend,\n resolveGroupKeysFromMirror,\n workersKeyOf,\n writePeerMcpRuntimeFiles,\n} from \"./lib/codex-mcp-config\"\nimport { enableFileLogging } from \"./lib/file-log-reporter\"\nimport {\n hookLauncherDegradedWarning,\n resolveSelfInvocation,\n} from \"./lib/hook-launcher/self-invocation\"\nimport { getCodexVersion, launchChild } from \"./lib/launch\"\nimport { injectAllowRules, planModeAllowRules } from \"./lib/mcp-permissions-settings\"\nimport { listModelsForEndpoint } from \"./lib/model-validation\"\nimport { ensureClaudeConfigMirror, PATHS, removeOwnClaudeConfigMirror, writeArtifactCredsToMirror } from \"./lib/paths\"\nimport { injectModelPickerSettingsFile } from \"./lib/model-picker-settings\"\nimport {\n buildArtifactOpenHookCommand,\n buildSessionBindHookCommand,\n buildStopHookCommand,\n captureLaunchBaseline,\n injectStopHookIntoSettingsFile,\n stopGateId,\n stopGateDisabled,\n} from \"./lib/orchestration/stop-gate-hook\"\nimport { buildPlanReviewHookCommand, planReviewEnabled } from \"./lib/orchestration/plan-review-hook\"\nimport {\n fileBaselineStore,\n repoFingerprint,\n repoRoot,\n stopGateEnabledForRepo,\n trustRepo,\n} from \"./lib/orchestration/stop-gate-policy\"\nimport {\n checksForDescriptor,\n descriptorHash,\n parseGateDescriptor,\n type GateDescriptor,\n} from \"./lib/orchestration/harness-parse\"\nimport {\n discoverGateCommands,\n readDiscoveredGate,\n sourcesHash,\n writeDiscoveredGate,\n} from \"./lib/orchestration/gate-discovery\"\nimport { liveExec } from \"./lib/orchestration/live-exec\"\nimport { hookMcpRuntimeFromEnv } from \"./lib/orchestration/hook-mcp-client\"\nimport { buildPromptSubmitHookCommand } from \"./lib/orchestration/prompt-submit-hook\"\nimport {\n FIRST_MATE_GUARD_MATCHER,\n buildFirstMateGuardHookCommand,\n} from \"./internal-first-mate-guard\"\nimport { assertShapingInstalled } from \"./lib/first-mate/operator-shaping\"\nimport {\n activeDispatchModes,\n buildWorkerGuardHookCommand,\n guardToolMatcher,\n} from \"./lib/worker-dispatch\"\nimport { buildFastDispatchGuardHookCommand } from \"./internal-fast-dispatch-guard\"\nimport {\n FAST_DISPATCH_TOOL_MATCHER,\n} from \"./lib/fast-dispatch-acl\"\nimport {\n assertFastDispatchGuardInstalled,\n} from \"./lib/orchestration/fast-dispatch-hook\"\nimport { buildMaxDispatchGuardHookCommand } from \"./internal-max-dispatch-guard\"\nimport {\n MAX_DISPATCH_TOOL_MATCHER,\n assertMaxDispatchGuardInstalled,\n} from \"./lib/max-dispatch-acl\"\nimport {\n MAX_PROFILE_MODELS,\n maxGeminiModel,\n maxGrokModel,\n maxOpusModel,\n maxReviewerModel as resolveMaxReviewerModel,\n} from \"./lib/max-profile-contract\"\nimport { buildArtifactReviewSkill, injectedSkillsForLaunch, writeInjectedSkill } from \"./lib/injected-skills\"\nimport { shouldUseInsecureTls } from \"./lib/artifact/tools\"\nimport { parseBoolEnv } from \"./lib/exec\"\nimport nodePath from \"node:path\"\nimport { tmpdir } from \"node:os\"\nimport { randomBytes } from \"node:crypto\"\nimport {\n agentNamesForToolAllowlist,\n buildPeerAwarenessSnippet,\n buildPeerAwarenessSummary,\n type McpGroup,\n type NativeAgentName,\n} from \"./lib/peer-mcp-personas\"\nimport { injectAttributionSuppressionIntoSettingsFile } from \"./lib/attribution-settings\"\nimport { appendPeerAwarenessToMirroredClaudeMd, appendToolbeltAwarenessToMirroredClaudeMd, buildOperatingDefaultsDigest, buildOperatingDefaultsDirective, type NativeAgentAvailability, prependArtifactPanelDirectiveToMirroredClaudeMd, prependOperatingDefaultsToMirroredClaudeMd, prependStyleDirectiveToMirroredClaudeMd } from \"./lib/claude-md-injection\"\nimport { availableToolCommands, buildToolbeltAwareness, toolbeltEnabled } from \"./lib/toolbelt\"\nimport { provisionToolbelt } from \"./lib/toolbelt/provision\"\nimport { colbertDegradedWarning, provisionAndIndexColbert } from \"./lib/colbert\"\nimport { startKeepAwake, stopKeepAwake } from \"./lib/keep-awake\"\nimport { warmTreeSitterPool } from \"./lib/tree-sitter-pool/pool\"\nimport { provisionBrowserAssets } from \"./lib/browser-mcp/provision\"\nimport {\n DEFAULT_CLAUDE_MODEL_FALLBACKS,\n isBudgetClaudeLead,\n pickClaudeDefault,\n resolveLeadSlugArg,\n} from \"./lib/port\"\nimport {\n agentToolsEnabled,\n artifactToolsEnabled,\n browseAgentEnabled,\n browserCompoundToolsEnabled,\n browserToolsEnabled,\n fleetToolsEnabled,\n geminiAvailable,\n nativeSubagentModel,\n brainstormModel,\n reviewerModel,\n reviewerFastModel,\n resolveGeminiReviewModel,\n scoutModel,\n scribeModel,\n implementerFastModel,\n generalPurposeFastModel,\n standInToolEnabled,\n workerToolsEnabled,\n fastScoutModel,\n fastPlanModel,\n fastGeneralPurposeModel,\n fastImplementerModel,\n fastReviewerModel,\n fastAdvisorModel,\n fastOracleModel,\n} from \"./lib/mcp-capabilities\"\nimport {\n getClaudeCodeEnvVars,\n parseSharedArgs,\n setupAndServe,\n sharedServerArgs,\n} from \"./lib/server-setup\"\nimport {\n formatFastPrerequisiteFailure,\n formatMaxPrerequisiteFailure,\n LUNA_DRIVER_ALIAS_ID,\n profileDescriptor,\n resolveLaunchProfile,\n validateFastProfilePrerequisites,\n validateMaxProfileLaunch,\n} from \"./lib/launch-profile\"\nimport { registerLaunch, unregisterLaunch } from \"./lib/launch-registry\"\nimport { LAUNCH_SECRET_HEADER } from \"./lib/messages-identity-preflight\"\nimport { state } from \"./lib/state\"\nimport { resolveModel } from \"./lib/utils\"\nimport { createFastLaunchCleanup } from \"./lib/fast-launch-cleanup\"\nimport {\n fastAdvisorClientEnabled,\n withFixedFastAdvisorArg,\n} from \"./lib/fast-advisor-client\"\n\nexport const claudeArgs = {\n ...sharedServerArgs,\n model: {\n alias: \"m\",\n type: \"string\",\n description:\n \"Override the default model for Claude Code. Accepts a full slug (e.g. claude-opus-4-7) or an Opus family shorthand (e.g. 4.7, 4.8, 4.6) which expands to the best variant for that family — adding the [1m] suffix when a 1M-context backend is in the catalog.\",\n },\n \"codex-mcp\": {\n type: \"boolean\" as const,\n default: true,\n description:\n \"Wire peer-model MCP personas (codex-critic, codex-reviewer, gemini-critic) into the spawned Claude Code session\",\n },\n \"codex-cli\": {\n type: \"boolean\" as const,\n default: false,\n description:\n \"Add a `codex mcp-server` stdio backend so codex-implementer can mutate files. Requires codex CLI 0.129+; gracefully falls back to HTTP-only if absent.\",\n },\n \"codex-mcp-only\": {\n type: \"boolean\" as const,\n default: false,\n description:\n \"Pass --strict-mcp-config to claude code so only github-router's MCP servers are loaded (hides user's existing MCP servers)\",\n },\n stealth: {\n type: \"boolean\" as const,\n default: false,\n description:\n \"Opt back into VS Code-only beta header filtering. Loses leverage features (task budgets, token-efficient tools, prompt caching, etc.) but minimizes the wire-fingerprint difference from VS Code Copilot Chat. By default the `claude` subcommand enables extended/leverage betas because the spawned Claude Code already identifies itself via UA and other headers — partial stealth doesn't buy much.\",\n },\n \"trust-gate\": {\n type: \"boolean\" as const,\n default: false,\n description:\n \"Explicitly record consent for the structural Stop-gate in THIS repo (pinned to the repo's root-commit). The gate is ON BY DEFAULT when a harness is detected (consent-by-launching), so this is now mostly redundant; it stays for explicit/scripted use. Disable the gate entirely with GH_ROUTER_DISABLE_STOP_GATE=1.\",\n },\n \"no-stop-gate\": {\n type: \"boolean\" as const,\n default: false,\n description:\n \"Disable the structural Stop-gate for THIS session (same effect as GH_ROUTER_DISABLE_STOP_GATE=1). Intended for driven/automated sessions where a blocking Stop hook would hang the turn-end while a fleet driver waits.\",\n },\n \"auto-update\": {\n type: \"boolean\" as const,\n default: true,\n description:\n \"Check for and install the latest Claude Code on launch via `claude update` (throttled to once per hour via ~/.local/share/github-router/last-update-check). `claude update` respects the real install method (native installer or npm), so it never creates a conflicting second install; builds too old to support it fall back to `npm install -g @anthropic-ai/claude-code@latest`. Set to false (--no-auto-update) to check and warn only. Falls back gracefully if claude/npm/network unavailable.\",\n },\n \"update-check\": {\n type: \"boolean\" as const,\n default: true,\n description:\n \"Check the npm registry for a newer Claude Code version on launch and warn if stale (non-blocking ~500ms cost). Set to false (--no-update-check) to skip the check entirely (useful for offline/CI). Independent from --auto-update: --no-update-check implies no auto-install (nothing to install since we never check).\",\n },\n} satisfies ArgsDef\n\n/**\n * Build the argv to forward to the spawned `claude` child from citty's\n * rawArgs (every token after the `claude` subcommand). citty is non-strict,\n * so an unknown flag such as `--print`/`-p`… `--output-format` is absorbed\n * into the parsed `args` object AND its value swallowed, instead of landing\n * in `args._`; forwarding only `args._` therefore drops headless flags unless\n * the user wrapped them in `--`. Here we walk rawArgs and forward every token\n * that is NOT one of github-router's OWN declared flags (or that flag's\n * consumed value). Everything after a literal `--` is forwarded verbatim,\n * preserving the prior explicit-passthrough behavior.\n *\n * A child flag whose NAME collides with a github-router flag (`-p`/`--port`,\n * `-v`/`--verbose`, `-m`/`--model`, `-a`/`--account-type`, `-r`/`--rate-limit`,\n * `-g`/`--github-token`) is owned by github-router; forward it to the child\n * explicitly after `--` (e.g. `github-router claude -- -p`). Every other Claude\n * flag (`--print`, `--output-format`, `--resume`, `--continue`, …) flows\n * through automatically.\n */\nexport function collectChildPassthroughArgs(\n rawArgs: ReadonlyArray<string>,\n argsDef: ArgsDef,\n): string[] {\n const known = new Set<string>()\n const stringTyped = new Set<string>()\n for (const [name, def] of Object.entries(argsDef)) {\n const rawAlias = \"alias\" in def ? def.alias : undefined\n const aliases =\n rawAlias === undefined\n ? []\n : Array.isArray(rawAlias)\n ? rawAlias\n : [rawAlias]\n for (const n of [name, ...aliases]) {\n known.add(n)\n if (def.type === \"string\") stringTyped.add(n)\n }\n }\n\n const forwarded: string[] = []\n for (let i = 0; i < rawArgs.length; i++) {\n const tok = rawArgs[i]\n // Explicit passthrough separator: forward everything after `--` verbatim\n // (matches the prior `args._`-only behavior, where citty routed post-`--`\n // tokens into `_`).\n if (tok === \"--\") {\n forwarded.push(...rawArgs.slice(i + 1))\n break\n }\n // A bare `-` or a non-dash token is a positional / value → forward.\n if (tok === \"-\" || !tok.startsWith(\"-\")) {\n forwarded.push(tok)\n continue\n }\n const doubleDash = tok.startsWith(\"--\")\n const afterDashes = tok.slice(doubleDash ? 2 : 1)\n const eq = afterDashes.indexOf(\"=\")\n const rawName = eq >= 0 ? afterDashes.slice(0, eq) : afterDashes\n const hasInlineValue = eq >= 0\n const negated = doubleDash && rawName.startsWith(\"no-\")\n const baseName = negated ? rawName.slice(3) : rawName\n\n const isKnown = known.has(rawName) || (negated && known.has(baseName))\n if (!isKnown) {\n // Unknown to github-router → belongs to the child claude (e.g. --print).\n forwarded.push(tok)\n continue\n }\n // Own flag: drop it. Also drop a separately-tokenized value for a\n // string-typed flag written as `--flag value` / `-a value` (no inline\n // `=`, next token present and not itself a flag). Booleans and `--no-…`\n // negations never consume a following token under citty/mri.\n const consumesValue =\n !negated\n && !hasInlineValue\n && stringTyped.has(rawName)\n && i + 1 < rawArgs.length\n && rawArgs[i + 1] !== \"--\"\n && !rawArgs[i + 1].startsWith(\"-\")\n if (consumesValue) i++\n }\n return forwarded\n}\n\nexport const claude = defineCommand({\n meta: {\n name: \"claude\",\n description: \"Start the proxy server and launch Claude Code\",\n },\n args: claudeArgs,\n async run({ args, rawArgs }) {\n // TTY requirement, with a narrowly-scoped opt-in bypass for headless\n // verification harnesses. `claude` normally assumes an interactive\n // terminal (the spawned Claude Code renders a TUI), so a piped-stdout\n // invocation (e.g. `bun run ./src/main.ts claude | cat`) is refused by\n // default. But `--print --input-format stream-json --output-format\n // stream-json` is Claude Code's own documented non-interactive mode —\n // it never touches the TTY — so an internal harness (e.g.\n // `scripts/probe-prompt-cache.ts`, see docs/prompt-caching.md) that\n // spawns exactly that combination has a legitimate reason to run with\n // piped stdio. `GH_ROUTER_ALLOW_HEADLESS_CLAUDE=1` opts into that path;\n // the default remains a hard TTY requirement for ordinary interactive\n // use, and the flag is not advertised as a general-purpose CLI option.\n const headlessProbeRequested =\n process.env.GH_ROUTER_ALLOW_HEADLESS_CLAUDE === \"1\"\n && rawArgs.includes(\"--print\")\n && rawArgs.includes(\"--input-format\")\n && rawArgs.includes(\"--output-format\")\n && rawArgs.filter((arg) => arg === \"stream-json\").length >= 2\n if (!process.stdout.isTTY && !headlessProbeRequested) {\n consola.error(\"The claude subcommand requires a TTY (interactive terminal).\")\n process.exit(1)\n }\n\n const parsed = parseSharedArgs(args as unknown as Record<string, unknown>)\n const requestedLaunchProfileId = resolveLaunchProfile(args.model)\n const codexMcpEnabled = (args as Record<string, unknown>)[\"codex-mcp\"] !== false\n\n // Fast and max native agents depend on the generated MCP runtime and their mandatory\n // Task/Agent ACL hook. Refuse this combination before setup or any runtime\n // artifact is written rather than silently launching with no native roster enforcement.\n if (requestedLaunchProfileId === \"max\" && ((args as Record<string, unknown>)[\"codex-cli\"] as boolean | undefined)) {\n const message =\n \"Max profile uses its fixed HTTP MCP surface; --codex-cli is not supported in max profile.\"\n process.stderr.write(`${message}\\n`)\n process.exit(1)\n }\n if (\n (requestedLaunchProfileId === \"fast\" || requestedLaunchProfileId === \"max\")\n && !codexMcpEnabled\n ) {\n const profileName = requestedLaunchProfileId === \"fast\" ? \"fast\" : \"max\"\n const message =\n `github-router claude -m ${profileName} requires codex MCP wiring for its native roster and dispatch ACL; remove --no-codex-mcp or choose a standard model.`\n process.stderr.write(`${message}\\n`)\n process.exit(1)\n }\n\n // Phase E P2.2: stealth-vs-leverage policy.\n // The `claude` subcommand defaults to LEVERAGE mode (extended-betas\n // ON) because the spawned Claude Code already identifies itself via\n // UA / editor-version / x-app headers — partial stealth doesn't\n // meaningfully reduce the wire fingerprint, and the cost of stealth\n // is losing features the user explicitly chose to install Claude\n // Code for (--max-budget-usd, token-efficient tools, prompt caching,\n // structured outputs, MCP, etc.).\n //\n // The `--stealth` flag opts back into the VS Code-only filter for\n // users who specifically want minimal wire diff over leverage.\n // The shared `--extended-betas` flag still works (treated as alias).\n //\n // Note: `advisor-tool-` is stripped in BOTH modes regardless of this\n // setting (Phase A: Copilot 400s on it). ADVISOR will be served via\n // Phase I's proxy-side translate path independently.\n if (args.stealth) {\n // Stealth wins if explicitly requested.\n parsed.extendedBetas = false\n consola.info(\n \"Stealth mode: VS Code-only beta filtering. Leverage features disabled.\",\n )\n } else if (!args[\"extended-betas\"]) {\n // No explicit --extended-betas AND no --stealth → default ON.\n parsed.extendedBetas = true\n }\n // If user passed --extended-betas explicitly, parsed already reflects it.\n\n // Phase H P2: Claude Code version check + opt-in auto-update.\n // Default: check + auto-install if newer version available\n // (throttled to once per hour). The user explicitly chose to install\n // a Claude Code wrapper — they want the latest features and bug\n // fixes. Opt-out via --no-auto-update (check only, warn) or\n // --no-update-check (silence entirely). Best-effort: skips silently\n // if npm is offline or claude is not on PATH. The check happens\n // BEFORE setupAndServe so a stale version doesn't get spawned.\n if (args[\"update-check\"] !== false) {\n try {\n const versionCheck = await checkClaudeVersion({\n noCheck: false,\n })\n if (versionCheck.skipped && versionCheck.skipReason === \"no-claude\") {\n // Claude isn't on PATH — let launchChild surface the more\n // contextual \"claude not found\" error in the spawn step.\n consola.debug(\n \"claude --version probe failed; skipping auto-update.\",\n )\n } else if (versionCheck.skipped && versionCheck.skipReason === \"no-npm\") {\n // npm view failed — likely offline. Don't block launch.\n consola.debug(\n \"npm view @anthropic-ai/claude-code failed; skipping auto-update check (likely offline).\",\n )\n } else if (\n versionCheck.needsUpdate\n && versionCheck.installedVersion\n && versionCheck.latestVersion\n ) {\n if (args[\"auto-update\"] !== false) {\n try {\n await updateClaude(versionCheck.latestVersion)\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err)\n consola.warn(\n `Auto-update of Claude Code from ${versionCheck.installedVersion} to ${versionCheck.latestVersion} failed (${msg}); continuing with installed version. Run \\`claude update\\` (or \\`npm install -g @anthropic-ai/claude-code@latest\\`) manually to retry.`,\n )\n }\n } else {\n consola.warn(\n `Claude Code v${versionCheck.installedVersion} is installed; v${versionCheck.latestVersion} is available. Run with --auto-update (the default) to install on launch, or \\`claude update\\` manually.`,\n )\n }\n }\n } catch (err) {\n // Whole version-check should never block launch.\n consola.debug(\"Claude version check failed:\", err)\n }\n }\n\n let server: Awaited<ReturnType<typeof setupAndServe>>[\"server\"]\n let serverUrl: string\n try {\n const result = await setupAndServe({\n ...parsed,\n port: parsed.port, // undefined = random port\n silent: true,\n })\n server = result.server\n serverUrl = result.serverUrl\n } catch (error) {\n consola.error(\"Failed to start server:\", error instanceof Error ? error.message : error)\n process.exit(1)\n }\n\n // Queue a best-effort self-update of github-router itself (detached,\n // applies next launch). Fire-and-forget so the bounded npm probe\n // never delays spawning Claude Code.\n void runSelfUpdate({ selfUpdate: args[\"self-update\"] !== false })\n\n // A failed mirror provision happens after the server is listening but before\n // any runtime artifacts exist. Close the server explicitly before exiting;\n // process.exit does not await pending shutdown work.\n const cleanupPreMirrorFailure = createFastLaunchCleanup({\n server,\n stopKeepAwake,\n removeMirror: removeOwnClaudeConfigMirror,\n })\n\n // Provision the router-owned CLAUDE_CONFIG_DIR with our synthetic\n // .credentials.json + a snapshot copy of the user's ~/.claude/.\n // The spawned Claude Code (and any teammates it spawns via the\n // agent-teams primitive) reads this dir instead of ~/.claude/,\n // finds our synthetic credential, and authenticates — closing the\n // teammate-spawn allowlist gap that drops ANTHROPIC_AUTH_TOKEN.\n // See ensureClaudeConfigMirror in src/lib/paths.ts.\n //\n // Run BEFORE enableFileLogging so a fatal credentials-write failure\n // surfaces on the user's terminal (we only throw on the credentials\n // write — copy failures of individual user files are debug-logged\n // and skipped).\n try {\n await ensureClaudeConfigMirror()\n } catch (err) {\n consola.error(\n `Failed to provision CLAUDE_CONFIG_DIR mirror: ${\n err instanceof Error ? err.message : String(err)\n }. Spawned Claude Code would not be able to authenticate.`,\n )\n await cleanupPreMirrorFailure()\n process.exit(1)\n }\n\n enableFileLogging() // redirect errors/warnings to file; suppress terminal output\n\n // Fast runtime artifacts are not owned by `launchChild` until its shutdown\n // callback is transferred. Keep an explicit pre-spawn cleanup handle so a\n // fast-only setup failure cannot leave runtime files or a launch-registry\n // entry behind while the broad standard-profile catch remains lenient.\n let fastRuntimeCleanup: (() => Promise<void>) | undefined\n let fastLaunchId: string | undefined\n let fastCleanupPromise: Promise<void> | undefined\n const disposeFastRuntime = async (): Promise<void> => {\n if (!fastRuntimeCleanup) return\n fastCleanupPromise ??= fastRuntimeCleanup()\n await fastCleanupPromise\n }\n const resetFastRuntimeOwnership = (): void => {\n fastRuntimeCleanup = undefined\n fastLaunchId = undefined\n }\n const cleanupFastLaunch = createFastLaunchCleanup({\n server,\n stopKeepAwake,\n removeMirror: removeOwnClaudeConfigMirror,\n runtimeCleanup: async () => {\n if (fastRuntimeCleanup) await fastRuntimeCleanup()\n },\n })\n const fastFatal = async (message: string): Promise<never> => {\n consola.error(message)\n process.stderr.write(`${message}\\n`)\n await cleanupFastLaunch()\n process.exit(1)\n throw new Error(\"process.exit returned unexpectedly\")\n }\n\n // Two slugs flow through this code:\n // * `chosenSlug` — the value we set for `ANTHROPIC_MODEL`. Must be an\n // Anthropic-published slug (e.g. `claude-opus-4-8`) so Claude Code's\n // hardcoded `/model` registry matches it and the UI shows the right\n // menu entry. The proxy's resolver translates this back to a Copilot\n // slug at request time, so the actual upstream call still works.\n // * `resolvedSlug` — the Copilot-side slug after `resolveModel`. Used\n // only for cache-presence validation (fallback chain) and the\n // launch banner.\n //\n // For the implicit-default path only, we walk\n // DEFAULT_CLAUDE_MODEL_FALLBACKS when neither the default nor any\n // earlier fallback resolves to a model present in the Copilot cache.\n // Explicit `--model` is respected as-is — including Copilot slugs\n // (which Claude Code's UI won't recognize, but power users may want\n // for explicit pinning).\n // `-m 4.7` / `-m 4.8` shorthand: treat a bare \"N.M\" value as an\n // Opus-family preference and let pickClaudeDefault pick the best\n // variant for that family (adding [1m] when an opus-N.M-1m backend\n // exists in the catalog). Full slugs and any non-matching string\n // continue to pass through unchanged. `usingDefault` stays false\n // for shorthand so the DEFAULT_CLAUDE_MODEL_FALLBACKS walk doesn't\n // override an explicit family request with the next-older Opus.\n //\n // `-m fast` now selects the explicit Luna profile. Profile selection uses the\n // RAW alias below, while lead resolution maps it to gpt-5.6-luna; a direct\n // Luna pin remains a standard-surface launch.\n // Trimmed, and it must stay in lockstep with `resolveLeadSlugArg`'s own\n // trim: that helper treats `-m \" \"` as absent and returns the default, so\n // computing `usingDefault` from the untrimmed argument would pick the\n // default model while suppressing the fallback walk that exists to rescue\n // it when the catalog lacks that family.\n const usingDefault = !args.model?.trim()\n const requestedSlug = resolveLeadSlugArg(args.model)\n // Resolved from the RAW `-m` argument, never the resolved lead slug —\n // see `resolveLaunchProfile`'s doc for why: only the literal \"fast\"\n // alias narrows the surface, so a direct `-m gpt-5.6-luna` pin stays a\n // standard-surface launch even though it drives the same model.\n const launchProfileId = resolveLaunchProfile(args.model)\n if (launchProfileId === \"fast\") {\n // Capability-availability prerequisites for the EXACT fast roster —\n // not an allowlist of models selectable later. Checked once, here,\n // against the catalog `setupAndServe` just populated; a partial\n // catalog fails the whole launch rather than silently substituting\n // or dropping an agent.\n const prereqCheck = validateFastProfilePrerequisites(state.models)\n if (!prereqCheck.ok) {\n const message = formatFastPrerequisiteFailure(prereqCheck.missing)\n await fastFatal(message)\n }\n } else if (launchProfileId === \"max\") {\n const prereqCheck = validateMaxProfileLaunch(state.models)\n if (!prereqCheck.ok) {\n const message = formatMaxPrerequisiteFailure(prereqCheck.missing)\n await fastFatal(message)\n }\n } else {\n // Standard profile behavior is unchanged. This branch intentionally keeps\n // all ordinary launches on the existing catalog/model flow.\n }\n let chosenSlug =\n launchProfileId === \"fast\"\n ? (requestedSlug.endsWith(\"[1m]\") ? `${LUNA_DRIVER_ALIAS_ID}[1m]` : LUNA_DRIVER_ALIAS_ID)\n : requestedSlug\n let resolvedSlug =\n launchProfileId === \"fast\" ? resolveModel(requestedSlug) : resolveModel(chosenSlug)\n\n if (usingDefault && state.models) {\n const inCache = (slug: string) =>\n state.models?.data.some((m) => m.id === resolveModel(slug)) ?? false\n if (!inCache(chosenSlug)) {\n for (const fallback of DEFAULT_CLAUDE_MODEL_FALLBACKS) {\n if (inCache(fallback)) {\n // Re-derive through pickClaudeDefault so 1M detection runs against\n // the FALLBACK's own family. The constant holds bare slugs, so\n // assigning one directly silently drops [1m] accounting on a\n // family that is 1M-capable — the user lands on a working model\n // with a 200k context budget it did not need to accept.\n // `inCache` already proved the family is present, so this cannot\n // trigger pickClaudeDefault's family-absent warning.\n const fallbackSlug = pickClaudeDefault(\n fallback.replace(/^claude-opus-/, \"\"),\n )\n consola.info(\n `Default model \"${chosenSlug}\" not in your Copilot model list; falling back to \"${fallbackSlug}\".`,\n )\n chosenSlug = fallbackSlug\n resolvedSlug = resolveModel(fallbackSlug)\n break\n }\n }\n }\n }\n\n if (resolvedSlug !== chosenSlug) {\n consola.info(`Model \"${chosenSlug}\" resolved to \"${resolvedSlug}\"`)\n }\n const modelEntry = state.models?.data.find((m) => m.id === resolvedSlug)\n if (!modelEntry) {\n const available = listModelsForEndpoint(\"/v1/messages\")\n consola.warn(\n `Model \"${resolvedSlug}\" not found. Available claude models: ${available.join(\", \")}`,\n )\n }\n\n // Banner shows the round-trip so the user sees both names. Claude Code's\n // UI will display the chosenSlug; Copilot upstream sees resolvedSlug.\n const banner =\n chosenSlug === resolvedSlug\n ? chosenSlug\n : `${chosenSlug} → ${resolvedSlug}`\n // Print to stderr directly — consola's terminal reporter is already gone\n process.stderr.write(`Server ready on ${serverUrl}, launching Claude Code (${banner})...\\n`)\n\n // Add the profile's live-catalog-gated rows through Claude Code's supported\n // `modelPicker` setting. This is independent of MCP wiring, so Standard\n // `--no-codex-mcp` still gets the same picker. The target is the per-launch\n // mirror provisioned above, never the operator's real settings.json.\n // Preserve an existing user-curated modelPicker wholesale. Its effective\n // row ids still feed the launch-global compaction minimum. Failures are\n // visible but non-fatal: explicit `-m` remains available and env setup\n // falls back to the router-declared profile rows.\n let pickerModels: string[] | undefined\n try {\n const settingsPath = nodePath.join(PATHS.CLAUDE_CONFIG_DIR, \"settings.json\")\n const picker = await injectModelPickerSettingsFile(settingsPath, launchProfileId)\n pickerModels = picker.models\n if (picker.reason === \"user-set\") {\n consola.info(\n \"Preserving the user-configured modelPicker for this launch; router-curated rows were not merged.\",\n )\n }\n } catch (err) {\n consola.warn(\n `Model-picker settings injection skipped: ${\n err instanceof Error ? err.message : String(err)\n }. Use an explicit -m model if the curated rows are unavailable.`,\n )\n }\n const envVars = getClaudeCodeEnvVars(\n serverUrl,\n chosenSlug,\n launchProfileId,\n pickerModels,\n )\n\n // Forward unrecognized flags (e.g. --print / --output-format / --resume)\n // to the spawned Claude Code child. citty is non-strict, so those land in\n // the parsed `args` object with their values swallowed rather than in\n // `args._`; walking rawArgs and dropping only github-router's OWN flags\n // makes `github-router claude -m <model> --print \"…\"` work headless\n // without requiring the `--` separator. See collectChildPassthroughArgs.\n let extraArgs = collectChildPassthroughArgs(rawArgs, claudeArgs)\n if (launchProfileId === \"fast\") {\n // Claude Code renders/persists Advisor identity from its own session\n // setting, independently of the proxy's nested Advisor dispatch. Pin both\n // layers to the same fixed model and remove every caller-supplied value so\n // a mirrored `advisorModel` or passthrough flag cannot make the UI lie.\n extraArgs = withFixedFastAdvisorArg(\n extraArgs,\n fastAdvisorClientEnabled(process.env),\n )\n }\n\n // LLM toolbelt: materialize curated CLI tools (rg/fd/jq/sd/sg/yq)\n // into the router bin dir prepended to the agent's PATH (the prepend\n // itself is done in getClaudeCodeEnvVars). Materialization runs in\n // the BACKGROUND so it never delays launch; the awareness one-liner\n // lists EVERY curated tool reachable this launch (system installs +\n // the toolbelt bin), appended to the mirrored CLAUDE.md so the main\n // agent AND descendants know which fast tools to prefer. Best-effort.\n if (toolbeltEnabled()) {\n void provisionToolbelt().catch((err) =>\n consola.debug(\"Toolbelt provisioning failed:\", err),\n )\n const toolbeltLine = buildToolbeltAwareness(availableToolCommands())\n if (toolbeltLine) {\n try {\n await appendToolbeltAwarenessToMirroredClaudeMd(toolbeltLine)\n } catch (err) {\n consola.warn(\n `Toolbelt CLAUDE.md append failed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n }\n }\n\n // Best-effort ColBERT semantic-search provision + background index of\n // the launch cwd (if a git repo). ON by default; never blocks launch,\n // never throws. Opt out with GH_ROUTER_DISABLE_SEMANTIC_SEARCH=1.\n void provisionAndIndexColbert()\n\n // Surface a terminally-failed semantic index to the HUMAN. Without this\n // the only signals are a `notice` the model reads and a log line, so a\n // degraded index can (and did) go unnoticed for weeks. Fire-and-forget:\n // lexical search still works, so this must never delay or fail a launch.\n void colbertDegradedWarning(undefined, { logsToFile: true })\n .then((warning) => {\n if (warning) process.stderr.write(`${warning}\\n`)\n })\n .catch(() => {})\n\n // Best-effort, bounded launch warm-up: ready one tree-sitter worker.\n // Opt out with GH_ROUTER_DISABLE_TS_POOL_WARMUP=1.\n void warmTreeSitterPool()\n\n // Best-effort: keep the machine awake while the proxy/Claude Code\n // session runs (win32 default-on; opt out GH_ROUTER_DISABLE_KEEP_AWAKE=1).\n // Released via stopKeepAwake() in the shutdown chain below AND via the\n // module's own self-registered SIGINT/SIGTERM/exit reaper.\n startKeepAwake()\n\n // Best-effort: materialize the browser extension + bridge into the\n // stable app-dir and stamp the running version, so a one-time \"Load\n // unpacked\" survives npx/bunx upgrades. Gated on --browse; never\n // blocks launch, never throws.\n if (browserToolsEnabled()) {\n void provisionBrowserAssets().catch((err) =>\n consola.debug(\"Browser extension provisioning failed:\", err),\n )\n }\n\n // Peer-MCP wiring. Default-on. When enabled:\n // 1. Decide between HTTP backend (always works, read-only personas)\n // and the `--codex-cli` stdio backend (requires codex 0.129+,\n // adds the implementer persona).\n // 2. Resolve the profile's third-lab peer from the live Copilot catalog\n // (standard prefers Gemini Pro; max uses Grok/high then Gemini Flash/high).\n // 3. Generate a per-launch nonce, write the MCP config tempfile\n // under PATHS.CLAUDE_RUNTIME_DIR with mode 0o600, AND write\n // one .md subagent file per peer agent into ~/.claude/agents/\n // (Phase 2.5 — `--agents` JSON does NOT populate Claude Code's\n // Task subagent_type enum on v2.1.138; .md files in the canonical\n // agents dir do).\n // 4. Inject `--mcp-config <path>` into the spawned Claude Code's\n // argv. Add `--strict-mcp-config` if the user explicitly opts\n // out of their existing MCP servers. The `--agents` JSON path\n // is intentionally NOT passed: the .md registration in the\n // canonical agents dir is the authoritative surface.\n // 5. Plumb `cleanup()` into launchChild's onShutdown so tempfiles\n // are unlinked on signal exit.\n //\n // The per-launch CLAUDE_CONFIG_DIR mirror is ALWAYS cleaned up on\n // shutdown (regardless of codex-mcp), since `ensureClaudeConfigMirror`\n // above always provisioned it. We chain the peer-MCP cleanup\n // (if any) ahead of the mirror removal so files inside the mirror\n // get unlinked first via known paths; the recursive `fs.rm` is\n // belt-and-braces for everything else.\n const baseShutdown = async (): Promise<void> => {\n await stopKeepAwake()\n await removeOwnClaudeConfigMirror()\n }\n let onShutdown: () => Promise<void> = baseShutdown\n // Captured inside the codex-mcp block (when built) so the always-on\n // operating-defaults injection below can ride the peer-awareness snippet\n // along in the SAME --append-system-prompt arg. Undefined when codex-mcp is\n // off (then only the operating-defaults directive is injected).\n let peerAwarenessSnippet: string | undefined\n let peerAwarenessSummary: string | undefined\n let operatingGroupKeys: Partial<Record<McpGroup, string>> = {}\n let fastWiringComplete = launchProfileId !== \"fast\"\n const browseAgentAvailable = browseAgentEnabled()\n const directBrowserAvailable = browserToolsEnabled()\n const artifactAvailable = artifactToolsEnabled()\n const resolvedMaxReviewerModel = launchProfileId === \"max\"\n ? resolveMaxReviewerModel()\n : undefined\n // Three of them are dropped rather than downgraded when their chain misses,\n // and a prompt naming a dropped agent sends the lead at something absent\n // from the Task `subagent_type` enum.\n // Restricted profiles use exact, catalog-validated role resolvers rather\n // than the standard fallback chains. The launch prerequisite checks above\n // guarantee every mandatory Fast role resolves; Max reviewer alone has the\n // explicit Grok/high -> Luna 1M/max fallback chosen once per launch.\n const nativeAgentModels: Partial<Record<NativeAgentName, string | undefined>> =\n launchProfileId === \"fast\"\n ? {\n Explore: fastScoutModel(),\n Plan: fastPlanModel(),\n \"general-purpose\": fastGeneralPurposeModel(),\n implementer: fastImplementerModel(),\n reviewer: fastReviewerModel(),\n }\n : launchProfileId === \"max\"\n ? {\n Explore: MAX_PROFILE_MODELS.luna,\n Plan: MAX_PROFILE_MODELS.sol,\n \"general-purpose\": MAX_PROFILE_MODELS.luna,\n implementer: MAX_PROFILE_MODELS.gemini,\n reviewer: resolvedMaxReviewerModel,\n brainstorm: maxGrokModel() ?? maxGeminiModel() ?? MAX_PROFILE_MODELS.grok,\n }\n : {\n implementer: nativeSubagentModel(),\n \"implementer-fast\": implementerFastModel(),\n reviewer: reviewerModel(),\n \"reviewer-fast\": reviewerFastModel(),\n brainstorm: brainstormModel(),\n scout: scoutModel(),\n scribe: scribeModel(),\n \"general-purpose-fast\": generalPurposeFastModel(),\n }\n const nativeAvailability: NativeAgentAvailability = {\n scoutAvailable:\n (launchProfileId === \"fast\" ? nativeAgentModels.Explore : nativeAgentModels.scout)\n != null,\n implementerFastAvailable: nativeAgentModels[\"implementer-fast\"] != null,\n reviewerFastAvailable: nativeAgentModels[\"reviewer-fast\"] != null,\n generalPurposeFastAvailable: nativeAgentModels[\"general-purpose-fast\"] != null,\n // Read from the FINAL `chosenSlug`, after the fallback walk above may have\n // reassigned it, so the prose describes the lead this session actually\n // got rather than the one it asked for.\n budgetLead: isBudgetClaudeLead(chosenSlug),\n // Hard roster RESTRICTION (not a catalog-availability signal) — see\n // `NativeAgentAvailability.profile`'s doc. The fast branch of\n // `buildOperatingDefaultsDirective` / `buildPeerAwarenessSnippet` /\n // `buildPeerAwarenessSummary` ignores every other flag above and\n // renders a short, self-contained fast-profile surface instead.\n profile: launchProfileId,\n }\n // Resolve before any settings/runtime file can persist a self-command. The\n // launcher publication must finish before those writes, never race them.\n const selfInvocation = await resolveSelfInvocation()\n // Surface a fallback to the HUMAN. `enableFileLogging()` has already run by\n // here, so a consola.warn would land in the error log where nobody looks —\n // same reasoning (and same shape) as the colbert degraded warning above.\n {\n const warning = hookLauncherDegradedWarning(selfInvocation)\n if (warning) process.stderr.write(`${warning}\\n`)\n }\n if (codexMcpEnabled) {\n try {\n const requestedCli =\n ((args as Record<string, unknown>)[\"codex-cli\"] as boolean | undefined) ?? false\n const isFastProfile = launchProfileId === \"fast\"\n const isMaxProfile = launchProfileId === \"max\"\n if (isFastProfile && requestedCli) {\n process.stderr.write(\n \"Fast profile uses its fixed HTTP MCP surface; ignoring --codex-cli.\\n\",\n )\n }\n const backend = isFastProfile || isMaxProfile\n ? \"http\"\n : resolveCodexCliBackend({\n requested: requestedCli,\n codexInfo: requestedCli ? getCodexVersion() : null,\n })\n const geminiModelsAvailable = isMaxProfile\n ? maxGeminiModel() !== undefined\n : geminiAvailable()\n if (!geminiModelsAvailable) {\n consola.info(\n isMaxProfile\n ? \"Neither Grok 4.6/high nor Gemini 3.8 Flash 1M/high is usable; max third-lab personas and stand_in will not be registered.\"\n : \"gemini-3.1-pro-preview not found in your Copilot model catalog; gemini-critic persona will not be registered.\",\n )\n }\n\n // Which scoped MCP servers to register. `peers` + `search` are\n // always on; `workers` / `decide` / `browser` only when their gate\n // passes at launch (avoids registering a server whose tools would\n // all be filtered out of tools/list). Resolve each group's\n // `.claude.json` config key ONCE (bare, or `gh-router-<group>` on\n // collision) and thread it into every channel — the mcpServers\n // entries, the persona .md routing strings, and the awareness\n // snippet — so a user-side `browser`/`search` MCP never silently\n // hijacks or drops one of ours.\n //\n // `fastDescriptor.allowedGroups` (defined only for the fast profile)\n // is a HARD deny applied to the base/catalog-gated groups only —\n // `workers`/`orchestrate` are dropped for fast regardless of\n // `workerToolsEnabled()`'s own verdict, per \"no environment flag or\n // catalog gate may re-enable workers or orchestrate in a fast\n // session\". The independently opted-in groups (`decide`/`browser`/\n // `fleet`/`first-mate`) are appended AFTER the filter and stay under\n // their own predicates regardless of profile, per plan section 6.\n const fastDescriptor = profileDescriptor(launchProfileId)\n const baseGroups: Array<McpGroup> = isFastProfile || isMaxProfile\n ? [\"peers\", \"search\"]\n : [\"peers\", \"search\", \"orchestrate\"]\n if (workerToolsEnabled() && !isFastProfile && !isMaxProfile) baseGroups.push(\"workers\")\n if ((isFastProfile || isMaxProfile) && browseAgentAvailable) baseGroups.push(\"workers\")\n const enabledGroups: Array<McpGroup> = fastDescriptor.allowedGroups\n ? baseGroups.filter((g) => fastDescriptor.allowedGroups!.has(g))\n : baseGroups\n if (!isFastProfile && !isMaxProfile && standInToolEnabled()) enabledGroups.push(\"decide\")\n if (\n isMaxProfile\n && maxOpusModel() !== undefined\n && standInToolEnabled({ maxProfile: true })\n ) {\n enabledGroups.push(\"decide\")\n }\n if (directBrowserAvailable && (!fastDescriptor.allowedGroups || fastDescriptor.allowedGroups.has(\"browser\"))) {\n enabledGroups.push(\"browser\")\n }\n if (!isFastProfile && !isMaxProfile && fleetToolsEnabled()) enabledGroups.push(\"fleet\")\n if (!isFastProfile && !isMaxProfile && agentToolsEnabled()) enabledGroups.push(\"first-mate\")\n if (isMaxProfile && fleetToolsEnabled()) enabledGroups.push(\"fleet\")\n if (isMaxProfile && agentToolsEnabled()) enabledGroups.push(\"first-mate\")\n const { keys: groupKeys, skipped: skippedGroups } =\n await resolveGroupKeysFromMirror(enabledGroups)\n operatingGroupKeys = groupKeys\n\n // Fast profile: hard-restrict the emitted native roster + persona\n // set + coordinator, and pin the three fast natives' reasoning\n // effort (see `mcp-capabilities.ts`'s `FAST_*_EFFORT` constants).\n // `fastDescriptor.personaAllowlist` is toolNameHttp-keyed (the MCP\n // wire currency); `agentNamesForToolAllowlist` translates it to the\n // agentName-keyed allowlist `writePeerMcpRuntimeFiles` consumes.\n // Worker dispatcher subagents are ALSO hard-denied for fast — force\n // `workerToolsAvailable: false` regardless of `workerToolsEnabled()`\n // so no worker-* .md (and no injected worker/orchestration skill or\n // guard, both gated on this same flag below) survives the profile\n // restriction even if the catalog gate would otherwise pass.\n if (\n isFastProfile\n && (fastOracleModel() == null || fastAdvisorModel() == null || nativeAgentModels.implementer == null)\n ) {\n throw new Error(\"fast profile prerequisite drift: exact Oracle, Advisor, or implementer model no longer resolves\")\n }\n const runtime = await writePeerMcpRuntimeFiles(serverUrl, {\n codexCli: backend === \"cli\",\n selfInvocation,\n geminiAvailable: geminiModelsAvailable,\n geminiModel: isMaxProfile\n ? maxGeminiModel()\n : resolveGeminiReviewModel(),\n groupKeys,\n workerToolsAvailable: !isFastProfile && !isMaxProfile && workerToolsEnabled(),\n browseAvailable: browseAgentAvailable,\n nativeSubagentModel: nativeAgentModels.implementer,\n reviewerModel: nativeAgentModels.reviewer,\n reviewerFastModel: nativeAgentModels[\"reviewer-fast\"],\n brainstormModel: nativeAgentModels.brainstorm,\n scoutModel:\n isFastProfile ? nativeAgentModels.Explore : nativeAgentModels.scout,\n scribeModel: nativeAgentModels.scribe,\n implementerFastModel: nativeAgentModels[\"implementer-fast\"],\n generalPurposeFastModel: nativeAgentModels[\"general-purpose-fast\"],\n nativeRoster: fastDescriptor.nativeRoster,\n personaAllowlist: isFastProfile\n ? undefined\n : fastDescriptor.personaAllowlist\n ? agentNamesForToolAllowlist(fastDescriptor.personaAllowlist)\n : undefined,\n includeCoordinator: fastDescriptor.hasCoordinator,\n ...(isFastProfile\n ? {\n fastProfile: true,\n fastExploreModel: nativeAgentModels.Explore,\n fastPlanModel: nativeAgentModels.Plan,\n fastGeneralPurposeModel: nativeAgentModels[\"general-purpose\"],\n fastImplementerModel: nativeAgentModels.implementer,\n fastReviewerModel: nativeAgentModels.reviewer,\n }\n : isMaxProfile\n ? {\n maxProfile: true,\n workerToolsAvailable: false,\n browseAvailable: browseAgentAvailable,\n maxExploreModel: MAX_PROFILE_MODELS.luna,\n maxPlanModel: MAX_PROFILE_MODELS.sol,\n maxGeneralPurposeModel: MAX_PROFILE_MODELS.luna,\n maxImplementerModel: MAX_PROFILE_MODELS.gemini,\n maxReviewerModel: resolvedMaxReviewerModel,\n maxReviewerEffort: resolvedMaxReviewerModel === MAX_PROFILE_MODELS.luna ? \"max\" : \"high\",\n maxBrainstormModel: maxGrokModel() ?? maxGeminiModel() ?? MAX_PROFILE_MODELS.grok,\n maxGeminiModel: maxGeminiModel(),\n maxGrokModel: maxGrokModel(),\n maxPeerModels: {\n sol: MAX_PROFILE_MODELS.sol,\n luna: MAX_PROFILE_MODELS.luna,\n opus: maxOpusModel(),\n gemini: maxGeminiModel(),\n grok: maxGrokModel(),\n },\n }\n : {}),\n })\n if (isFastProfile || isMaxProfile) fastRuntimeCleanup = runtime.cleanup\n // Keyed launch registry entry for this session: the `/mcp` nonce\n // (already minted by `writePeerMcpRuntimeFiles`) plus a SEPARATE\n // `/v1/messages` identity-preflight secret, scoped to this launch's\n // profile. Replaces the old `state.peerMcpNonce = runtime.nonce`\n // scalar assignment — a bare scalar couldn't express \"which\n // profile authenticated this request\", so a concurrent fast +\n // standard launch (or a reconnect) had no way to keep their\n // identities from crossing. See `src/lib/launch-registry.ts`.\n const launchSecret = randomBytes(32).toString(\"hex\")\n const launchEntry = registerLaunch({\n profileId: launchProfileId,\n nonce: runtime.nonce,\n secret: launchSecret,\n allowedGroups: fastDescriptor.allowedGroups,\n allowedPersonas: fastDescriptor.personaAllowlist,\n })\n if (isFastProfile || isMaxProfile) fastLaunchId = launchEntry.launchId\n\n // Delivered via `ANTHROPIC_CUSTOM_HEADERS` (an Anthropic SDK env var\n // Claude Code already forwards on every `/v1/messages` request) so\n // the identity preflight in `routes/messages/handler.ts` can bind\n // this launch's profile to its main-loop traffic, not just `/mcp`.\n // Merge rather than overwrite: `getClaudeCodeEnvVars` doesn't set\n // this key today, but a future caller-supplied value must not lose\n // our security header, and ours must not clobber theirs either.\n envVars.ANTHROPIC_CUSTOM_HEADERS = envVars.ANTHROPIC_CUSTOM_HEADERS\n ? `${envVars.ANTHROPIC_CUSTOM_HEADERS}\\n${LAUNCH_SECRET_HEADER}: ${launchSecret}`\n : `${LAUNCH_SECRET_HEADER}: ${launchSecret}`\n // Reach-back channel for the advisory-review hooks (hook V2): the\n // detached Stop reviewer and the UserPromptSubmit hook run as separate\n // processes with no in-proc state, so they call the proxy over loopback\n // HTTP using this URL + the per-launch nonce (the same nonce the /mcp\n // handler validates). Set on the spawned child's env so the hooks — and\n // the detached reviewer they spawn — inherit it.\n envVars.GH_ROUTER_HOOK_MCP_URL = serverUrl\n envVars.GH_ROUTER_HOOK_NONCE = runtime.nonce\n onShutdown = (isFastProfile || isMaxProfile)\n ? async (): Promise<void> => {\n try {\n unregisterLaunch(launchEntry.launchId)\n } finally {\n try {\n await runtime.cleanup()\n } finally {\n resetFastRuntimeOwnership()\n await baseShutdown()\n }\n }\n }\n : async (): Promise<void> => {\n unregisterLaunch(launchEntry.launchId)\n await runtime.cleanup()\n await baseShutdown()\n }\n\n // Standard-profile subagent MCP visibility: inject `gh-router-peers` (and the\n // `codex-cli` stdio entry when enabled) into the mirrored\n // `<CLAUDE_CONFIG_DIR>/.claude.json` so subagents — Agent-tool\n // subagents, forks, agent-teams subprocesses — discover the peer\n // MCP from persistent (user-scope) config rather than the parent's\n // ephemeral --mcp-config CLI flag. Same nonce as runtime files\n // (the proxy validates Authorization against the launch nonce\n // regardless of which channel the request came through).\n //\n // On collision with a user-side entry of the same name, this\n // returns ok:false; we then keep --mcp-config as the fallback so\n // at least the parent session retains the peer tools (subagents\n // remain blind in that case, by design — explicit branch, not\n // silent precedence).\n // Fast is deliberately different: the parent receives its enabled\n // groups through --mcp-config, while each native gets only its inline\n // role-scoped servers (`Plan` alone receives peers/Oracle; read/search\n // roles receive search; worker-browse receives workers). Do NOT persist\n // proxy MCPs into the shared mirror for this profile: execution roles\n // with inherited tools would otherwise receive Oracle or Artifact tools.\n let subagentVisibility: string\n let injected: Awaited<ReturnType<typeof injectPeerMcpIntoMirror>> | undefined\n if (isFastProfile) {\n extraArgs.push(\"--mcp-config\", runtime.mcpConfigPath)\n if ((args as Record<string, unknown>)[\"codex-mcp-only\"] === true) {\n extraArgs.push(\"--strict-mcp-config\")\n }\n subagentVisibility =\n \"role-scoped (lead via --mcp-config; subagents via inline mcpServers)\"\n } else {\n injected = await injectPeerMcpIntoMirror(serverUrl, {\n codexCli: backend === \"cli\",\n selfInvocation,\n geminiAvailable: geminiModelsAvailable,\n groupKeys,\n nonce: runtime.nonce,\n })\n\n // Channel selection: prefer the mirror (subagent-visible) when\n // injection succeeded. Only fall back to --mcp-config when\n // injection refused due to a user-side collision. Pushing BOTH\n // would register the same server name twice (mirror + CLI flag),\n // which is ambiguous across Claude Code versions.\n if (!injected.ok) {\n extraArgs.push(\"--mcp-config\", runtime.mcpConfigPath)\n if ((args as Record<string, unknown>)[\"codex-mcp-only\"] === true) {\n extraArgs.push(\"--strict-mcp-config\")\n }\n } else if ((args as Record<string, unknown>)[\"codex-mcp-only\"] === true) {\n // User asked for strict-MCP-only but the mirror inject path\n // can't enforce that (other user-scope MCPs already in the\n // mirror's snapshot are visible). Warn so the flag's mismatch\n // with the new behavior is obvious.\n consola.warn(\n \"--codex-mcp-only has no effect when peer MCP is wired via the \"\n + \"mirrored .claude.json (the user's existing user-scope MCPs in \"\n + \"the snapshot are still visible). Pass --no-codex-mcp to skip \"\n + \"peer-MCP wiring entirely.\",\n )\n }\n subagentVisibility = injected.ok\n ? `subagent-visible (mirrored mcpServers: [${injected.serversAdded.join(\", \")}])`\n : `subagent-INVISIBLE (collision on user-side mcpServers: [${injected.conflictingServers.join(\", \")}]; parent-only via --mcp-config)`\n }\n\n if (isFastProfile) {\n let fastGuardInstalled = false\n try {\n const settingsPath = nodePath.join(PATHS.CLAUDE_CONFIG_DIR, \"settings.json\")\n const guardCommand = buildFastDispatchGuardHookCommand(selfInvocation, {\n allowBrowse: browseAgentAvailable,\n allowedTargets: [\n ...(fastDescriptor.nativeRoster ?? []),\n ...(browseAgentAvailable ? [\"worker-browse\"] : []),\n ],\n })\n await injectStopHookIntoSettingsFile(\n settingsPath,\n guardCommand,\n \"PreToolUse\",\n 10,\n FAST_DISPATCH_TOOL_MATCHER,\n )\n fastGuardInstalled = true\n } catch (err) {\n consola.error(`Could not register the fast native dispatch ACL hook: ${String(err)}`)\n }\n assertFastDispatchGuardInstalled(true, fastGuardInstalled)\n fastWiringComplete = true\n } else if (isMaxProfile) {\n let maxGuardInstalled = false\n try {\n const settingsPath = nodePath.join(PATHS.CLAUDE_CONFIG_DIR, \"settings.json\")\n const guardCommand = buildMaxDispatchGuardHookCommand(selfInvocation, {\n reviewerModel: resolvedMaxReviewerModel,\n reviewerEffort: resolvedMaxReviewerModel === MAX_PROFILE_MODELS.luna ? \"max\" : \"high\",\n })\n await injectStopHookIntoSettingsFile(\n settingsPath,\n guardCommand,\n \"PreToolUse\",\n 10,\n MAX_DISPATCH_TOOL_MATCHER,\n )\n maxGuardInstalled = true\n } catch (err) {\n consola.error(`Could not register the max native dispatch ACL hook: ${String(err)}`)\n }\n assertMaxDispatchGuardInstalled(true, maxGuardInstalled)\n fastWiringComplete = true\n }\n\n const personaNames = runtime.personas.map((p) => p.agentName).join(\", \")\n const skippedNote =\n skippedGroups.length > 0\n ? ` WARNING: groups [${skippedGroups.join(\", \")}] skipped — both the bare and \\`gh-router-<group>\\` keys collide with your own mcpServers; those tools are unavailable this session (rename the user-side server to re-enable).`\n : \"\"\n process.stderr.write(\n `Peer MCP wired (backend=${backend}, personas=[${personaNames}], `\n + `subagent .md files=${runtime.agentMdPaths.length}, ${subagentVisibility}).${skippedNote}\\n`,\n )\n\n // ── Floor-raising agent surface (docs/floor-raising-agent-surface.md) ──\n // NOTE (intentional coupling, gemini integration review): this block is\n // nested in `if (codexMcpEnabled)` — the github-router \"enhancement\n // layer\" master switch — alongside the MCP server injection above. The\n // skills REQUIRE that injection (they call mcp__workers__* /\n // mcp__orchestrate__* / mcp__search__* tools), so coupling them here is\n // correct. The Stop-gate is MCP-independent and could live outside;\n // keeping it here means `--no-codex-mcp` opts out of the whole layer\n // (consistent: that flag also hides --trust-gate, so the gate was never\n // enabled in such a session anyway). Decoupling the Stop-gate + moving\n // the per-prompt reset out is a clean follow-up.\n // When the worker/orchestrate backend is available, materialize the\n // injected skills into the mirror and register the front-end\n // UserPromptSubmit hook (per-prompt Stop-gate budget reset + advisory\n // goal steer). gh-first-mate is additionally gated on the first-mate MCP\n // server so the slash command does not advertise an unavailable tool.\n // The hooks scope themselves to the top-level session via the payload's\n // agent_type, so subagents/teammates are untouched.\n const sessionCwd = process.cwd()\n // Worker/orchestration skills and their prompt-submit steering belong\n // only to the standard profile. Fast and max intentionally omit the\n // slash commands even when the worker catalog gate is otherwise open.\n const workerSkillsActive = workerToolsEnabled() && launchProfileId === \"standard\"\n const skillsToWrite = injectedSkillsForLaunch({\n profileId: launchProfileId,\n workerSkillsActive,\n firstMateEnabled: agentToolsEnabled(),\n })\n let skillsWritten = 0\n for (const s of skillsToWrite) {\n const r = await writeInjectedSkill(s.name, s.md).catch(() => ({ written: false }))\n if (r.written) skillsWritten++\n }\n if (workerSkillsActive) {\n try {\n const settingsPath = nodePath.join(PATHS.CLAUDE_CONFIG_DIR, \"settings.json\")\n const cmd = buildPromptSubmitHookCommand(selfInvocation)\n // Raise the host hook timeout to 45s (default 30s): the V2 path may\n // make one gpt-5.6-sol scope call + a parallel code search. The hook's\n // own enrichment is bounded well under this (≈22s) and fails open,\n // so 45s is headroom, not a tax the user routinely pays.\n await injectStopHookIntoSettingsFile(settingsPath, cmd, \"UserPromptSubmit\", 45)\n } catch (err) {\n consola.warn(`Could not register the UserPromptSubmit hook: ${String(err)}`)\n }\n }\n // Auto-approve github-router's own injected MCP servers so their tools\n // run WITHOUT a permission prompt in every mode — including plan mode,\n // where the research tools (search / peers / workers-explore / stand_in /\n // orchestrate) are exactly what the model reaches for. MCP tools aren't\n // subject to plan mode's file-edit/shell-write restriction, so a bare\n // `mcp__<server>` allow rule (on the RESOLVED keys) auto-runs them there\n // too. deny/ask and the user's own allow entries are preserved.\n // Auto-approve github-router's own injected MCP servers PLUS the native\n // read-only research tools (WebSearch/WebFetch) so they run WITHOUT a\n // permission prompt in every mode — including plan mode, where that\n // research surface is exactly what the model reaches for. MCP tools and\n // read-only natives aren't subject to plan mode's file-edit/shell-write\n // restriction, so an allow rule auto-runs them there too. deny/ask and\n // the user's own allow entries are preserved.\n //\n // HOISTED OUT of the `workerSkillsActive` block (plan section 6): this\n // must run for EVERY profile, including fast, so the groups that ARE\n // still registered there (peers/search) stay auto-approved even though\n // the worker-only skills/hook/guard above and below are skipped.\n try {\n const settingsPath = nodePath.join(PATHS.CLAUDE_CONFIG_DIR, \"settings.json\")\n // Authoritative list of the servers we actually injected — on the\n // mirror path that's `injected.serversAdded` (includes the `codex-cli`\n // stdio server, not just the HTTP groups); on the collision fallback,\n // reconstruct it from the resolved group keys + codex-cli.\n const injectedServerKeys = injected?.ok\n ? injected.serversAdded\n : [\n ...Object.values(groupKeys).filter((k): k is string => Boolean(k)),\n ...(backend === \"cli\" ? [\"codex-cli\"] : []),\n ]\n const res = await injectAllowRules(settingsPath, planModeAllowRules(injectedServerKeys))\n if (res.added.length) {\n consola.debug(`Auto-approved for plan mode: ${res.added.join(\", \")}`)\n }\n } catch (err) {\n consola.warn(`Could not auto-approve injected tools: ${String(err)}`)\n }\n const workerGuardActive = workerSkillsActive || ((isFastProfile || isMaxProfile) && browseAgentAvailable)\n if (workerGuardActive) {\n // Workers non-blocking guard: a PreToolUse hook scoped (matcher) to the\n // active worker tools that DENIES a raw `mcp__<workersKey>__<mode>` call\n // from the main agent (redirecting it to the `worker-<mode>` background\n // dispatcher) and ALLOWS it only from that dispatcher subagent. The\n // resolved workersKey + active modes are baked into the command\n // (dedup-distinct) and the matcher. Local + instant, so a short 10s\n // timeout is ample.\n //\n // GATED ON `injected.ok`: the guard only makes sense when subagents can\n // SEE the workers MCP (mirror injection succeeded). On the collision\n // fallback (parent-only --mcp-config, subagents blind), a `worker-*`\n // dispatcher could not reach the worker tool — registering the guard\n // then would deny the main agent AND leave it no working dispatcher, a\n // fully-broken state. So when injection failed we skip the guard and\n // leave raw (blocking) workers usable on the main thread.\n //\n // HYBRID opt-out (`GH_ROUTER_DISABLE_WORKER_GUARD=1`): keeps the\n // non-blocking guarantee ON by default, but lets an operator restore the\n // raw `mcp__workers__*` escape hatch on demand (e.g. for guaranteed\n // structured-arg fidelity, or when a blocking call is acceptable) — so\n // the worker-* agents COMPLEMENT rather than hard-replace the raw tools.\n const dispatcherCanReachWorkers = isFastProfile || injected?.ok === true\n if (!dispatcherCanReachWorkers) {\n consola.warn(\n \"Workers non-blocking guard NOT registered: subagent MCP injection \"\n + \"fell back to parent-only (--mcp-config), so worker-* dispatchers \"\n + \"cannot reach the workers server. Raw (blocking) worker tools remain \"\n + \"usable on the main thread this session.\",\n )\n } else if (process.env.GH_ROUTER_DISABLE_WORKER_GUARD === \"1\") {\n consola.info(\n \"Workers non-blocking guard disabled via GH_ROUTER_DISABLE_WORKER_GUARD=1 \"\n + \"— raw mcp__workers__* is callable on the main thread (blocking); the \"\n + \"worker-* background agents remain the steered, non-blocking default.\",\n )\n } else {\n try {\n const settingsPath = nodePath.join(PATHS.CLAUDE_CONFIG_DIR, \"settings.json\")\n const workersKey = workersKeyOf(groupKeys)\n const modes = isFastProfile || isMaxProfile\n ? ([\"browse\"] as const)\n : activeDispatchModes({ browse: browseAgentAvailable })\n const cmd = buildWorkerGuardHookCommand(\n selfInvocation,\n workersKey,\n modes,\n )\n const matcher = guardToolMatcher(workersKey, modes)\n await injectStopHookIntoSettingsFile(settingsPath, cmd, \"PreToolUse\", 10, matcher)\n } catch (err) {\n consola.warn(`Could not register the workers PreToolUse guard hook: ${String(err)}`)\n }\n }\n }\n if (skillsWritten > 0) {\n const skillNames = skillsToWrite.map((s) => `/${s.name}`).join(\", \")\n process.stderr.write(\n `Injected skills (${skillsWritten}/${skillsToWrite.length}): ${skillNames}.\\n`,\n )\n }\n\n // In operator/`--agents` mode, keep local worker/orchestrate MCP tools\n // subagent-only for the MAIN operator. File-authoring tools and Bash stay\n // available; steering to cloud-agent delegation lives in the banner and\n // /gh-first-mate skill. Fail-closed only for this reduced PreToolUse guard.\n if (agentToolsEnabled()) {\n let shapingInstalled = false\n try {\n const settingsPath = nodePath.join(PATHS.CLAUDE_CONFIG_DIR, \"settings.json\")\n const guardCmd = buildFirstMateGuardHookCommand(selfInvocation)\n await injectStopHookIntoSettingsFile(\n settingsPath,\n guardCmd,\n \"PreToolUse\",\n undefined,\n FIRST_MATE_GUARD_MATCHER,\n )\n shapingInstalled = true\n } catch (err) {\n consola.error(\n `Could not register the operator worker/orchestrate guard hook: ${String(err)}`,\n )\n }\n assertShapingInstalled(true, shapingInstalled)\n\n // Surface the scaffold allowlist AT STARTUP rather than only as a\n // refusal deep inside a tool call. `scaffold_repo` creates branches,\n // commits files and opens PRs, so it is deny-by-default — but a user\n // upgrading into that gate would otherwise discover it as an opaque\n // mid-mission failure naming an env var they have never seen. One\n // line at launch turns a surprise into a setting.\n if (!process.env.GH_ROUTER_FM_SCAFFOLD_REPOS?.trim()) {\n consola.info(\n \"first-mate: scaffold_repo is disabled (it writes to real repositories). \"\n + \"Set GH_ROUTER_FM_SCAFFOLD_REPOS to a comma-separated list of owner/name \"\n + \"entries, or owner/* for a whole org, to enable it.\",\n )\n }\n }\n\n // ai-or-die session binding. When launched inside an ai-or-die Terminal\n // tab, ai-or-die sets AIORDIE_CLAUDE_BIND to a per-tab sidecar path.\n // Register a SessionStart/SessionEnd hook that records the active claude\n // session id + transcript path to that sidecar on every startup / resume\n // / clear / compact, so ai-or-die can bind the tab's sticky-note\n // summariser to the exact transcript (surviving /resume, /clear and\n // exit→relaunch). The path is baked into the hook command (not env), and\n // AIORDIE_CLAUDE_BIND is stripped from the child's env (sanitizeParentEnv),\n // so a nested `github-router claude` can't hijack the parent tab; the hook\n // itself also skips subagent/teammate payloads (agent_id/agent_type).\n const aiordieSidecar = (process.env.AIORDIE_CLAUDE_BIND ?? \"\").trim()\n // The path is baked into the hook command string (double-quoted, like\n // buildStopHookCommand). It is app-controlled (ai-or-die's data dir + a\n // uuid), so it never contains a double-quote; refuse defensively if it\n // somehow does rather than emit a malformed command (ai-or-die then falls\n // back to its inference path).\n if (aiordieSidecar.length > 0 && !aiordieSidecar.includes('\"')) {\n try {\n const settingsPath = nodePath.join(PATHS.CLAUDE_CONFIG_DIR, \"settings.json\")\n const command = buildSessionBindHookCommand(selfInvocation, aiordieSidecar)\n await injectStopHookIntoSettingsFile(settingsPath, command, \"SessionStart\")\n await injectStopHookIntoSettingsFile(settingsPath, command, \"SessionEnd\")\n } catch (err) {\n consola.warn(`Could not register the ai-or-die session-bind hook: ${String(err)}`)\n }\n }\n\n // Default-on plan review in the artifact panel: when inside an ai-or-die\n // tab (AIORDIE_SESSION_ID set), the artifact_* tools reach a real review\n // panel, so materialize the gh-artifact-review skill and steer the agent\n // to open plans there by default. Skill is written here (not in\n // INJECTED_SKILLS) so it only appears inside a tab; the CLAUDE.md\n // directive reaches descendants. Both best-effort.\n if (artifactAvailable) {\n const artifactReviewSkill = buildArtifactReviewSkill(groupKeys.peers)\n await writeInjectedSkill(artifactReviewSkill.name, artifactReviewSkill.md)\n .catch(() => ({ written: false }))\n try {\n await prependArtifactPanelDirectiveToMirroredClaudeMd(groupKeys.peers)\n } catch (err) {\n consola.warn(`Artifact-panel directive prepend failed: ${String(err)}`)\n }\n // Hands-off auto-open: write the artifact creds to a mode-600 mirror\n // file (AIORDIE_TOKEN is stripped from the child env, and argv leaks to\n // ps), then register a PostToolUse(ExitPlanMode) hook so the finalized\n // plan opens in the panel without the model calling artifact_open.\n try {\n await writeArtifactCredsToMirror(shouldUseInsecureTls(process.env.AIORDIE_BASE_URL ?? \"\"))\n const settingsPath = nodePath.join(PATHS.CLAUDE_CONFIG_DIR, \"settings.json\")\n const cmd = buildArtifactOpenHookCommand(selfInvocation)\n await injectStopHookIntoSettingsFile(settingsPath, cmd, \"PostToolUse\", undefined, \"ExitPlanMode\")\n } catch (err) {\n consola.warn(`Could not register the artifact auto-open hook: ${String(err)}`)\n }\n }\n\n // Advisory plan review: a SECOND PostToolUse(ExitPlanMode) hook, separate\n // from artifact auto-open. It is default-on when the hook MCP runtime is\n // wired, top-level-only at runtime, and never blocks ExitPlanMode; material\n // findings are written to the shared findings store for the next prompt.\n if (!isFastProfile && hookMcpRuntimeFromEnv(envVars) && planReviewEnabled()) {\n try {\n const settingsPath = nodePath.join(PATHS.CLAUDE_CONFIG_DIR, \"settings.json\")\n const command = buildPlanReviewHookCommand(selfInvocation)\n await injectStopHookIntoSettingsFile(settingsPath, command, \"PostToolUse\", undefined, \"ExitPlanMode\")\n } catch (err) {\n consola.warn(`Could not register the advisory plan-review hook: ${String(err)}`)\n }\n }\n\n // Structural-gate Stop hook — CONSENT-GATED per repo (default OFF; it\n // never runs an UNTRUSTED repo's scripts). `--trust-gate` records consent\n // for this repo; GH_ROUTER_ENABLE_STOP_GATE force-enables. The hook also\n // re-checks trust at runtime and scopes to the top-level session.\n if (!isFastProfile && !isMaxProfile && (args as Record<string, unknown>)[\"trust-gate\"] === true) {\n try {\n const root = await trustRepo(sessionCwd)\n process.stderr.write(\n `Structural gate trusted for this repo (${root}); it will run on launch here from now on.\\n`,\n )\n } catch (err) {\n consola.warn(`Could not record gate trust: ${String(err)}`)\n }\n }\n const gateDisabled = isFastProfile || isMaxProfile || stopGateDisabled(args as Record<string, unknown>)\n const forceEnabled = parseBoolEnv(process.env.GH_ROUTER_ENABLE_STOP_GATE) === true\n const includeTests = parseBoolEnv(process.env.GH_ROUTER_STOP_GATE_RUN_TESTS) === true\n const gateRoot = await repoRoot(sessionCwd).catch(() => sessionCwd)\n // Resolve the gate source: the deterministic parser first (the bun/TS\n // sealed fast-path OR a parsed multi-language check set), then the cached\n // model-discovered record. A cache MISS marks `discovering` (background\n // discovery arms the gate on the NEXT launch — no launch-time model\n // latency). Discovery is OPT-IN (GH_ROUTER_ENABLE_GATE_DISCOVERY=1): it\n // runs a read-only worker that reads repo files, so it stays off by\n // default; the parser covers the common ecosystems with no model at all.\n let descriptor: GateDescriptor | null = null\n let discovering = false\n if (!gateDisabled) {\n descriptor = await parseGateDescriptor(gateRoot, { includeTests }).catch(() => null)\n if (!descriptor) {\n const cached = await readDiscoveredGate(gateRoot).catch(() => null)\n if (cached) {\n descriptor = {\n kind: \"discovered\",\n checks: cached.checks,\n ecosystem: cached.ecosystem,\n workdir: gateRoot,\n evidence: cached.evidence,\n }\n // Force-enable wants a gate NOW (not a next-launch background discovery);\n // when nothing parsed/cached, it falls back to the sealed default below.\n } else if (!forceEnabled && workerToolsEnabled() && parseBoolEnv(process.env.GH_ROUTER_ENABLE_GATE_DISCOVERY) === true) {\n discovering = true\n }\n }\n }\n // Enable when forced-on, already trusted, or auto-trust-on-detection (a\n // resolved descriptor OR a kicked discovery is consent-by-launching). The\n // gate only ever runs the launched repo's own checks and is\n // baseline-isolated; opt out entirely with GH_ROUTER_DISABLE_STOP_GATE=1.\n let gateEnabled = gateDisabled ? false : await stopGateEnabledForRepo(sessionCwd).catch(() => false)\n let autoTrusted = false\n if (!gateEnabled && !gateDisabled && (descriptor || discovering)) {\n try {\n await trustRepo(sessionCwd)\n gateEnabled = true\n autoTrusted = true\n } catch (err) {\n consola.warn(`Could not auto-trust this repo for the structural gate: ${String(err)}`)\n }\n }\n // Force-enable (GH_ROUTER_ENABLE_STOP_GATE / --trust-gate) with no parsed\n // or discovered descriptor falls back to the sealed default gate, matching\n // the legacy behavior of explicit enablement (takes precedence over a\n // background discovery, which `forceEnabled` already suppressed above).\n if (gateEnabled && !descriptor && !discovering) {\n descriptor = { kind: \"sealed\", gateId: stopGateId(), workdir: gateRoot }\n }\n if (gateEnabled && descriptor) {\n const armed = descriptor\n try {\n const settingsPath = nodePath.join(PATHS.CLAUDE_CONFIG_DIR, \"settings.json\")\n const command = buildStopHookCommand(selfInvocation)\n // Arm the matching runtime resolver (env reaches the child via envVars).\n if (armed.kind === \"sealed\") envVars.GH_ROUTER_STOP_GATE_ID = armed.gateId\n else if (armed.kind === \"parsed\") envVars.GH_ROUTER_STOP_GATE_PARSED = \"1\"\n else envVars.GH_ROUTER_STOP_GATE_DISCOVERED = \"1\"\n if (includeTests) envVars.GH_ROUTER_STOP_GATE_RUN_TESTS = \"1\"\n await injectStopHookIntoSettingsFile(settingsPath, command)\n // Capture the baseline at LAUNCH (pre-mutation) for the dynamic paths,\n // so an agent-introduced failure is a regression — not silently adopted\n // as the baseline at first stop. Sealed keeps its legacy first-stop\n // baseline (unchanged). Fire-and-forget: never blocks the launch.\n if (armed.kind !== \"sealed\") {\n const checks = checksForDescriptor(armed)\n const descriptorKey = descriptorHash(armed)\n // Per-launch token isolates concurrent sessions' baselines; the child\n // reads it back to recompute the same launch-baseline key.\n const token = randomBytes(8).toString(\"hex\")\n envVars.GH_ROUTER_STOP_GATE_BASELINE_TOKEN = token\n void (async () => {\n await captureLaunchBaseline({\n checks,\n workdir: armed.workdir,\n exec: liveExec,\n descriptorKey,\n token,\n baseline: fileBaselineStore(nodePath.join(tmpdir(), \"gh-router-stopgate-baseline\")),\n })\n })().catch(() => {})\n }\n const tail =\n \"A regression or a gate-weakening diff blocks stopping until fixed (per-prompt, max 2). \"\n + \"Opt out with GH_ROUTER_DISABLE_STOP_GATE=1.\\n\"\n if (armed.kind === \"sealed\") {\n process.stderr.write(\n (autoTrusted\n ? `Structural-gate Stop hook enabled by default for this repo (gate=${armed.gateId}; runs typecheck/test/lint at stop). `\n : `Structural-gate Stop hook enabled (gate=${armed.gateId}). `) + tail,\n )\n } else {\n const ids = checksForDescriptor(armed).map((c) => c.id).join(\", \")\n const testNote = includeTests\n ? \"Full test suite ON. \"\n : \"Full test suite off by default (enable with GH_ROUTER_STOP_GATE_RUN_TESTS=1). \"\n process.stderr.write(\n `Structural-gate Stop hook armed for this ${armed.ecosystem} repo (checks: ${ids}; `\n + `from ${armed.evidence.join(\", \")}). ${testNote}${tail}`,\n )\n }\n } catch (err) {\n // Never fail the launch over the hook; surface and continue.\n consola.warn(`Could not register the structural-gate Stop hook: ${String(err)}`)\n }\n } else if (gateEnabled && discovering) {\n // Kick a background discovery; the gate arms on the next launch.\n process.stderr.write(\n \"Structural Stop-gate: no checks parsed for this repo — discovering check commands in the \"\n + \"background (arms on the next launch). Disable with GH_ROUTER_ENABLE_GATE_DISCOVERY=0.\\n\",\n )\n void (async () => {\n try {\n const disc = await discoverGateCommands(gateRoot, {\n includeTests,\n signal: AbortSignal.timeout(120_000),\n })\n if (disc) {\n const [fingerprint, sh] = await Promise.all([\n repoFingerprint(gateRoot).catch(() => \"\"),\n sourcesHash(gateRoot).catch(() => \"\"),\n ])\n await writeDiscoveredGate({\n root: gateRoot,\n fingerprint,\n sourcesHash: sh,\n discoveredAt: new Date().toISOString(),\n model: \"gemini-3.5-flash\",\n ecosystem: disc.ecosystem,\n checks: disc.checks,\n confidence: disc.confidence,\n evidence: disc.evidence,\n })\n }\n } catch {\n /* best-effort: discovery never blocks or fails the launch. */\n }\n })().catch(() => {})\n } else if (!gateDisabled && !descriptor && !discovering) {\n // The original \"silent skip\" fix: say WHY the gate is off.\n process.stderr.write(\n \"Structural Stop-gate not enabled: no checks found in this repo \"\n + \"(looked at package.json scripts / CI workflows / Makefile / Cargo.toml / go.mod / pyproject). \"\n + \"Force a sealed gate with GH_ROUTER_ENABLE_STOP_GATE=1\"\n + (workerToolsEnabled() ? \", or let a model discover them with GH_ROUTER_ENABLE_GATE_DISCOVERY=1\" : \"\")\n + \".\\n\",\n )\n }\n\n // Awareness snippet: append a short, descriptive system-prompt\n // section telling Claude *what* peer-review tools exist — Claude\n // decides *whether* to call them based on each tool's own\n // `description` (the routing layer). This is the awareness layer.\n //\n // Delivery is dual-surface, both unconditional:\n // 1. --append-system-prompt — system-turn position, strongest\n // attention weight; reaches the main agent only.\n // 2. <CLAUDE_CONFIG_DIR>/CLAUDE.md (appended) — user-turn\n // <claudeMd> wrapper; reaches Agent-tool subagents and\n // agent-teams teammates that inherit CLAUDE_CONFIG_DIR but\n // not --append-system-prompt.\n //\n // Capability gates: worker_* and stand_in mentions are gated on\n // the same predicates the /mcp tools/list uses (workerToolsEnabled\n // / standInToolEnabled), so the snippet never names a tool that\n // is missing from the live catalog.\n //\n // Previously gated by GH_ROUTER_PEER_AWARENESS (default-on).\n // The flag was dropped (per plan: it served no purpose now that\n // the snippet is default-on across both surfaces). Existing\n // `GH_ROUTER_PEER_AWARENESS=0` shell exports are silent no-ops.\n const peerSnippet = buildPeerAwarenessSnippet({\n codexCli: backend === \"cli\",\n geminiAvailable: geminiModelsAvailable,\n geminiModel: isMaxProfile\n ? maxGeminiModel()\n : resolveGeminiReviewModel(),\n workerToolsAvailable: isMaxProfile ? false : workerToolsEnabled(),\n standInAvailable: isMaxProfile\n ? (maxOpusModel() !== undefined && standInToolEnabled({ maxProfile: true }))\n : standInToolEnabled(),\n browseAvailable: browseAgentAvailable,\n browserToolsAvailable: directBrowserAvailable,\n compoundBrowseAvailable: isMaxProfile ? false : browserCompoundToolsEnabled(),\n powerBrowseAvailable: isMaxProfile ? false : state.powerBrowseEnabled,\n fleetAvailable: fleetToolsEnabled(),\n agentToolsAvailable: agentToolsEnabled(),\n artifactToolsAvailable: artifactAvailable,\n ...nativeAvailability,\n profile: launchProfileId,\n groupKeys,\n })\n // Capture the peer-awareness snippet; the always-on operating-defaults\n // injection after this block composes the single --append-system-prompt\n // (operating-defaults first, then this summary).\n peerAwarenessSnippet = peerSnippet\n peerAwarenessSummary = buildPeerAwarenessSummary({\n workerToolsAvailable: isMaxProfile ? false : workerToolsEnabled(),\n standInAvailable: isMaxProfile\n ? (maxOpusModel() !== undefined && standInToolEnabled({ maxProfile: true }))\n : standInToolEnabled(),\n browseAvailable: browseAgentAvailable,\n browserToolsAvailable: directBrowserAvailable,\n fleetAvailable: fleetToolsEnabled(),\n agentToolsAvailable: agentToolsEnabled(),\n artifactToolsAvailable: artifactAvailable,\n ...nativeAvailability,\n profile: launchProfileId,\n nativeAgentModels,\n groupKeys,\n })\n // Ordering invariant: this MUST run AFTER ensureClaudeConfigMirror()\n // has resolved (above in this same handler), so the snapshot of\n // the user's ~/.claude/CLAUDE.md is already in place before we\n // append our marker block. The helper's own mirror-only safety\n // guard rejects writes outside CLAUDE_CONFIG_DIR as defence in\n // depth. Failures warn-and-continue: this CLAUDE.md copy is now the\n // primary full-inventory surface (the system prompt carries only a\n // summary of it), so on the rare write failure the agent falls back to\n // the tool descriptions in tools/list, not a launch-blocker.\n try {\n await appendPeerAwarenessToMirroredClaudeMd(peerSnippet)\n } catch (err) {\n consola.warn(\n `Peer-awareness CLAUDE.md append failed (agent keeps tool descriptions via tools/list, loses the inventory overview): ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n // Style directive: prepend a short writing/communication style\n // directive at the TOP of the mirrored CLAUDE.md so every\n // spawned agent reads it first. Independent marker fence from\n // the peer-awareness block, so the two coexist (style at top,\n // user content in the middle, peer-awareness at the bottom).\n // Best-effort like the append above.\n try {\n await prependStyleDirectiveToMirroredClaudeMd()\n } catch (err) {\n consola.warn(\n `Style-directive CLAUDE.md prepend failed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n } catch (err) {\n if (launchProfileId === \"fast\" || launchProfileId === \"max\") {\n if (fastLaunchId) unregisterLaunch(fastLaunchId)\n await disposeFastRuntime().catch(() => {})\n await server.close(true).catch(() => {})\n await baseShutdown().catch(() => {})\n resetFastRuntimeOwnership()\n const profileLabel = launchProfileId === \"fast\" ? \"Fast\" : \"Max\"\n const message = `${profileLabel} profile wiring failed; refusing to launch an unguarded session: ${err instanceof Error ? err.message : String(err)}`\n consola.error(message)\n process.stderr.write(`${message}\\n`)\n process.exit(1)\n }\n consola.warn(\n `Peer MCP wiring failed (claude will launch without it): ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n }\n\n // Operating-defaults directive (orchestrator posture + hybrid excellence\n // lens): injected by DEFAULT, NOT gated on codex-mcp, so the posture always\n // reaches the agent even under --no-codex-mcp. Two surfaces:\n // 1. --append-system-prompt (main agent, highest salience): the single\n // such arg for the session carries a condensed digest, with a compact\n // summary of the peer-awareness inventory riding along after it.\n // 2. the mirrored CLAUDE.md TOP (main agent and descendant agents): the\n // full directive is prepended after the style directive when that ran.\n // ensureClaudeConfigMirror() ran unconditionally above, so the mirror exists\n // regardless of codex-mcp; the prepend is best-effort (warn-and-continue).\n // Peer-awareness inventory lives ONCE, in the mirrored CLAUDE.md (appended\n // above), which the main agent and descendants both read. The system prompt\n // carries only a compact summary, not the full ~1.1k-token snippet, so\n // the inventory is not duplicated in the context window on every turn. The\n // full operating-defaults directive lives in CLAUDE.md, while a condensed\n // digest keeps those defaults at top salience in --append-system-prompt.\n // If the CLAUDE.md append happened to fail, the agent still has every tool's\n // own description in tools/list (the real routing signal); it just loses this\n // higher-level overview.\n const operatingDefaultsDigest = buildOperatingDefaultsDigest({ profile: launchProfileId })\n extraArgs.push(\n \"--append-system-prompt\",\n peerAwarenessSnippet && peerAwarenessSummary\n ? `${operatingDefaultsDigest}\\n\\n${peerAwarenessSummary}`\n : operatingDefaultsDigest,\n )\n try {\n await prependOperatingDefaultsToMirroredClaudeMd(\n buildOperatingDefaultsDirective({\n ...nativeAvailability,\n fastRuntimeAvailable: fastWiringComplete,\n browseAvailable: browseAgentAvailable,\n browserToolsAvailable: directBrowserAvailable,\n artifactAvailable,\n groupKeys: operatingGroupKeys,\n peersKey: operatingGroupKeys.peers,\n }),\n )\n } catch (err) {\n consola.warn(\n `Operating-defaults CLAUDE.md prepend failed: ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n\n // Deterministic backstop for the injected no-attribution style directive:\n // write `attribution: {commit:\"\", pr:\"\"}` into the mirrored settings.json so\n // Claude Code's harness suppresses the commit/PR bylines at the source, not\n // just via the advisory CLAUDE.md prose. Presence-guarded (an existing\n // user `attribution`/`includeCoAuthoredBy` wins) and best-effort. Opt out\n // with GH_ROUTER_DISABLE_NO_ATTRIBUTION=1.\n if (process.env.GH_ROUTER_DISABLE_NO_ATTRIBUTION !== \"1\") {\n try {\n const settingsPath = nodePath.join(PATHS.CLAUDE_CONFIG_DIR, \"settings.json\")\n await injectAttributionSuppressionIntoSettingsFile(settingsPath)\n } catch (err) {\n consola.warn(\n `No-attribution settings backstop skipped: ${\n err instanceof Error ? err.message : String(err)\n }`,\n )\n }\n }\n\n launchChild(\n { kind: \"claude-code\", envVars, extraArgs, model: chosenSlug },\n server,\n { onShutdown },\n )\n },\n})\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- import { $t as warmTreeSitterPool, D as toolbeltEnabled, Jt as hasSupportedBrowserInstalled, Xt as provisionAndIndexColbert, Yt as colbertDegradedWarning, ln as DEFAULT_CODEX_MODEL, qt as provisionBrowserAssets, un as DEFAULT_CODEX_MODEL_FALLBACKS } from "./peer-mcp-personas-D4bHdjOx.js";
1
+ import { $t as warmTreeSitterPool, D as toolbeltEnabled, Jt as hasSupportedBrowserInstalled, Xt as provisionAndIndexColbert, Yt as colbertDegradedWarning, ln as DEFAULT_CODEX_MODEL, qt as provisionBrowserAssets, un as DEFAULT_CODEX_MODEL_FALLBACKS } from "./peer-mcp-personas-C9fDtu69.js";
2
2
  import { t as state } from "./state-B8adscCv.js";
3
3
  import { d as resolveModel, u as resolveCodexModel } from "./token-CbuFyx-B.js";
4
- import { a as sharedServerArgs, d as runSelfUpdate, i as setupAndServe, l as listModelsForEndpoint, n as getCodexEnvVars, r as parseSharedArgs, s as startKeepAwake, u as enableFileLogging } from "./server-setup-CSkdFAPP.js";
5
- import { i as launchChild, t as provisionToolbelt } from "./provision-D3_GtXze.js";
4
+ import { a as sharedServerArgs, d as enableFileLogging, f as runSelfUpdate, i as setupAndServe, n as getCodexEnvVars, r as parseSharedArgs, s as startKeepAwake, u as listModelsForEndpoint } from "./server-setup-BP_JM0qb.js";
5
+ import { i as launchChild, t as provisionToolbelt } from "./provision-Bn4FOzR4.js";
6
6
  import { defineCommand } from "citty";
7
7
  import consola from "consola";
8
8
  import process from "node:process";
@@ -85,4 +85,4 @@ const codex = defineCommand({
85
85
  //#endregion
86
86
  export { codex };
87
87
 
88
- //# sourceMappingURL=codex-kgVL5OyN.js.map
88
+ //# sourceMappingURL=codex-DdhBGec4.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"codex-kgVL5OyN.js","names":[],"sources":["../src/codex.ts"],"sourcesContent":["import process from \"node:process\"\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { enableFileLogging } from \"./lib/file-log-reporter\"\nimport { launchChild } from \"./lib/launch\"\nimport { listModelsForEndpoint } from \"./lib/model-validation\"\nimport {\n DEFAULT_CODEX_MODEL,\n DEFAULT_CODEX_MODEL_FALLBACKS,\n} from \"./lib/port\"\nimport {\n getCodexEnvVars,\n parseSharedArgs,\n setupAndServe,\n sharedServerArgs,\n} from \"./lib/server-setup\"\nimport { runSelfUpdate } from \"./lib/self-update\"\nimport { state } from \"./lib/state\"\nimport { toolbeltEnabled } from \"./lib/toolbelt\"\nimport { provisionToolbelt } from \"./lib/toolbelt/provision\"\nimport { colbertDegradedWarning, provisionAndIndexColbert } from \"./lib/colbert\"\nimport { startKeepAwake } from \"./lib/keep-awake\"\nimport { warmTreeSitterPool } from \"./lib/tree-sitter-pool/pool\"\nimport { provisionBrowserAssets } from \"./lib/browser-mcp/provision\"\nimport { hasSupportedBrowserInstalled } from \"./lib/browser-mcp/browser-detect\"\nimport { resolveCodexModel, resolveModel } from \"./lib/utils\"\n\nexport const codex = defineCommand({\n meta: {\n name: \"codex\",\n description: \"Start the proxy server and launch Codex CLI\",\n },\n args: {\n ...sharedServerArgs,\n model: {\n alias: \"m\",\n type: \"string\",\n description: \"Override the default model for Codex CLI\",\n },\n },\n async run({ args }) {\n if (!process.stdout.isTTY) {\n consola.error(\"The codex subcommand requires a TTY (interactive terminal).\")\n process.exit(1)\n }\n\n const parsed = parseSharedArgs(args as unknown as Record<string, unknown>)\n\n let server: Awaited<ReturnType<typeof setupAndServe>>[\"server\"]\n let serverUrl: string\n try {\n const result = await setupAndServe({\n ...parsed,\n port: parsed.port, // undefined = random port\n silent: true,\n })\n server = result.server\n serverUrl = result.serverUrl\n } catch (error) {\n consola.error(\"Failed to start server:\", error instanceof Error ? error.message : error)\n process.exit(1)\n }\n\n // Best-effort self-update (detached, applies next launch).\n void runSelfUpdate({ selfUpdate: args[\"self-update\"] !== false })\n\n // Materialize the LLM toolbelt in the background (PATH prepend is in\n // getCodexEnvVars). Best-effort; never blocks launch.\n if (toolbeltEnabled()) {\n void provisionToolbelt().catch(() => {})\n }\n\n // Best-effort ColBERT semantic-search provision + background index of\n // the launch cwd. ON by default; never blocks launch, never throws.\n void provisionAndIndexColbert()\n\n // Surface a terminally-failed semantic index to the HUMAN (see the note\n // in claude.ts). Fire-and-forget; lexical search still works.\n void colbertDegradedWarning(undefined, { logsToFile: true })\n .then((warning) => {\n if (warning) process.stderr.write(`${warning}\\n`)\n })\n .catch(() => {})\n\n // Best-effort, bounded launch warm-up: ready one tree-sitter worker.\n // Opt out with GH_ROUTER_DISABLE_TS_POOL_WARMUP=1.\n void warmTreeSitterPool()\n\n // Best-effort: keep the machine awake while the proxy/Codex session\n // runs (win32 default-on; opt out GH_ROUTER_DISABLE_KEEP_AWAKE=1).\n // Self-registered SIGINT/SIGTERM/exit reaper releases the assertion.\n startKeepAwake()\n\n // Best-effort: materialize the browser extension + bridge into the\n // stable app-dir and stamp the running version. Gated inline (browse\n // opt-in + a supported browser) rather than via browserToolsEnabled()\n // so the codex command path doesn't eagerly pull the compressor /\n // worker-agent graph. Never blocks launch, never throws.\n const browseOptIn =\n state.browseEnabled || process.env.GH_ROUTER_ENABLE_BROWSE === \"1\"\n if (browseOptIn && hasSupportedBrowserInstalled()) {\n void provisionBrowserAssets().catch((err) =>\n consola.debug(\"Browser extension provisioning failed:\", err),\n )\n }\n\n const usingDefault = !args.model\n const requestedModel = args.model ?? DEFAULT_CODEX_MODEL\n\n // Resolve model before printing success message (so we show the actual model)\n // but enable file logging first so resolution warnings go to file, not terminal\n enableFileLogging()\n\n let codexModel = resolveCodexModel(requestedModel)\n if (codexModel !== requestedModel) {\n consola.info(`Model \"${requestedModel}\" resolved to \"${codexModel}\"`)\n }\n\n // For the implicit-default path only: honor the explicit fallback order\n // (DEFAULT_CODEX_MODEL, then DEFAULT_CODEX_MODEL_FALLBACKS led by gpt-5.5)\n // by cache presence BEFORE resolveCodexModel's codex-slug-preferring\n // \"best /responses model\" safety net. `resolveModel` (NOT resolveCodexModel)\n // walks the chain, so the codex-slug preference can't shadow an\n // earlier-in-chain named fallback (e.g. gpt-5.5) that IS present. The\n // resolveCodexModel result above stays as the FINAL safety net, used only\n // when none of the named chain entries is in the catalog.\n if (usingDefault && state.models) {\n const inCache = (id: string) =>\n state.models?.data.some((m) => m.id === id) ?? false\n const firstPresent = [DEFAULT_CODEX_MODEL, ...DEFAULT_CODEX_MODEL_FALLBACKS]\n .map((id) => resolveModel(id))\n .find((id) => inCache(id))\n if (firstPresent) {\n if (firstPresent !== codexModel) {\n consola.info(\n `Default model \"${DEFAULT_CODEX_MODEL}\" not in your Copilot model list; falling back to \"${firstPresent}\".`,\n )\n }\n codexModel = firstPresent\n }\n }\n\n // Validate model exists in Copilot model list\n const modelEntry = state.models?.data.find((m) => m.id === codexModel)\n if (!modelEntry) {\n const available = listModelsForEndpoint(\"/responses\")\n consola.warn(\n `Model \"${codexModel}\" not found. Available codex models: ${available.join(\", \")}`,\n )\n } else {\n const ctx = modelEntry.capabilities?.limits?.max_context_window_tokens\n if (ctx) consola.info(`Model context window: ${ctx.toLocaleString()} tokens`)\n }\n\n // Print to stderr directly — consola's terminal reporter is already gone\n process.stderr.write(`Server ready on ${serverUrl}, launching Codex CLI (${codexModel})...\\n`)\n\n const envVars = getCodexEnvVars(serverUrl)\n const extraArgs = ((args as unknown as Record<string, unknown>)._ as string[]) ?? []\n\n launchChild(\n {\n kind: \"codex\",\n envVars,\n extraArgs,\n model: codexModel,\n serverUrl,\n },\n server,\n )\n },\n})\n"],"mappings":";;;;;;;;;AA6BA,MAAa,QAAQ,cAAc;CACjC,MAAM;EACJ,MAAM;EACN,aAAa;CACf;CACA,MAAM;EACJ,GAAG;EACH,OAAO;GACL,OAAO;GACP,MAAM;GACN,aAAa;EACf;CACF;CACA,MAAM,IAAI,EAAE,QAAQ;EAClB,IAAI,CAAC,QAAQ,OAAO,OAAO;GACzB,QAAQ,MAAM,6DAA6D;GAC3E,QAAQ,KAAK,CAAC;EAChB;EAEA,MAAM,SAAS,gBAAgB,IAA0C;EAEzE,IAAI;EACJ,IAAI;EACJ,IAAI;GACF,MAAM,SAAS,MAAM,cAAc;IACjC,GAAG;IACH,MAAM,OAAO;IACb,QAAQ;GACV,CAAC;GACD,SAAS,OAAO;GAChB,YAAY,OAAO;EACrB,SAAS,OAAO;GACd,QAAQ,MAAM,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,KAAK;GACvF,QAAQ,KAAK,CAAC;EAChB;EAGA,cAAmB,EAAE,YAAY,KAAK,mBAAmB,MAAM,CAAC;EAIhE,IAAI,gBAAgB,GAClB,kBAAuB,CAAC,CAAC,YAAY,CAAC,CAAC;EAKzC,yBAA8B;EAI9B,uBAA4B,KAAA,GAAW,EAAE,YAAY,KAAK,CAAC,CAAC,CACzD,MAAM,YAAY;GACjB,IAAI,SAAS,QAAQ,OAAO,MAAM,GAAG,QAAQ,GAAG;EAClD,CAAC,CAAC,CACD,YAAY,CAAC,CAAC;EAIjB,mBAAwB;EAKxB,eAAe;EASf,KADE,MAAM,iBAAiB,QAAQ,IAAI,4BAA4B,QAC9C,6BAA6B,GAC9C,uBAA4B,CAAC,CAAC,OAAO,QACnC,QAAQ,MAAM,0CAA0C,GAAG,CAC7D;EAGF,MAAM,eAAe,CAAC,KAAK;EAC3B,MAAM,iBAAiB,KAAK,SAAA;EAI5B,kBAAkB;EAElB,IAAI,aAAa,kBAAkB,cAAc;EACjD,IAAI,eAAe,gBACjB,QAAQ,KAAK,UAAU,eAAe,iBAAiB,WAAW,EAAE;EAWtE,IAAI,gBAAgB,MAAM,QAAQ;GAChC,MAAM,WAAW,OACf,MAAM,QAAQ,KAAK,MAAM,MAAM,EAAE,OAAO,EAAE,KAAK;GACjD,MAAM,eAAe,CAAC,qBAAqB,GAAG,6BAA6B,CAAC,CACzE,KAAK,OAAO,aAAa,EAAE,CAAC,CAAC,CAC7B,MAAM,OAAO,QAAQ,EAAE,CAAC;GAC3B,IAAI,cAAc;IAChB,IAAI,iBAAiB,YACnB,QAAQ,KACN,kBAAkB,oBAAoB,qDAAqD,aAAa,GAC1G;IAEF,aAAa;GACf;EACF;EAGA,MAAM,aAAa,MAAM,QAAQ,KAAK,MAAM,MAAM,EAAE,OAAO,UAAU;EACrE,IAAI,CAAC,YAAY;GACf,MAAM,YAAY,sBAAsB,YAAY;GACpD,QAAQ,KACN,UAAU,WAAW,uCAAuC,UAAU,KAAK,IAAI,GACjF;EACF,OAAO;GACL,MAAM,MAAM,WAAW,cAAc,QAAQ;GAC7C,IAAI,KAAK,QAAQ,KAAK,yBAAyB,IAAI,eAAe,EAAE,QAAQ;EAC9E;EAGA,QAAQ,OAAO,MAAM,mBAAmB,UAAU,yBAAyB,WAAW,OAAO;EAE7F,MAAM,UAAU,gBAAgB,SAAS;EACzC,MAAM,YAAc,KAA4C,KAAkB,CAAC;EAEnF,YACE;GACE,MAAM;GACN;GACA;GACA,OAAO;GACP;EACF,GACA,MACF;CACF;AACF,CAAC"}
1
+ {"version":3,"file":"codex-DdhBGec4.js","names":[],"sources":["../src/codex.ts"],"sourcesContent":["import process from \"node:process\"\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { enableFileLogging } from \"./lib/file-log-reporter\"\nimport { launchChild } from \"./lib/launch\"\nimport { listModelsForEndpoint } from \"./lib/model-validation\"\nimport {\n DEFAULT_CODEX_MODEL,\n DEFAULT_CODEX_MODEL_FALLBACKS,\n} from \"./lib/port\"\nimport {\n getCodexEnvVars,\n parseSharedArgs,\n setupAndServe,\n sharedServerArgs,\n} from \"./lib/server-setup\"\nimport { runSelfUpdate } from \"./lib/self-update\"\nimport { state } from \"./lib/state\"\nimport { toolbeltEnabled } from \"./lib/toolbelt\"\nimport { provisionToolbelt } from \"./lib/toolbelt/provision\"\nimport { colbertDegradedWarning, provisionAndIndexColbert } from \"./lib/colbert\"\nimport { startKeepAwake } from \"./lib/keep-awake\"\nimport { warmTreeSitterPool } from \"./lib/tree-sitter-pool/pool\"\nimport { provisionBrowserAssets } from \"./lib/browser-mcp/provision\"\nimport { hasSupportedBrowserInstalled } from \"./lib/browser-mcp/browser-detect\"\nimport { resolveCodexModel, resolveModel } from \"./lib/utils\"\n\nexport const codex = defineCommand({\n meta: {\n name: \"codex\",\n description: \"Start the proxy server and launch Codex CLI\",\n },\n args: {\n ...sharedServerArgs,\n model: {\n alias: \"m\",\n type: \"string\",\n description: \"Override the default model for Codex CLI\",\n },\n },\n async run({ args }) {\n if (!process.stdout.isTTY) {\n consola.error(\"The codex subcommand requires a TTY (interactive terminal).\")\n process.exit(1)\n }\n\n const parsed = parseSharedArgs(args as unknown as Record<string, unknown>)\n\n let server: Awaited<ReturnType<typeof setupAndServe>>[\"server\"]\n let serverUrl: string\n try {\n const result = await setupAndServe({\n ...parsed,\n port: parsed.port, // undefined = random port\n silent: true,\n })\n server = result.server\n serverUrl = result.serverUrl\n } catch (error) {\n consola.error(\"Failed to start server:\", error instanceof Error ? error.message : error)\n process.exit(1)\n }\n\n // Best-effort self-update (detached, applies next launch).\n void runSelfUpdate({ selfUpdate: args[\"self-update\"] !== false })\n\n // Materialize the LLM toolbelt in the background (PATH prepend is in\n // getCodexEnvVars). Best-effort; never blocks launch.\n if (toolbeltEnabled()) {\n void provisionToolbelt().catch(() => {})\n }\n\n // Best-effort ColBERT semantic-search provision + background index of\n // the launch cwd. ON by default; never blocks launch, never throws.\n void provisionAndIndexColbert()\n\n // Surface a terminally-failed semantic index to the HUMAN (see the note\n // in claude.ts). Fire-and-forget; lexical search still works.\n void colbertDegradedWarning(undefined, { logsToFile: true })\n .then((warning) => {\n if (warning) process.stderr.write(`${warning}\\n`)\n })\n .catch(() => {})\n\n // Best-effort, bounded launch warm-up: ready one tree-sitter worker.\n // Opt out with GH_ROUTER_DISABLE_TS_POOL_WARMUP=1.\n void warmTreeSitterPool()\n\n // Best-effort: keep the machine awake while the proxy/Codex session\n // runs (win32 default-on; opt out GH_ROUTER_DISABLE_KEEP_AWAKE=1).\n // Self-registered SIGINT/SIGTERM/exit reaper releases the assertion.\n startKeepAwake()\n\n // Best-effort: materialize the browser extension + bridge into the\n // stable app-dir and stamp the running version. Gated inline (browse\n // opt-in + a supported browser) rather than via browserToolsEnabled()\n // so the codex command path doesn't eagerly pull the compressor /\n // worker-agent graph. Never blocks launch, never throws.\n const browseOptIn =\n state.browseEnabled || process.env.GH_ROUTER_ENABLE_BROWSE === \"1\"\n if (browseOptIn && hasSupportedBrowserInstalled()) {\n void provisionBrowserAssets().catch((err) =>\n consola.debug(\"Browser extension provisioning failed:\", err),\n )\n }\n\n const usingDefault = !args.model\n const requestedModel = args.model ?? DEFAULT_CODEX_MODEL\n\n // Resolve model before printing success message (so we show the actual model)\n // but enable file logging first so resolution warnings go to file, not terminal\n enableFileLogging()\n\n let codexModel = resolveCodexModel(requestedModel)\n if (codexModel !== requestedModel) {\n consola.info(`Model \"${requestedModel}\" resolved to \"${codexModel}\"`)\n }\n\n // For the implicit-default path only: honor the explicit fallback order\n // (DEFAULT_CODEX_MODEL, then DEFAULT_CODEX_MODEL_FALLBACKS led by gpt-5.5)\n // by cache presence BEFORE resolveCodexModel's codex-slug-preferring\n // \"best /responses model\" safety net. `resolveModel` (NOT resolveCodexModel)\n // walks the chain, so the codex-slug preference can't shadow an\n // earlier-in-chain named fallback (e.g. gpt-5.5) that IS present. The\n // resolveCodexModel result above stays as the FINAL safety net, used only\n // when none of the named chain entries is in the catalog.\n if (usingDefault && state.models) {\n const inCache = (id: string) =>\n state.models?.data.some((m) => m.id === id) ?? false\n const firstPresent = [DEFAULT_CODEX_MODEL, ...DEFAULT_CODEX_MODEL_FALLBACKS]\n .map((id) => resolveModel(id))\n .find((id) => inCache(id))\n if (firstPresent) {\n if (firstPresent !== codexModel) {\n consola.info(\n `Default model \"${DEFAULT_CODEX_MODEL}\" not in your Copilot model list; falling back to \"${firstPresent}\".`,\n )\n }\n codexModel = firstPresent\n }\n }\n\n // Validate model exists in Copilot model list\n const modelEntry = state.models?.data.find((m) => m.id === codexModel)\n if (!modelEntry) {\n const available = listModelsForEndpoint(\"/responses\")\n consola.warn(\n `Model \"${codexModel}\" not found. Available codex models: ${available.join(\", \")}`,\n )\n } else {\n const ctx = modelEntry.capabilities?.limits?.max_context_window_tokens\n if (ctx) consola.info(`Model context window: ${ctx.toLocaleString()} tokens`)\n }\n\n // Print to stderr directly — consola's terminal reporter is already gone\n process.stderr.write(`Server ready on ${serverUrl}, launching Codex CLI (${codexModel})...\\n`)\n\n const envVars = getCodexEnvVars(serverUrl)\n const extraArgs = ((args as unknown as Record<string, unknown>)._ as string[]) ?? []\n\n launchChild(\n {\n kind: \"codex\",\n envVars,\n extraArgs,\n model: codexModel,\n serverUrl,\n },\n server,\n )\n },\n})\n"],"mappings":";;;;;;;;;AA6BA,MAAa,QAAQ,cAAc;CACjC,MAAM;EACJ,MAAM;EACN,aAAa;CACf;CACA,MAAM;EACJ,GAAG;EACH,OAAO;GACL,OAAO;GACP,MAAM;GACN,aAAa;EACf;CACF;CACA,MAAM,IAAI,EAAE,QAAQ;EAClB,IAAI,CAAC,QAAQ,OAAO,OAAO;GACzB,QAAQ,MAAM,6DAA6D;GAC3E,QAAQ,KAAK,CAAC;EAChB;EAEA,MAAM,SAAS,gBAAgB,IAA0C;EAEzE,IAAI;EACJ,IAAI;EACJ,IAAI;GACF,MAAM,SAAS,MAAM,cAAc;IACjC,GAAG;IACH,MAAM,OAAO;IACb,QAAQ;GACV,CAAC;GACD,SAAS,OAAO;GAChB,YAAY,OAAO;EACrB,SAAS,OAAO;GACd,QAAQ,MAAM,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,KAAK;GACvF,QAAQ,KAAK,CAAC;EAChB;EAGA,cAAmB,EAAE,YAAY,KAAK,mBAAmB,MAAM,CAAC;EAIhE,IAAI,gBAAgB,GAClB,kBAAuB,CAAC,CAAC,YAAY,CAAC,CAAC;EAKzC,yBAA8B;EAI9B,uBAA4B,KAAA,GAAW,EAAE,YAAY,KAAK,CAAC,CAAC,CACzD,MAAM,YAAY;GACjB,IAAI,SAAS,QAAQ,OAAO,MAAM,GAAG,QAAQ,GAAG;EAClD,CAAC,CAAC,CACD,YAAY,CAAC,CAAC;EAIjB,mBAAwB;EAKxB,eAAe;EASf,KADE,MAAM,iBAAiB,QAAQ,IAAI,4BAA4B,QAC9C,6BAA6B,GAC9C,uBAA4B,CAAC,CAAC,OAAO,QACnC,QAAQ,MAAM,0CAA0C,GAAG,CAC7D;EAGF,MAAM,eAAe,CAAC,KAAK;EAC3B,MAAM,iBAAiB,KAAK,SAAA;EAI5B,kBAAkB;EAElB,IAAI,aAAa,kBAAkB,cAAc;EACjD,IAAI,eAAe,gBACjB,QAAQ,KAAK,UAAU,eAAe,iBAAiB,WAAW,EAAE;EAWtE,IAAI,gBAAgB,MAAM,QAAQ;GAChC,MAAM,WAAW,OACf,MAAM,QAAQ,KAAK,MAAM,MAAM,EAAE,OAAO,EAAE,KAAK;GACjD,MAAM,eAAe,CAAC,qBAAqB,GAAG,6BAA6B,CAAC,CACzE,KAAK,OAAO,aAAa,EAAE,CAAC,CAAC,CAC7B,MAAM,OAAO,QAAQ,EAAE,CAAC;GAC3B,IAAI,cAAc;IAChB,IAAI,iBAAiB,YACnB,QAAQ,KACN,kBAAkB,oBAAoB,qDAAqD,aAAa,GAC1G;IAEF,aAAa;GACf;EACF;EAGA,MAAM,aAAa,MAAM,QAAQ,KAAK,MAAM,MAAM,EAAE,OAAO,UAAU;EACrE,IAAI,CAAC,YAAY;GACf,MAAM,YAAY,sBAAsB,YAAY;GACpD,QAAQ,KACN,UAAU,WAAW,uCAAuC,UAAU,KAAK,IAAI,GACjF;EACF,OAAO;GACL,MAAM,MAAM,WAAW,cAAc,QAAQ;GAC7C,IAAI,KAAK,QAAQ,KAAK,yBAAyB,IAAI,eAAe,EAAE,QAAQ;EAC9E;EAGA,QAAQ,OAAO,MAAM,mBAAmB,UAAU,yBAAyB,WAAW,OAAO;EAE7F,MAAM,UAAU,gBAAgB,SAAS;EACzC,MAAM,YAAc,KAA4C,KAAkB,CAAC;EAEnF,YACE;GACE,MAAM;GACN;GACA;GACA,OAAO;GACP;EACF,GACA,MACF;CACF;AACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { C as runWorkerAgent } from "./peer-mcp-personas-C9fDtu69.js";
2
+ export { runWorkerAgent };
@@ -606,7 +606,7 @@ async function discoverGateCommands(cwd, opts) {
606
606
  if (files.length === 0) return null;
607
607
  let result;
608
608
  try {
609
- const { runWorkerAgent } = await import("./engine-xuIzQNV1.js");
609
+ const { runWorkerAgent } = await import("./engine-C7DkYq2g.js");
610
610
  result = await runWorkerAgent({
611
611
  mode: "explore",
612
612
  workspace: root,
@@ -632,4 +632,4 @@ async function discoverGateCommands(cwd, opts) {
632
632
  //#endregion
633
633
  export { checksForDescriptor as a, writeDiscoveredGate as i, readDiscoveredGate as n, descriptorHash as o, sourcesHash as r, parseGateDescriptor as s, discoverGateCommands as t };
634
634
 
635
- //# sourceMappingURL=gate-discovery-D4-F99e_.js.map
635
+ //# sourceMappingURL=gate-discovery-C6jB3bBG.js.map