github-router 0.3.275 → 0.3.282

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 (106) hide show
  1. package/dist/{attribution-settings-ZOaCUrYY.js → attribution-settings-srL3gBR9.js} +60 -57
  2. package/dist/attribution-settings-srL3gBR9.js.map +1 -0
  3. package/dist/{auth-Q1tfmfCT.js → auth-VUL2Zxvw.js} +3 -3
  4. package/dist/{auth-Q1tfmfCT.js.map → auth-VUL2Zxvw.js.map} +1 -1
  5. package/dist/browser-ext/manifest.json +1 -1
  6. package/dist/{check-usage-CHLz4tU_.js → check-usage-CcLdFPGr.js} +4 -4
  7. package/dist/{check-usage-CHLz4tU_.js.map → check-usage-CcLdFPGr.js.map} +1 -1
  8. package/dist/{claude-Cl4gYoOZ.js → claude-DJQjA5oQ.js} +57 -30
  9. package/dist/claude-DJQjA5oQ.js.map +1 -0
  10. package/dist/{codex-D_IXUgKf.js → codex-BAXemWpJ.js} +5 -5
  11. package/dist/{codex-D_IXUgKf.js.map → codex-BAXemWpJ.js.map} +1 -1
  12. package/dist/{debug-CuuxCk_J.js → debug-CtzYWxpJ.js} +2 -2
  13. package/dist/{debug-CuuxCk_J.js.map → debug-CtzYWxpJ.js.map} +1 -1
  14. package/dist/engine-BvLgh1QI.js +2 -0
  15. package/dist/{gate-discovery-Br448Md6.js → gate-discovery-BwtiYKvW.js} +5 -5
  16. package/dist/{gate-discovery-Br448Md6.js.map → gate-discovery-BwtiYKvW.js.map} +1 -1
  17. package/dist/{get-copilot-usage-BRN18uMJ.js → get-copilot-usage-B-EDAqQb.js} +2 -2
  18. package/dist/{get-copilot-usage-BRN18uMJ.js.map → get-copilot-usage-B-EDAqQb.js.map} +1 -1
  19. package/dist/hooks.mjs +37870 -0
  20. package/dist/hooks.sha256 +1 -0
  21. package/dist/{internal-artifact-open-CDqPfegE.js → internal-artifact-open-Dj5Nlq0L.js} +2 -2
  22. package/dist/{internal-artifact-open-CDqPfegE.js.map → internal-artifact-open-Dj5Nlq0L.js.map} +1 -1
  23. package/dist/{internal-first-mate-guard-7v2CtMA6.js → internal-first-mate-guard-CQdXWjNz.js} +1 -1
  24. package/dist/{internal-first-mate-guard-La0tIjTU.js → internal-first-mate-guard-DMgHg2s6.js} +5 -4
  25. package/dist/{internal-first-mate-guard-La0tIjTU.js.map → internal-first-mate-guard-DMgHg2s6.js.map} +1 -1
  26. package/dist/{internal-plan-review-CH9qTHoZ.js → internal-plan-review-DRFHET_B.js} +11 -4
  27. package/dist/internal-plan-review-DRFHET_B.js.map +1 -0
  28. package/dist/{internal-prompt-submit-Bve1s4z_.js → internal-prompt-submit-f1LR2P2G.js} +4 -4
  29. package/dist/{internal-prompt-submit-Bve1s4z_.js.map → internal-prompt-submit-f1LR2P2G.js.map} +1 -1
  30. package/dist/{internal-session-bind-Cc8bMXHK.js → internal-session-bind-DhZhxJ3T.js} +2 -2
  31. package/dist/{internal-session-bind-Cc8bMXHK.js.map → internal-session-bind-DhZhxJ3T.js.map} +1 -1
  32. package/dist/{internal-stop-hook-DMLQ8vRZ.js → internal-stop-hook-514RJeHO.js} +68 -20
  33. package/dist/internal-stop-hook-514RJeHO.js.map +1 -0
  34. package/dist/{internal-stop-review-CWE7_QVv.js → internal-stop-review-BBsLcbPG.js} +2 -2
  35. package/dist/{internal-stop-review-CWE7_QVv.js.map → internal-stop-review-BBsLcbPG.js.map} +1 -1
  36. package/dist/{internal-worker-guard-Lu8VHj5k.js → internal-worker-guard-VucpClSi.js} +2 -2
  37. package/dist/{internal-worker-guard-Lu8VHj5k.js.map → internal-worker-guard-VucpClSi.js.map} +1 -1
  38. package/dist/{internal-workspace-header-BRMz0Yql.js → internal-workspace-header-OYgHEnFt.js} +2 -2
  39. package/dist/{internal-workspace-header-BRMz0Yql.js.map → internal-workspace-header-OYgHEnFt.js.map} +1 -1
  40. package/dist/lib/tree-sitter-pool/lifecycle-C7W8D2lx.js +165 -0
  41. package/dist/lib/tree-sitter-pool/lifecycle-Dx0SnP7Z.js +157 -0
  42. package/dist/lib/tree-sitter-pool/worker.js +287 -14
  43. package/dist/{lifecycle-0XrazT05.js → lifecycle-B7CHqKlF.js} +2 -2
  44. package/dist/{lifecycle-0XrazT05.js.map → lifecycle-B7CHqKlF.js.map} +1 -1
  45. package/dist/lifecycle-CbmHMMSD.js +2 -0
  46. package/dist/{lifecycle-AgNOtFRv.js → lifecycle-D-rL81tT.js} +2 -2
  47. package/dist/{lifecycle-AgNOtFRv.js.map → lifecycle-D-rL81tT.js.map} +1 -1
  48. package/dist/lifecycle-DTcZwa7U.js +2 -0
  49. package/dist/lifecycle-K9oVtGde.mjs +16 -0
  50. package/dist/main.js +18 -18
  51. package/dist/{mcp-workspace-header-CGJbNeHb.js → mcp-workspace-header-ucs2SDST.js} +5 -6
  52. package/dist/mcp-workspace-header-ucs2SDST.js.map +1 -0
  53. package/dist/{models-d0gkuYGy.js → models-C16mBK2M.js} +3 -3
  54. package/dist/{models-d0gkuYGy.js.map → models-C16mBK2M.js.map} +1 -1
  55. package/dist/{orchestration-B_Q3ncXI.js → orchestration-CtM6FYNx.js} +2 -2
  56. package/dist/{orchestration-B_Q3ncXI.js.map → orchestration-CtM6FYNx.js.map} +1 -1
  57. package/dist/package-root-B-osctCk.js +29 -0
  58. package/dist/package-root-B-osctCk.js.map +1 -0
  59. package/dist/paths-CV9K7Xqm.js +2 -0
  60. package/dist/{paths-Bg1_DWhi.js → paths-wLC0InjX.js} +28 -4
  61. package/dist/paths-wLC0InjX.js.map +1 -0
  62. package/dist/{peer-mcp-personas-TMOZJhfy.js → peer-mcp-personas-l4P4s1fK.js} +497 -133
  63. package/dist/peer-mcp-personas-l4P4s1fK.js.map +1 -0
  64. package/dist/{plan-review-hook-BKOcW5s4.js → plan-review-hook-Lf9ISdF6.js} +5 -6
  65. package/dist/plan-review-hook-Lf9ISdF6.js.map +1 -0
  66. package/dist/{prompt-submit-hook-F7Zih_au.js → prompt-submit-hook-BlijaOn7.js} +6 -11
  67. package/dist/prompt-submit-hook-BlijaOn7.js.map +1 -0
  68. package/dist/{provision-BJ5vUpmp.js → provision-DlT34zcf.js} +4 -4
  69. package/dist/{provision-BJ5vUpmp.js.map → provision-DlT34zcf.js.map} +1 -1
  70. package/dist/self-invocation-CKMjcA5F.js +380 -0
  71. package/dist/self-invocation-CKMjcA5F.js.map +1 -0
  72. package/dist/{serve-DMA82DFJ.js → serve-orGUartp.js} +34 -18
  73. package/dist/serve-orGUartp.js.map +1 -0
  74. package/dist/{server-setup-CVfqSkh_.js → server-setup-BRBe8gW4.js} +63 -7
  75. package/dist/{server-setup-CVfqSkh_.js.map → server-setup-BRBe8gW4.js.map} +1 -1
  76. package/dist/{start-BGze5TnZ.js → start-sutbbkwc.js} +3 -3
  77. package/dist/{start-BGze5TnZ.js.map → start-sutbbkwc.js.map} +1 -1
  78. package/dist/{stop-gate-hook-BqpumJtl.js → stop-gate-hook-DgJ6sW8N.js} +100 -52
  79. package/dist/stop-gate-hook-DgJ6sW8N.js.map +1 -0
  80. package/dist/{stop-gate-policy-C0XOBZhB.js → stop-gate-policy-DG5yYWGn.js} +2 -2
  81. package/dist/{stop-gate-policy-C0XOBZhB.js.map → stop-gate-policy-DG5yYWGn.js.map} +1 -1
  82. package/dist/{token-Bz6HoH2H.js → token-CnlB0884.js} +2 -2
  83. package/dist/token-CnlB0884.js.map +1 -0
  84. package/dist/{version-_Q1WpsQp.js → version-C8x2hQrZ.js} +14 -2
  85. package/dist/version-C8x2hQrZ.js.map +1 -0
  86. package/dist/{worker-dispatch-Bj1uYyG9.js → worker-dispatch-4O3IWtP0.js} +4 -4
  87. package/dist/worker-dispatch-4O3IWtP0.js.map +1 -0
  88. package/package.json +2 -2
  89. package/dist/attribution-settings-ZOaCUrYY.js.map +0 -1
  90. package/dist/claude-Cl4gYoOZ.js.map +0 -1
  91. package/dist/engine-Drs3cxLW.js +0 -2
  92. package/dist/internal-plan-review-CH9qTHoZ.js.map +0 -1
  93. package/dist/internal-stop-hook-DMLQ8vRZ.js.map +0 -1
  94. package/dist/lifecycle-2M0IThRr.js +0 -2
  95. package/dist/lifecycle-C8kFsAj-.js +0 -2
  96. package/dist/mcp-workspace-header-CGJbNeHb.js.map +0 -1
  97. package/dist/paths-BbHtQAOs.js +0 -2
  98. package/dist/paths-Bg1_DWhi.js.map +0 -1
  99. package/dist/peer-mcp-personas-TMOZJhfy.js.map +0 -1
  100. package/dist/plan-review-hook-BKOcW5s4.js.map +0 -1
  101. package/dist/prompt-submit-hook-F7Zih_au.js.map +0 -1
  102. package/dist/serve-DMA82DFJ.js.map +0 -1
  103. package/dist/stop-gate-hook-BqpumJtl.js.map +0 -1
  104. package/dist/token-Bz6HoH2H.js.map +0 -1
  105. package/dist/version-_Q1WpsQp.js.map +0 -1
  106. package/dist/worker-dispatch-Bj1uYyG9.js.map +0 -1
@@ -1,13 +1,14 @@
1
- import { t as getPackageVersion } from "./version-_Q1WpsQp.js";
2
- import { t as PATHS } from "./paths-Bg1_DWhi.js";
3
- import { A as state, C as GITHUB_GRAPHQL_URL, D as githubAgentGraphQLHeaders, E as copilotVersion, O as githubAgentHeaders, S as GITHUB_API_BASE_URL, T as copilotHeaders, b as sanitizeTransportText, d as resolveModel, f as sleep$2, g as HTTPError, h as isAllowedCopilotHost, i as tryRefreshAndRetry, v as classifyTransportError, w as copilotBaseUrl, x as withTransientRetry, y as fetchWithTransientRetry } from "./token-Bz6HoH2H.js";
1
+ import { n as explicitPackageRoot } from "./package-root-B-osctCk.js";
2
+ import { t as getPackageVersion } from "./version-C8x2hQrZ.js";
3
+ import { t as PATHS } from "./paths-wLC0InjX.js";
4
+ import { A as state, C as GITHUB_GRAPHQL_URL, D as githubAgentGraphQLHeaders, E as copilotVersion, O as githubAgentHeaders, S as GITHUB_API_BASE_URL, T as copilotHeaders, b as sanitizeTransportText, d as resolveModel, f as sleep$2, g as HTTPError, h as isAllowedCopilotHost, i as tryRefreshAndRetry, v as classifyTransportError, w as copilotBaseUrl, x as withTransientRetry, y as fetchWithTransientRetry } from "./token-CnlB0884.js";
4
5
  import { a as resolveExecutable, c as runManagedExeCapture, i as parseIntEnv, l as spawnTaskkillBestEffort, r as parseBoolEnv } from "./exec-y8C_MU8A.js";
5
- import { i as registerExitHandlers$1, n as getInstanceUuid, r as recordWorkerRepo, t as WorktreeRegistry } from "./lifecycle-0XrazT05.js";
6
- import { t as MCP_WORKSPACE_HEADER } from "./mcp-workspace-header-CGJbNeHb.js";
6
+ import { i as registerExitHandlers$1, n as getInstanceUuid, r as recordWorkerRepo, t as WorktreeRegistry } from "./lifecycle-B7CHqKlF.js";
7
+ import { t as MCP_WORKSPACE_HEADER } from "./mcp-workspace-header-ucs2SDST.js";
7
8
  import { n as ArtifactError, r as applyInsecureTls, t as ArtifactClient } from "./client-CQMfroGV.js";
8
- import { n as isPidAlive$1, r as registerColbertExitHandlers, s as trackChild, t as getColbertInstanceUuid } from "./lifecycle-AgNOtFRv.js";
9
- import { h as runGateChecks, m as sealedGateIds, p as resolveSealedGate } from "./stop-gate-hook-BqpumJtl.js";
10
- import { t as liveExec } from "./orchestration-B_Q3ncXI.js";
9
+ import { n as isPidAlive$1, r as registerColbertExitHandlers, s as trackChild, t as getColbertInstanceUuid } from "./lifecycle-D-rL81tT.js";
10
+ import { f as resolveSealedGate, m as runGateChecks, p as sealedGateIds } from "./stop-gate-hook-DgJ6sW8N.js";
11
+ import { t as liveExec } from "./orchestration-CtM6FYNx.js";
11
12
  import { createRequire } from "node:module";
12
13
  import consola from "consola";
13
14
  import { chmodSync, closeSync, constants, cpSync, existsSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync } from "node:fs";
@@ -11888,6 +11889,123 @@ function objectProp(description, properties, required) {
11888
11889
  function anyProp(description) {
11889
11890
  return { description };
11890
11891
  }
11892
+ //#endregion
11893
+ //#region src/lib/tree-sitter-assets/files.ts
11894
+ /** WASM assets code search loads from tree-sitter-wasms. */
11895
+ const TREE_SITTER_GRAMMAR_FILES = {
11896
+ typescript: "tree-sitter-typescript.wasm",
11897
+ tsx: "tree-sitter-tsx.wasm",
11898
+ javascript: "tree-sitter-javascript.wasm",
11899
+ python: "tree-sitter-python.wasm",
11900
+ go: "tree-sitter-go.wasm",
11901
+ rust: "tree-sitter-rust.wasm",
11902
+ java: "tree-sitter-java.wasm",
11903
+ c: "tree-sitter-c.wasm",
11904
+ cpp: "tree-sitter-cpp.wasm"
11905
+ };
11906
+ const TREE_SITTER_RUNTIME_FILE = "tree-sitter.wasm";
11907
+ //#endregion
11908
+ //#region src/lib/tree-sitter-assets/provision.ts
11909
+ const PUBLISH_ATTEMPTS = 3;
11910
+ let _provisioned$1 = false;
11911
+ let _inFlight$1;
11912
+ /**
11913
+ * Materialize every required WASM asset. Single-flight and success-cached;
11914
+ * transient failures remain retryable. Never throws to the launcher.
11915
+ */
11916
+ function provisionTreeSitterAssets() {
11917
+ if (_provisioned$1) return Promise.resolve();
11918
+ if (_inFlight$1) return _inFlight$1;
11919
+ _inFlight$1 = Promise.resolve().then(() => provisionImpl()).then((complete) => {
11920
+ if (complete) _provisioned$1 = true;
11921
+ }).finally(() => {
11922
+ _inFlight$1 = void 0;
11923
+ });
11924
+ return _inFlight$1;
11925
+ }
11926
+ function provisionImpl() {
11927
+ try {
11928
+ const require = createRequire(import.meta.url);
11929
+ const grammarPackage = require.resolve("tree-sitter-wasms/package.json");
11930
+ const grammarRoot = path.join(path.dirname(grammarPackage), "out");
11931
+ const runtime = require.resolve("web-tree-sitter/tree-sitter.wasm");
11932
+ const destination = PATHS.TREE_SITTER_ASSETS_DIR;
11933
+ mkdirSync(destination, { recursive: true });
11934
+ let complete = publishAsset(runtime, path.join(destination, TREE_SITTER_RUNTIME_FILE));
11935
+ for (const filename of Object.values(TREE_SITTER_GRAMMAR_FILES)) complete = publishAsset(path.join(grammarRoot, filename), path.join(destination, filename)) && complete;
11936
+ return complete;
11937
+ } catch (err) {
11938
+ consola.debug("[tree-sitter-assets] provisioning skipped:", err);
11939
+ return false;
11940
+ }
11941
+ }
11942
+ /**
11943
+ * Publish through a unique same-directory temporary file. Never remove the
11944
+ * destination first: a concurrent parser must see either the prior complete
11945
+ * file or the new complete file, never a missing/partial path. A losing racer
11946
+ * accepts the winner when its bytes match the source.
11947
+ */
11948
+ function publishAsset(source, destination) {
11949
+ let bytes;
11950
+ try {
11951
+ bytes = readFileSync(source);
11952
+ } catch {
11953
+ return false;
11954
+ }
11955
+ if (matchesContent(destination, bytes)) return true;
11956
+ for (let attempt = 0; attempt < PUBLISH_ATTEMPTS; attempt++) {
11957
+ const tmp = `${destination}.${process.pid}-${attempt}.tmp`;
11958
+ try {
11959
+ writeFileSync(tmp, bytes);
11960
+ renameSync(tmp, destination);
11961
+ return true;
11962
+ } catch {
11963
+ try {
11964
+ rmSync(tmp, { force: true });
11965
+ } catch {}
11966
+ if (matchesContent(destination, bytes)) return true;
11967
+ }
11968
+ }
11969
+ return false;
11970
+ }
11971
+ /**
11972
+ * Whether the published file is byte-identical to the source.
11973
+ *
11974
+ * Content, not size: a grammar upgrade that happens to keep the same byte
11975
+ * length would otherwise never propagate, and the stale copy would shadow the
11976
+ * package's newer file permanently — a silent, self-perpetuating wrong answer.
11977
+ * The size check first keeps the common case to one `stat`.
11978
+ */
11979
+ function matchesContent(file, bytes) {
11980
+ try {
11981
+ const stat = statSync(file);
11982
+ if (!stat.isFile() || stat.size !== bytes.byteLength) return false;
11983
+ return readFileSync(file).equals(bytes);
11984
+ } catch {
11985
+ return false;
11986
+ }
11987
+ }
11988
+ /**
11989
+ * Whether the stable directory holds the COMPLETE asset set: the runtime plus
11990
+ * every grammar.
11991
+ *
11992
+ * Callers must gate on the whole set, never on the one file they are about to
11993
+ * read. web-tree-sitter enforces a language-ABI version between the runtime and
11994
+ * the grammars, so adopting a stable runtime while grammars still come from the
11995
+ * package tree (or the reverse) can pair mismatched builds. That surfaces as a
11996
+ * caught `Language.load` failure, which silently disables structural ranking —
11997
+ * the exact silent degradation this whole change is meant to end.
11998
+ */
11999
+ function stableTreeSitterAssetsComplete() {
12000
+ const dir = PATHS.TREE_SITTER_ASSETS_DIR;
12001
+ return [TREE_SITTER_RUNTIME_FILE, ...Object.values(TREE_SITTER_GRAMMAR_FILES)].every((name) => {
12002
+ try {
12003
+ return statSync(path.join(dir, name)).isFile();
12004
+ } catch {
12005
+ return false;
12006
+ }
12007
+ });
12008
+ }
11891
12009
  /**
11892
12010
  * Extension → grammar key. Grammars not in this map skip structural
11893
12011
  * parsing (the hit falls back to the regex SYMBOL_REGEX heuristic for
@@ -11915,22 +12033,11 @@ const EXTENSION_TO_LANG = {
11915
12033
  ".hxx": "cpp"
11916
12034
  };
11917
12035
  /**
11918
- * Grammar key → wasm filename under `node_modules/tree-sitter-wasms/out/`.
11919
- * Resolved at runtime from `node_modules`; the file paths are stable
11920
- * because `tree-sitter-wasms` ships prebuilt binaries (no per-install
11921
- * codegen).
12036
+ * Grammar key → wasm filename. The stable APP_DIR copy is preferred; the
12037
+ * original `node_modules/tree-sitter-wasms/out/` directory remains the
12038
+ * first-run fallback while background provisioning completes.
11922
12039
  */
11923
- const GRAMMAR_FILES = {
11924
- typescript: "tree-sitter-typescript.wasm",
11925
- tsx: "tree-sitter-tsx.wasm",
11926
- javascript: "tree-sitter-javascript.wasm",
11927
- python: "tree-sitter-python.wasm",
11928
- go: "tree-sitter-go.wasm",
11929
- rust: "tree-sitter-rust.wasm",
11930
- java: "tree-sitter-java.wasm",
11931
- c: "tree-sitter-c.wasm",
11932
- cpp: "tree-sitter-cpp.wasm"
11933
- };
12040
+ const GRAMMAR_FILES = TREE_SITTER_GRAMMAR_FILES;
11934
12041
  /**
11935
12042
  * Per-language definition-shape node types. When a matched identifier
11936
12043
  * sits inside one of these nodes AND is at the node's "name" position,
@@ -12064,12 +12171,16 @@ function getLanguageKeyForPath(filePath) {
12064
12171
  }
12065
12172
  let _grammarBundle;
12066
12173
  /**
12067
- * Resolve the `tree-sitter-wasms/out/` directory at the package root.
12068
- * `require.resolve` is used through a try/catch — the bundled-only
12069
- * fallback runs in environments where node_modules has been pruned to
12070
- * just runtime deps.
12174
+ * Resolve the grammar directory. The stable APP_DIR copy wins only when the
12175
+ * COMPLETE set is present; otherwise `require.resolve` supplies the
12176
+ * package-tree fallback for first launch or a best-effort provisioning failure.
12177
+ *
12178
+ * All-or-nothing on purpose — see `stableTreeSitterAssetsComplete()`: mixing a
12179
+ * stable runtime with package-tree grammars can pair mismatched ABI builds and
12180
+ * silently disable structural ranking.
12071
12181
  */
12072
12182
  function resolveGrammarRoot() {
12183
+ if (stableTreeSitterAssetsComplete()) return PATHS.TREE_SITTER_ASSETS_DIR;
12073
12184
  try {
12074
12185
  const pkgPath = __require.resolve("tree-sitter-wasms/package.json");
12075
12186
  return path$1.join(path$1.dirname(pkgPath), "out");
@@ -12078,6 +12189,15 @@ function resolveGrammarRoot() {
12078
12189
  }
12079
12190
  }
12080
12191
  /**
12192
+ * web-tree-sitter normally resolves this sidecar relative to its JS module.
12193
+ * Prefer the durable copy, but only under the same all-present gate the
12194
+ * grammars use, so the runtime and the grammars always come from one install.
12195
+ */
12196
+ function parserInitOptions() {
12197
+ if (!stableTreeSitterAssetsComplete()) return void 0;
12198
+ return { locateFile: () => path$1.join(PATHS.TREE_SITTER_ASSETS_DIR, TREE_SITTER_RUNTIME_FILE) };
12199
+ }
12200
+ /**
12081
12201
  * Pre-load all grammars at module-init time so the first search
12082
12202
  * doesn't pay a ~500ms cold-start cost. The Promise is captured at
12083
12203
  * import time and awaited per-call; per-grammar failures are caught
@@ -12088,7 +12208,7 @@ function getGrammarBundle() {
12088
12208
  _grammarBundle = { ready: (async () => {
12089
12209
  const out = /* @__PURE__ */ new Map();
12090
12210
  try {
12091
- await Parser.init();
12211
+ await Parser.init(parserInitOptions());
12092
12212
  } catch (err) {
12093
12213
  consola.warn(`[code_search] tree-sitter Parser.init failed; structural ranking disabled: ${err.message}`);
12094
12214
  return out;
@@ -13271,16 +13391,19 @@ const STRUCTURAL_CACHE_MAX = 64;
13271
13391
  const SYMBOL_REGEX = /^(?:export\s+)?(?:default\s+)?(?:async\s+)?(?:public\s+|private\s+|protected\s+|static\s+|abstract\s+|readonly\s+)*(?:function|class|interface|type|enum|def|fn|trait|impl|module|namespace|const|let|var)\s+[A-Za-z_$]/;
13272
13392
  let _rgResolution;
13273
13393
  /**
13274
- * Tri-tier resolution. Memoized. Mirrors cc-backup
13394
+ * Four-tier resolution. Memoized. Mirrors cc-backup
13275
13395
  * `src/utils/ripgrep.ts:31-65`.
13276
13396
  *
13277
13397
  * 1. System rg on PATH — use the literal command name `"rg"` (NOT
13278
13398
  * the absolute path). This leverages NoDefaultCurrentDirectory-
13279
13399
  * InExePath on Windows, preventing PATH-hijacking via a
13280
13400
  * malicious ./rg.exe in the proxy's cwd.
13281
- * 2. Bundled via `@vscode/ripgrep` falls back to the per-platform
13401
+ * 2. Router-owned toolbelt copy under APP_DIR. Its absolute path is
13402
+ * safe because it cannot resolve to a planted binary in the cwd,
13403
+ * and it survives a temp-hosted bunx package tree being reaped.
13404
+ * 3. Bundled via `@vscode/ripgrep` — falls back to the per-platform
13282
13405
  * binary that `optionalDependencies` installed.
13283
- * 3. Throw — surfaced to the caller as an MCP isError response.
13406
+ * 4. Throw — surfaced to the caller as an MCP isError response.
13284
13407
  */
13285
13408
  function resolveRipgrep() {
13286
13409
  if (_rgResolution) return _rgResolution;
@@ -13291,6 +13414,14 @@ function resolveRipgrep() {
13291
13414
  };
13292
13415
  return _rgResolution;
13293
13416
  }
13417
+ const toolbeltPath = path$1.join(PATHS.TOOLBELT_BIN_DIR, process.platform === "win32" ? "rg.exe" : "rg");
13418
+ if (existsSync(toolbeltPath)) {
13419
+ _rgResolution = {
13420
+ rgPath: toolbeltPath,
13421
+ source: "toolbelt"
13422
+ };
13423
+ return _rgResolution;
13424
+ }
13294
13425
  try {
13295
13426
  const mod = __require("@vscode/ripgrep");
13296
13427
  if (mod.rgPath && existsSync(mod.rgPath)) {
@@ -17206,14 +17337,19 @@ function findPackageRoot(startDir, maxHops = 10) {
17206
17337
  }
17207
17338
  }
17208
17339
  /**
17209
- * Resolve the github-router package root. Uses two sources in order:
17210
- * 1. process.argv[1] the entrypoint script, walks up from there.
17211
- * 2. import.meta.url of THIS module, walks up from there.
17212
- * 3. process.cwd() as last resort.
17340
+ * Resolve the github-router package root. Uses sources in order:
17341
+ * 1. The explicit root baked into the relocated hook launcher's argv. From
17342
+ * `<APP_DIR>/hooks/`, neither entrypoint walk can find the package and cwd
17343
+ * is the user's workspace, so this source must win when present.
17344
+ * 2. process.argv[1] — the entrypoint script, walks up from there.
17345
+ * 3. import.meta.url of THIS module, walks up from there.
17346
+ * 4. process.cwd() as last resort.
17213
17347
  *
17214
- * Robust across bun (src/main.ts) and node (dist/main.js) launch paths.
17348
+ * Robust across relocated hooks, bun (src/main.ts), and node (dist/main.js).
17215
17349
  */
17216
17350
  function packageRoot() {
17351
+ const explicit = explicitPackageRoot();
17352
+ if (explicit) return explicit;
17217
17353
  const entryPath = typeof process$1?.argv?.[1] === "string" ? process$1.argv[1] : void 0;
17218
17354
  if (entryPath) {
17219
17355
  const fromEntry = findPackageRoot(path.dirname(entryPath));
@@ -18470,7 +18606,7 @@ function logAudit$1(record) {
18470
18606
  try {
18471
18607
  const fs = await import("node:fs/promises");
18472
18608
  const path = await import("node:path");
18473
- const { PATHS } = await import("./paths-BbHtQAOs.js");
18609
+ const { PATHS } = await import("./paths-CV9K7Xqm.js");
18474
18610
  const dir = path.join(PATHS.APP_DIR, "browser-mcp");
18475
18611
  await fs.mkdir(dir, { recursive: true });
18476
18612
  const line = JSON.stringify({
@@ -22715,7 +22851,7 @@ const EMPTY_USAGE = {
22715
22851
  total: 0
22716
22852
  }
22717
22853
  };
22718
- const DEFAULT_MODEL$1 = {
22854
+ const DEFAULT_MODEL = {
22719
22855
  id: "unknown",
22720
22856
  name: "unknown",
22721
22857
  api: "unknown",
@@ -22737,7 +22873,7 @@ function createMutableAgentState(initialState) {
22737
22873
  let messages = initialState?.messages?.slice() ?? [];
22738
22874
  return {
22739
22875
  systemPrompt: initialState?.systemPrompt ?? "",
22740
- model: initialState?.model ?? DEFAULT_MODEL$1,
22876
+ model: initialState?.model ?? DEFAULT_MODEL,
22741
22877
  thinkingLevel: initialState?.thinkingLevel ?? "off",
22742
22878
  get tools() {
22743
22879
  return tools;
@@ -23462,18 +23598,174 @@ function resolveModelAndThinking(opts) {
23462
23598
  if (!clamp) clamp = allowed[0];
23463
23599
  return mkOk(clamp);
23464
23600
  }
23601
+ const CATALOG_PRICE_SCALE = 1e9;
23602
+ const TOKENS_PER_MILLION = 1e6;
23603
+ /**
23604
+ * Last-resort per-1M-token prices, recorded from the live catalog on
23605
+ * 2026-08-12. The LIVE catalog always wins; this only fills in when
23606
+ * `state.models` is unpopulated, which in practice means the startup catalog
23607
+ * fetch failed. Without it the injected roster degrades to bare names and the
23608
+ * model loses the cost signal entirely for that session.
23609
+ *
23610
+ * A hardcoded copy of a value that HAS a live source is a second source of
23611
+ * truth, and this one has already been observed to drift: two figures written
23612
+ * from memory into a commit message (`gpt-5.3-codex` 400/1600, `gpt-5.5`
23613
+ * 500/2000) were both wrong against the live catalog (175/1400 and 500/3000).
23614
+ * That is exactly the silent-misroute failure this table risks, so
23615
+ * `warnOnTokenPriceDrift()` compares it against the live catalog once at
23616
+ * startup and logs any disagreement rather than letting a stale number sit
23617
+ * here indefinitely.
23618
+ *
23619
+ * This is NOT the same trade as `INDICATIVE_TOKENS_PER_SECOND`: throughput
23620
+ * cannot be derived from the catalog at all, so hardcoding is the only option
23621
+ * there. Price can, so hardcoding is strictly a degraded fallback.
23622
+ */
23623
+ const FALLBACK_TOKEN_PRICES = Object.freeze({
23624
+ "gpt-5.6-luna": {
23625
+ in: 20,
23626
+ out: 120
23627
+ },
23628
+ "gpt-5.6-terra": {
23629
+ in: 200,
23630
+ out: 1200
23631
+ },
23632
+ "gpt-5.4-mini": {
23633
+ in: 75,
23634
+ out: 450
23635
+ },
23636
+ "claude-sonnet-5": {
23637
+ in: 200,
23638
+ out: 1e3
23639
+ },
23640
+ "gpt-5.3-codex": {
23641
+ in: 175,
23642
+ out: 1400
23643
+ },
23644
+ "claude-haiku-4.5": {
23645
+ in: 100,
23646
+ out: 500
23647
+ },
23648
+ "claude-opus-5": {
23649
+ in: 500,
23650
+ out: 2500
23651
+ },
23652
+ "gpt-5.6-sol": {
23653
+ in: 500,
23654
+ out: 3e3
23655
+ },
23656
+ "grok-4.5": {
23657
+ in: 200,
23658
+ out: 600
23659
+ },
23660
+ "gpt-5.5": {
23661
+ in: 500,
23662
+ out: 3e3
23663
+ },
23664
+ "gemini-3.6-flash": {
23665
+ in: 150,
23666
+ out: 750
23667
+ },
23668
+ "gemini-3.5-flash": {
23669
+ in: 150,
23670
+ out: 900
23671
+ },
23672
+ "gemini-3.1-pro-preview": {
23673
+ in: 200,
23674
+ out: 1200
23675
+ }
23676
+ });
23677
+ /**
23678
+ * Compare every `FALLBACK_TOKEN_PRICES` entry against the live catalog and warn
23679
+ * on disagreement. Call once after the catalog is populated. Makes fallback
23680
+ * staleness VISIBLE instead of silent: a stale entry only ever surfaces on the
23681
+ * degraded path, where nobody is looking, so without this it could be wrong for
23682
+ * months. Warn-only by design — a price mismatch must never block a launch.
23683
+ */
23684
+ function warnOnTokenPriceDrift() {
23685
+ for (const [id, hardcoded] of Object.entries(FALLBACK_TOKEN_PRICES)) {
23686
+ const live = livePricesFor(id);
23687
+ if (!live) continue;
23688
+ if (live.in !== hardcoded.in || live.out !== hardcoded.out) consola.warn(`[model-resolve] FALLBACK_TOKEN_PRICES is stale for ${id}: hardcoded ${hardcoded.in}/${hardcoded.out}, live catalog ${live.in}/${live.out}. Update the table in src/lib/worker-agent/model-resolve.ts.`);
23689
+ }
23690
+ }
23691
+ /** Live-catalog price lookup with no fallback. Split out so the drift check can
23692
+ * compare against the catalog without the fallback masking a disagreement. */
23693
+ function livePricesFor(modelId) {
23694
+ const prices = state.models?.data.find((model) => model.id === modelId)?.billing?.token_prices;
23695
+ if (!prices || typeof prices.batch_size !== "number" || !Number.isSafeInteger(prices.batch_size) || prices.batch_size <= 0 || typeof prices.input_price !== "number" || !Number.isFinite(prices.input_price) || prices.input_price < 0 || typeof prices.output_price !== "number" || !Number.isFinite(prices.output_price) || prices.output_price < 0) return;
23696
+ const toPerMillion = (price) => price / CATALOG_PRICE_SCALE * TOKENS_PER_MILLION / prices.batch_size;
23697
+ return {
23698
+ in: toPerMillion(prices.input_price),
23699
+ out: toPerMillion(prices.output_price)
23700
+ };
23701
+ }
23702
+ /**
23703
+ * A model's per-1M-token prices: live catalog first, then the dated fallback
23704
+ * table. Still returns undefined for a model in neither, so a caller never
23705
+ * mistakes a guess for a fact — the fallback covers models we have actually
23706
+ * recorded, not every id.
23707
+ */
23708
+ function catalogTokenPrices(modelId) {
23709
+ return livePricesFor(modelId) ?? FALLBACK_TOKEN_PRICES[modelId];
23710
+ }
23711
+ /**
23712
+ * Approximate output tokens/sec, median of n=3 per model, measured 2026-08-12
23713
+ * through this proxy. Reproduce with `bun scripts/bench-model-speed.ts` — the
23714
+ * harness is committed precisely so these numbers can be re-derived and
23715
+ * challenged instead of being trusted. Rounded coarsely on purpose: run-to-run
23716
+ * variance is large (`gpt-5.6-sol` measured 22 in an early n=1 pass and 74 at
23717
+ * n=3), so any digit beyond the leading one or two would be false precision.
23718
+ *
23719
+ * Wall clock includes time-to-first-token, which is why an early n=1 pass put
23720
+ * `gemini-3.1-pro-preview` at 9: that response emitted only 66 tokens, so TTFT
23721
+ * dominated. Reasoning tokens are timed but may not appear in `output_tokens`,
23722
+ * so heavy-reasoning models are penalised here.
23723
+ *
23724
+ * This is a deliberately hardcoded, coarse speed hint, indicative and never a
23725
+ * per-call benchmark: a recoverable speed retry is safer than a quality score
23726
+ * that silently misroutes.
23727
+ *
23728
+ * NOT the whole picture for agent work. The benchmark also measures p50 latency
23729
+ * to a trivial tool call, which is the workload an agent model actually spends
23730
+ * its turns on, and the ordering differs from raw generation: `gpt-5.6-sol`
23731
+ * generates at 75 but takes ~4.3s to reach a tool call, while `gpt-5.6-luna`
23732
+ * takes ~0.9s. That figure is deliberately NOT surfaced to the model, because a
23733
+ * second speed axis invites optimising a routing choice that policy already
23734
+ * settles (see the decorrelation note below).
23735
+ */
23736
+ const INDICATIVE_TOKENS_PER_SECOND = Object.freeze({
23737
+ "gpt-5.6-luna": 120,
23738
+ "gpt-5.6-terra": 100,
23739
+ "gpt-5.4-mini": 100,
23740
+ "claude-sonnet-5": 100,
23741
+ "gpt-5.3-codex": 85,
23742
+ "claude-haiku-4.5": 85,
23743
+ "claude-opus-5": 80,
23744
+ "gpt-5.6-sol": 75,
23745
+ "grok-4.5": 70,
23746
+ "gpt-5.5": 65,
23747
+ "gemini-3.6-flash": 45,
23748
+ "gemini-3.5-flash": 40,
23749
+ "gemini-3.1-pro-preview": 25
23750
+ });
23751
+ /** Returns the approximate, indicative output speed when it was measured. */
23752
+ function indicativeTokensPerSecond(modelId) {
23753
+ return INDICATIVE_TOKENS_PER_SECOND[modelId];
23754
+ }
23465
23755
  /** Worker-usable models need a big enough window to be worth delegating to. */
23466
23756
  const CATALOG_MIN_CONTEXT = 2e5;
23467
23757
  /**
23468
23758
  * Derived view of the live catalog: every model a worker could actually be
23469
23759
  * pointed at, with the metadata needed to choose between them.
23470
23760
  *
23471
- * DERIVED ONLY, and that is the whole design. A one-liner like "strong
23761
+ * Derived facts only, with one explicitly-labelled exception:
23762
+ * `INDICATIVE_TOKENS_PER_SECOND` is a dated, coarse measurement whose speed
23763
+ * signal is recoverable by retrying a slow selection. A one-liner like "strong
23472
23764
  * reasoning, weak long-context recall" cannot be computed from catalog
23473
23765
  * metadata — it is editorial, it goes stale silently as vendors ship, and the
23474
23766
  * asymmetry is brutal: a MISSING characterization costs one suboptimal pick
23475
23767
  * the model recovers from, while a WRONG one misroutes invisibly at the call
23476
- * site. So this ships facts and lets the caller judge.
23768
+ * site. So this ships facts, the recoverable speed hint, and no quality score.
23477
23769
  *
23478
23770
  * It exists because the hardcoded chains cannot discover anything. Models are
23479
23771
  * live in the catalog that appear nowhere in `src/` — nobody evaluated them
@@ -23499,13 +23791,16 @@ function buildCatalogView() {
23499
23791
  if (ctx < CATALOG_MIN_CONTEXT) continue;
23500
23792
  const efforts = (supports.reasoning_effort ?? []).filter((effort) => WORKER_THINKING_LEVELS.includes(effort));
23501
23793
  if (efforts.length === 0) continue;
23794
+ const prices = catalogTokenPrices(model.id);
23795
+ const tps = indicativeTokensPerSecond(model.id);
23502
23796
  rows.push({
23503
23797
  id: model.id,
23504
23798
  vendor: model.vendor,
23505
23799
  ctx,
23506
23800
  ...limits?.max_output_tokens ? { maxOut: limits.max_output_tokens } : {},
23507
23801
  efforts,
23508
- ...model.model_picker_price_category ? { cost: model.model_picker_price_category } : {}
23802
+ ...prices ?? {},
23803
+ ...tps === void 0 ? {} : { tps }
23509
23804
  });
23510
23805
  }
23511
23806
  return rows.sort((a, b) => a.id.localeCompare(b.id));
@@ -26501,13 +26796,22 @@ function geminiAvailable(source = state) {
26501
26796
  /**
26502
26797
  * First id in `chain` that is present in the live catalog. With
26503
26798
  * `requireToolCalls`, skips an entry whose catalog record does not advertise
26504
- * `tool_calls` (strict `!== true`, so absent metadata fails closed). Returns
26505
- * undefined when the catalog is unavailable or nothing in the chain matches, so
26506
- * every caller degrades gracefully rather than throwing on a thin catalog.
26799
+ * `tool_calls` (strict `!== true`, so absent metadata fails closed). With
26800
+ * `minContextTokens`, skips an entry whose advertised context window is below
26801
+ * that floor (absent metadata likewise fails closed). Returns undefined when
26802
+ * the catalog is unavailable or nothing in the chain matches, so every caller
26803
+ * degrades gracefully rather than throwing on a thin catalog.
26507
26804
  *
26508
26805
  * Extracted from `resolveOpenAiFrontier` so the per-agent resolvers below share
26509
26806
  * one walk instead of hand-copying it. Ids are matched EXACTLY against
26510
26807
  * `catalog.id` — no slug translation, matching the pre-existing behavior.
26808
+ *
26809
+ * `minContextTokens` is OPT-IN because the constraint is genuinely per-agent:
26810
+ * the conditional cheaper-tier agents promise 1M end to end. Enforcing the
26811
+ * floor here rather than by comment is what stops a chain silently degrading
26812
+ * when an id's advertised window shrinks upstream — `withOneMSuffix` would then
26813
+ * just omit the `[1m]` bracket, and the agent would be budgeted at Claude Code's
26814
+ * 200K default with no signal that anything changed.
26511
26815
  */
26512
26816
  function firstPresentInCatalog(chain, opts) {
26513
26817
  const models = state.models?.data;
@@ -26516,6 +26820,7 @@ function firstPresentInCatalog(chain, opts) {
26516
26820
  const found = models.find((m) => m.id === id);
26517
26821
  if (!found) continue;
26518
26822
  if (opts?.requireToolCalls && found.capabilities?.supports?.tool_calls !== true) continue;
26823
+ if (opts?.minContextTokens != null && (found.capabilities?.limits?.max_context_window_tokens ?? 0) < opts.minContextTokens) continue;
26519
26824
  return id;
26520
26825
  }
26521
26826
  }
@@ -26595,23 +26900,65 @@ function scribeModel() {
26595
26900
  * caller drop the agent instead, so the lead falls back to the CLI's `Explore`
26596
26901
  * (same behavior as before `scout` existed) rather than to an expensive
26597
26902
  * impostor wearing the cheap agent's name.
26903
+ *
26904
+ * `gpt-5.6-luna` leads because it is the cheapest 1M-context model in the
26905
+ * catalog; `gemini-3.6-flash` remains the cross-vendor fallback so an OpenAI-side
26906
+ * outage does not remove the scout. Both entries must continue advertising at
26907
+ * least 1M context so Claude Code's `[1m]` accounting remains honest if an
26908
+ * upstream catalog entry shrinks.
26909
+ *
26910
+ * This chain deliberately uses literal ids rather than `EXPLORE_DEFAULT_MODEL`:
26911
+ * the explore worker default and scout's cross-vendor fallback are independent
26912
+ * policies, so retuning one must not silently collapse the other. There is no
26913
+ * 400K last resort. On a catalog carrying neither chain member, `scout` is
26914
+ * dropped rather than inheriting the lead or presenting a narrower-context agent.
26598
26915
  */
26916
+ const SCOUT_MODEL_CHAIN = Object.freeze(["gpt-5.6-luna", "gemini-3.6-flash"]);
26599
26917
  function scoutModel() {
26600
- return firstPresentInCatalog([EXPLORE_DEFAULT_MODEL, DEFAULT_MODEL], { requireToolCalls: true });
26918
+ return firstPresentInCatalog(SCOUT_MODEL_CHAIN, {
26919
+ requireToolCalls: true,
26920
+ minContextTokens: ONE_M_TOKENS
26921
+ });
26922
+ }
26923
+ /** Model for `implementer-fast` — the cheaper implementation tier. Absent →
26924
+ * the agent is dropped.
26925
+ *
26926
+ * `gpt-5.6-sol` is deliberately NOT in this chain: changes needing frontier
26927
+ * judgment already belong to `implementer`, while this agent handles
26928
+ * well-specified, mechanical changes at a lower tier. Both entries are 1M+;
26929
+ * their different speed and effort properties stay out of shared claims. */
26930
+ function implementerFastModel() {
26931
+ return firstPresentInCatalog(["gpt-5.6-terra", REVIEW_DEFAULT_MODEL], {
26932
+ requireToolCalls: true,
26933
+ minContextTokens: ONE_M_TOKENS
26934
+ });
26935
+ }
26936
+ /** Model for `general-purpose-fast` — the fast, cheapest catch-all. Absent →
26937
+ * dropped.
26938
+ *
26939
+ * Single-entry by design. `gpt-5.6-luna` is the cheapest model in the live
26940
+ * catalog and measured fastest among the catch-all candidates, while carrying
26941
+ * 1.05M context and the full `none..max` effort ladder. No
26942
+ * `-mini`/`-lite`/`-haiku` model in the catalog serves 1M, which is why this
26943
+ * catch-all uses a `gpt-5.6-*` slug rather than a mini one. */
26944
+ function generalPurposeFastModel() {
26945
+ return firstPresentInCatalog(["gpt-5.6-luna"], {
26946
+ requireToolCalls: true,
26947
+ minContextTokens: ONE_M_TOKENS
26948
+ });
26601
26949
  }
26602
26950
  /**
26603
26951
  * Gate for the worker tools (`explore`, `review`, `implement`).
26604
26952
  *
26605
26953
  * Returns true iff BOTH:
26606
- * 1. Copilot's live catalog (`state.models?.data`) contains the
26607
- * worker default model (`gpt-5.4-mini`, used by explore)
26608
- * AND that entry advertises `capabilities.supports.tool_calls ===
26609
- * true`. The worker loop is function-calling; a model that can't
26610
- * emit tool_calls is unusable, so dormant-register (omit from
26611
- * `tools/list`) keeps the surface honest. (The implement default
26612
- * `gpt-5.6-sol` is NOT gated here — if it's absent, implement calls
26613
- * surface a clean resolve error rather than disabling all worker
26614
- * tools, since explore/review still work.)
26954
+ * 1. Copilot's live catalog (`state.models?.data`) contains any model in the
26955
+ * ordered worker gate chain (`gpt-5.6-luna` → `gpt-5.4-mini`) and that
26956
+ * entry advertises `capabilities.supports.tool_calls === true`. Luna leads
26957
+ * on qualifying tiers; mini preserves the worker surface on individual
26958
+ * trial and education catalogs. The catalog is the entitlement signal.
26959
+ * The worker loop is function-calling, so a model without tool calls is
26960
+ * unusable. Per-mode defaults are NOT gated here — an absent mode default
26961
+ * surfaces a clean resolve error rather than disabling all worker tools.
26615
26962
  * 2. The operator hasn't set `GH_ROUTER_DISABLE_WORKER_TOOLS=1`
26616
26963
  * (opt-out — workers ship enabled by default per plan).
26617
26964
  *
@@ -26620,17 +26967,12 @@ function scoutModel() {
26620
26967
  * validation in the engine, which surfaces a clean `isError`
26621
26968
  * envelope with the catalog's eligible model ids on mismatch.
26622
26969
  *
26623
- * `WORKER_DEFAULT_MODEL` is imported (aliased from `DEFAULT_MODEL`)
26624
- * from `src/lib/worker-agent` so the engine owns the single source
26625
- * of truth.
26970
+ * `WORKER_DEFAULT_MODEL_CHAIN` is imported from `src/lib/worker-agent` so the
26971
+ * engine owns the single source of truth for both gating and fallback order.
26626
26972
  */
26627
26973
  function workerToolsEnabled() {
26628
26974
  if (process.env.GH_ROUTER_DISABLE_WORKER_TOOLS === "1") return false;
26629
- const models = state.models?.data;
26630
- if (!models) return false;
26631
- const found = models.find((m) => m.id === DEFAULT_MODEL);
26632
- if (!found) return false;
26633
- return found.capabilities?.supports?.tool_calls === true;
26975
+ return firstPresentInCatalog(DEFAULT_MODEL_CHAIN, { requireToolCalls: true }) != null;
26634
26976
  }
26635
26977
  /**
26636
26978
  * Gate for the compound L2 browser tools (`browser_act`, `browser_observe`,
@@ -26737,10 +27079,10 @@ function artifactToolsEnabled() {
26737
27079
  * browser is on disk. The browse agent drives the SAME Chrome/Edge
26738
27080
  * bridge as the raw `browser_*` tools, so it can't be useful without
26739
27081
  * that surface enabled.
26740
- * 2. The browse default model (`BROWSE_DEFAULT_MODEL`, `gpt-5.4-mini`)
27082
+ * 2. The browse default model (`BROWSE_DEFAULT_MODEL`, `gpt-5.6-luna`)
26741
27083
  * is in Copilot's live catalog AND `pickEndpoint()` resolves a
26742
27084
  * reachable endpoint for it. Unlike `workerToolsEnabled()` (which
26743
- * checks `tool_calls` on the gemini default), the browse default is
27085
+ * checks `tool_calls` on the shared gate sentinel), the browse default is
26744
27086
  * a `/responses`-only gpt-5.x model — `pickEndpoint` is the right
26745
27087
  * reachability probe (it returns undefined only when the model
26746
27088
  * serves neither chat nor responses).
@@ -31493,32 +31835,33 @@ async function saveOverflowPatch(dir) {
31493
31835
  */
31494
31836
  const WORKTREE_REGISTRY = new WorktreeRegistry();
31495
31837
  registerExitHandlers$1(WORKTREE_REGISTRY);
31496
- /** Worker-availability GATE sentinel + final fallback. `gpt-5.4-mini` cheap,
31497
- * broadly-available, tool-call-capable, 400k-context, with tight
31498
- * function-calling-loop discipline (earlier gemini-flash cheap defaults
31499
- * early-stopped with empty turns on the function-calling loop; gpt-5.4-mini
31500
- * does not). Exported and aliased as `WORKER_DEFAULT_MODEL`:
31501
- * `workerToolsEnabled()` gates the ENTIRE worker surface on this id being
31502
- * present with `tool_calls`. It is no longer `explore`'s default (see
31503
- * `EXPLORE_DEFAULT_MODEL`) it stays the gate sentinel because it's the
31504
- * cheapest broadly-present tool-caller, and the fallback for any unmatched
31505
- * mode. */
31506
- const DEFAULT_MODEL = "gpt-5.4-mini";
31838
+ /** Worker-availability gate + unmatched-mode fallback chain. Luna leads where
31839
+ * the live catalog grants access: it is cheaper, faster, and has a larger context
31840
+ * window than mini. Mini remains the broad-tier fallback because individual-trial
31841
+ * and education catalogs may omit Luna. The catalog itself is the entitlement
31842
+ * signal; `billing.restricted_to` describes model policy, not the user's tier.
31843
+ *
31844
+ * `workerToolsEnabled()` admits the worker surface when either entry is present
31845
+ * with `tool_calls`. `resolveDefaultModel()` picks the first usable live entry for
31846
+ * an unmatched worker mode. Per-mode defaults remain independent of the gate. */
31847
+ const DEFAULT_MODEL_CHAIN = Object.freeze(["gpt-5.6-luna", "gpt-5.4-mini"]);
31507
31848
  const DEFAULT_THINKING = "xhigh";
31508
- /** Default model for the READ-ONLY `explore` mode. `gemini-3.6-flash` at `high`
31509
- * (via `EXPLORE_DEFAULT_THINKING`; flash advertises no xhigh) — a fast, cheap,
31510
- * 1M-context tool-caller for read-only repo research. Routes over
31511
- * `/chat/completions` via the translation shim (the same proven path the
31512
- * `review` worker uses for gemini). Like `implement`'s gpt-5.6-sol this is NOT a
31513
- * `workerToolsEnabled` gate input if absent (e.g. a non-enterprise tier)
31514
- * `explore` errors helpfully at call time rather than vanishing the whole worker
31515
- * surface. The caller (the main model) overrides BOTH the model and the reasoning
31516
- * per call via the `model` / `thinking` args see the tier ladder (gpt-5.6-sol
31517
- * heavy / gpt-5.6-terra moderate / gemini-3.6-flash light) in the MCP tool desc. */
31518
- const EXPLORE_DEFAULT_MODEL = "gemini-3.6-flash";
31519
- /** Default thinking for `explore`. `high` (flash has no xhigh); explicit rather
31520
- * than inherited from `DEFAULT_THINKING` so the explore effort can't drift if the
31521
- * shared fallback changes. */
31849
+ function resolveDefaultModel() {
31850
+ const models = state.models?.data ?? [];
31851
+ return DEFAULT_MODEL_CHAIN.find((id) => models.some((model) => model.id === id && model.capabilities?.supports?.tool_calls === true)) ?? DEFAULT_MODEL_CHAIN[0];
31852
+ }
31853
+ /** Default model for the READ-ONLY `explore` mode. `gpt-5.6-luna` at `high`
31854
+ * (via `EXPLORE_DEFAULT_THINKING`) is the measured strict improvement over the
31855
+ * former Gemini Flash default: lower token cost, faster generation and tool-call
31856
+ * latency, a larger context window, and the full reasoning-effort ladder. `high`
31857
+ * is therefore a real selected tier rather than a clamp. Like `implement`'s
31858
+ * gpt-5.6-sol this per-mode default is NOT a `workerToolsEnabled` gate input — if
31859
+ * absent on a thin catalog, `explore` errors helpfully at call time rather than
31860
+ * vanishing the whole worker surface. The caller can override model and thinking
31861
+ * per call via the `model` / `thinking` args. */
31862
+ const EXPLORE_DEFAULT_MODEL = "gpt-5.6-luna";
31863
+ /** Default thinking for `explore`. Explicit rather than inherited from
31864
+ * `DEFAULT_THINKING` so the explore effort cannot drift with the fallback. */
31522
31865
  const EXPLORE_DEFAULT_THINKING = "high";
31523
31866
  /** Default model + thinking for the READ-ONLY `review` mode.
31524
31867
  * `gemini-3.1-pro-preview` at `xhigh` (clamped to `high` at call time — gemini
@@ -31535,41 +31878,44 @@ const EXPLORE_DEFAULT_THINKING = "high";
31535
31878
  const REVIEW_DEFAULT_MODEL = "gemini-3.1-pro-preview";
31536
31879
  const REVIEW_DEFAULT_THINKING = "xhigh";
31537
31880
  /** Default model + thinking for the READ+WRITE `implement` mode. `gpt-5.6-sol`
31538
- * at `xhigh` — the strongest reasoning tier in the catalog, 1M+ context,
31539
- * routed through `/responses` by the stream-fn endpoint split. Coding edits
31540
- * benefit from maximum reasoning; the higher per-call cost is justified for
31541
- * autonomous implementation. An explicit `opts.model` still wins. */
31881
+ * at `high` — a time-to-outcome default for the 1M+ context model, routed
31882
+ * through `/responses` by the stream-fn endpoint split. Any caller can restore
31883
+ * a higher tier per call via `thinking` or per session via `worker_defaults`;
31884
+ * precedence is per-call > session > built-in. */
31542
31885
  const IMPLEMENT_DEFAULT_MODEL = "gpt-5.6-sol";
31543
- const IMPLEMENT_DEFAULT_THINKING = "xhigh";
31544
- /** `test` starts with the same built-in pair as `implement`, but remains an
31545
- * independent mode so either can be overridden without affecting the other. */
31886
+ const IMPLEMENT_DEFAULT_THINKING = "high";
31887
+ /** `test` starts with the same time-to-outcome built-in pair as `implement`, but
31888
+ * remains independent so either mode can restore a higher tier per call via
31889
+ * `thinking` or per session via `worker_defaults`. Resolution precedence is
31890
+ * per-call > session > built-in. */
31546
31891
  const TEST_DEFAULT_MODEL = "gpt-5.6-sol";
31547
- const TEST_DEFAULT_THINKING = "xhigh";
31548
- /** Default model for `browse` mode. `gpt-5.4-mini` the Gate-B-winning
31549
- * browse model (small + fast enough to drive a tab at human pace, with
31550
- * enough tool-calling discipline to terminate). This is DISTINCT from the
31551
- * gemini worker `DEFAULT_MODEL`: browse is a different workload (drive a
31552
- * page, not read a repo) and was tuned separately. May be retuned after
31553
- * the flash-vs-mini eval settles. Routed through `/responses` by the
31554
- * stream-fn's endpoint split (it's a gpt-5.x model). Caller can override
31892
+ const TEST_DEFAULT_THINKING = "high";
31893
+ /** Default model for `browse` mode. `gpt-5.6-luna` has the same measured image
31894
+ * ceiling as `gpt-5.4-mini`, so screenshot-heavy sessions retain their input
31895
+ * capacity, and endpoint routing is derived from the live catalog. Luna's full
31896
+ * reasoning-effort ladder preserves the independent `high` browse default.
31897
+ * This is deliberately a per-mode default even though it also leads
31898
+ * `DEFAULT_MODEL_CHAIN`; the general worker gate remains tier-adaptive while
31899
+ * browse still applies its independent reachability gate. Caller can override
31555
31900
  * per call via the `model` arg.
31556
31901
  *
31557
31902
  * Exported so the MCP browse handler reads the same constant — drift
31558
31903
  * between the two would ship a tool whose docs disagree with its runtime
31559
31904
  * default. */
31560
- const BROWSE_DEFAULT_MODEL = "gpt-5.4-mini";
31905
+ const BROWSE_DEFAULT_MODEL = "gpt-5.6-luna";
31561
31906
  /** Default thinking for `browse`. Higher than the page-driving workload
31562
31907
  * strictly needs, but the termination discipline benefits from it. */
31563
31908
  const BROWSE_DEFAULT_THINKING = "high";
31564
- /** Default model + thinking for the read-only `plan` mode. `claude-opus-4.8`
31565
- * at `xhigh` planning is the highest-leverage read-only step (the plan
31566
- * shapes everything downstream), so it gets the strongest reasoning model
31567
- * rather than the lightweight `gemini-3.6-flash` explore default. Uses the DOTTED
31568
- * Copilot catalog id (the worker resolver exact-matches `catalog.id`, it does
31569
- * NOT translate the Anthropic dashed slug; `claude-opus-5` is a single-segment
31570
- * slug so dotted == dashed). Falls back to a helpful unknown-model error at call
31571
- * time if opus-5 isn't in the catalog (e.g. a non-enterprise tier), exactly like
31572
- * `implement`'s `gpt-5.6-sol`. Caller's `model` arg still wins. */
31909
+ /** Default model + thinking for the read-only `plan` mode. `claude-opus-5`
31910
+ * at `high` favours time-to-outcome while retaining the strongest planning
31911
+ * model rather than the lightweight `gpt-5.6-luna` explore default. Any
31912
+ * caller can restore a higher tier per call via `thinking` or per session via
31913
+ * `worker_defaults`; precedence is per-call > session > built-in. Uses the
31914
+ * DOTTED Copilot catalog id (the worker resolver exact-matches `catalog.id`, it
31915
+ * does NOT translate the Anthropic dashed slug; `claude-opus-5` is a
31916
+ * single-segment slug so dotted == dashed). Falls back to a helpful unknown-model
31917
+ * error at call time if opus-5 isn't in the catalog (e.g. a non-enterprise tier),
31918
+ * exactly like `implement`'s `gpt-5.6-sol`. */
31573
31919
  const PLAN_DEFAULT_MODEL = "claude-opus-5";
31574
31920
  const BUILT_IN_MODE_DEFAULTS = Object.freeze({
31575
31921
  explore: {
@@ -31582,7 +31928,7 @@ const BUILT_IN_MODE_DEFAULTS = Object.freeze({
31582
31928
  },
31583
31929
  plan: {
31584
31930
  model: PLAN_DEFAULT_MODEL,
31585
- thinking: "xhigh"
31931
+ thinking: "high"
31586
31932
  },
31587
31933
  implement: {
31588
31934
  model: IMPLEMENT_DEFAULT_MODEL,
@@ -31597,10 +31943,10 @@ const BUILT_IN_MODE_DEFAULTS = Object.freeze({
31597
31943
  thinking: BROWSE_DEFAULT_THINKING
31598
31944
  }
31599
31945
  });
31600
- /** Resolve the effective mode ladder without changing the gate sentinel. */
31946
+ /** Resolve the effective mode ladder without changing the worker gate. */
31601
31947
  function resolveModeDefaults(mode, ignoreSessionDefaults = false) {
31602
31948
  const builtIn = BUILT_IN_MODE_DEFAULTS[mode] ?? {
31603
- model: "gpt-5.4-mini",
31949
+ model: resolveDefaultModel(),
31604
31950
  thinking: DEFAULT_THINKING
31605
31951
  };
31606
31952
  const override = ignoreSessionDefaults ? {} : getWorkerSessionDefault(mode);
@@ -33652,7 +33998,7 @@ const PERSONAS_READ = Object.freeze([
33652
33998
  toolNameHttp: "codex_reviewer",
33653
33999
  model: "gpt-5.3-codex",
33654
34000
  endpoint: "/v1/responses",
33655
- description: "Line-level code reviewer backed by gpt-5.3-codex (OpenAI, ≈272K-token input window), a code-specialist reviewer that is fastest around high effort (~16s at high effort). It reviews concrete diffs, files, or function bodies and returns findings with severity, file:line locations, issue impact, and a minimal suggested fix. Use when the artifact is actual code and the goal is bug, edge-case, security, concurrency, resource, or idiom review. Not for architecture or tradeoff review, use codex_critic or gemini_critic; pass the diff or file content verbatim.",
34001
+ description: "Line-level code reviewer backed by gpt-5.3-codex (OpenAI, ≈272K-token input window), a code specialist for line-level review. It reviews concrete diffs, files, or function bodies and returns findings with severity, file:line locations, issue impact, and a minimal suggested fix. Use when the artifact is actual code and the goal is bug, edge-case, security, concurrency, resource, or idiom review. Not for architecture or tradeoff review, use codex_critic or gemini_critic; pass the diff or file content verbatim.",
33656
34002
  baseInstructions: REVIEWER_BASE,
33657
34003
  agentPrompt: "",
33658
34004
  writeCapable: false,
@@ -33843,8 +34189,9 @@ function buildPeerAwarenessSnippet(opts) {
33843
34189
  criticList.push("`opus_critic` (Opus 5)");
33844
34190
  const codexCliClause = opts.codexCli ? " `mcp__codex-cli__codex` dispatches to `codex-implementer` (gpt-5.3-codex with workspace-write) for end-to-end coding tasks." : "";
33845
34191
  const para2Parts = [`\`mcp__${searchKey}__code\` is the one-stop code search (no extra model call). Its DEFAULT mode (or \`mode:"semantic"\`) ranks by MEANING via ColBERT over a per-workspace index, the first thing to reach for on intent/concept questions ("where is retry/backoff handled", "how does auth work"); when that index isn't ready it transparently falls back to lexical (the response \`source\` says which engine ran). Forced modes cover the rest: \`lexical\` (BM25F-ranked + tree-sitter, best for exact symbols), \`exact\`, \`regex\`, \`complete\` (exhaustive set), \`ast_pattern\`+\`ast_lang\` for multi-line AST shapes, \`scan\` for a whole-workspace symbol outline, \`multiline\` for cross-line regex. Multiple queries can run in a single turn. The index covers code-shaped files; for unstructured files (logs, \`.csv\`, \`.env*\`, config-only wiring), \`grep\`/\`glob\` still apply.`];
33846
- if (opts.workerToolsAvailable) para2Parts.push(`\`worker-*\` are background Agent subagents (subagent_type) that run the matching worker in its own context and deliver the result as a completion notification, so a long run never blocks the turn: \`worker-explore\` (read-only research), \`worker-review\` (reads the code to verify a change or claim), \`worker-plan\` (ordered implementation plan), \`worker-implement\` (edit/write/bash; ALWAYS runs in an isolated git worktree and returns the diff via a saved patch file; for in-place edits use the \`implementer\` subagent), \`worker-test\` (independent test author; also always worktree-isolated). The raw \`mcp__${workersKey}__*\` tools they call are guarded (a direct main-thread call is redirected to the matching agent); Workers themselves have \`code_search\`.`);
33847
- para2Parts.push(`Native subagents (Task), each in its own context so heavy work never fills yours: \`implementer\` (you know what to build), \`reviewer\` (something exists and you want it assessed, including reproducing and root-causing a failure), \`brainstorm\` (you do not yet know which approach to take)${opts.scoutAvailable === false ? "" : ", `scout` (find or understand something in the repo, cheap)"}, \`scribe\` (docs and ADRs that trail the code).`);
34192
+ if (opts.workerToolsAvailable) para2Parts.push(`\`worker-*\` are background Agent subagents (subagent_type) that run the matching worker in its own context and deliver the result as a completion notification, so a long run never blocks the turn: \`worker-explore\` (read-only research), \`worker-review\` (reads the code to verify a change or claim), \`worker-plan\` (ordered implementation plan), \`worker-implement\` (edit/write/bash; ALWAYS runs in an isolated git worktree and returns the diff via a saved patch file; for in-place edits use the \`implementer\` subagent), \`worker-test\` (independent test author; also always worktree-isolated)${opts.browseAvailable ? ", `worker-browse` (autonomous browser agent driving a real browser)" : ""}. The raw \`mcp__${workersKey}__*\` tools they call are guarded (a direct main-thread call is redirected to the matching agent); Workers themselves have \`code_search\`.`);
34193
+ const catchAllClause = opts.generalPurposeFastAvailable === false ? "" : " Catch-all on a fast, economical non-lead model for work no specialist fits: `general-purpose-fast`.";
34194
+ para2Parts.push(`Native subagents (Task), each in its own context so heavy work never fills yours: \`implementer\` (coding changes needing judgment or with ambiguous scope)${opts.implementerFastAvailable === false ? "" : ", `implementer-fast` (well-specified, mechanical coding changes)"}, \`reviewer\` (something exists and you want it assessed, including reproducing and root-causing a failure), \`brainstorm\` (you do not yet know which approach to take)${opts.scoutAvailable === false ? "" : ", `scout` (find or understand something in the repo, cheap)"}, \`scribe\` (docs and ADRs that trail the code).${catchAllClause}`);
33848
34195
  if (opts.workerToolsAvailable) para2Parts.push(`For a bounded, well-scoped implementation, prefer the \`implementer\` subagent over \`worker-implement\`; reach for \`worker-implement\` only when you specifically need git-worktree isolation, parallel variants, or a throwaway experiment.`);
33849
34196
  if (opts.workerToolsAvailable) para2Parts.push(`\`mcp__${orchestrateKey}__decompose\` composes an open-ended ask into a typed, VERIFIED workflow IR (a strong driver decorrelated by a cross-lab critic, so the decompose step isn't a single point of failure), and \`mcp__${orchestrateKey}__run_workflow\` executes that IR through a frozen kernel delivering max(orchestrated, baseline) over a sealed executable gate, so it never ships worse than a plain single-model run. \`mcp__${orchestrateKey}__verify_workflow\` checks an IR's floor invariants before you run it, and \`mcp__${orchestrateKey}__attest_step\` audits that a finished run's producers were each checked by a different lab. They suit non-trivial, role-separated asks; a trivial ask does not need them.`);
33850
34197
  else para2Parts.push(`\`mcp__${orchestrateKey}__verify_workflow\` statically checks a workflow IR's floor invariants and \`mcp__${orchestrateKey}__attest_step\` audits a run's cross-lab lineage (the \`decompose\`/\`run_workflow\` composer + kernel need the worker backend, unavailable here).`);
@@ -33877,13 +34224,30 @@ function buildPeerAwarenessSnippet(opts) {
33877
34224
  */
33878
34225
  function buildPeerAwarenessSummary(opts) {
33879
34226
  const key = (g) => opts.groupKeys?.[g] ?? GROUP_META[g].preferredKey;
34227
+ const renderNative = (name) => {
34228
+ const modelId = opts.nativeAgentModels?.[name];
34229
+ if (!modelId) return `\`${name}\``;
34230
+ const prices = catalogTokenPrices(modelId);
34231
+ const tps = indicativeTokensPerSecond(modelId);
34232
+ if (!prices || tps == null) return `\`${name}\``;
34233
+ return `\`${name}\` ${prices.in}/${prices.out} ~${tps}t/s`;
34234
+ };
34235
+ const summaryNativeNames = [
34236
+ renderNative("implementer"),
34237
+ opts.implementerFastAvailable === false ? void 0 : renderNative("implementer-fast"),
34238
+ renderNative("reviewer"),
34239
+ renderNative("brainstorm"),
34240
+ opts.scoutAvailable === false ? void 0 : renderNative("scout"),
34241
+ renderNative("scribe"),
34242
+ opts.generalPurposeFastAvailable === false ? void 0 : renderNative("general-purpose-fast")
34243
+ ].filter((n) => n != null);
33880
34244
  const lines = [
33881
34245
  "## Injected capabilities (summary)",
33882
34246
  "",
33883
- `Native subagents (Task), each in its own context: \`implementer\` (you know what to build), \`reviewer\` (something exists and you want it assessed, including reproducing and root-causing a failure), \`brainstorm\` (you do not yet know which approach to take), \`scout\` (find or understand something in the repo, cheap), \`scribe\` (docs and ADRs that trail the code). They read the repo and can run things; the peer critics below cannot, so reach for \`reviewer\` when an assessment needs execution or repo context and for a critic when you already hold the artifact.`,
34247
+ `${summaryNativeNames.some((n) => /\d/.test(n)) ? "Native subagents (Task), own context. Cost is per 1M tokens in/out, tok/s approximate:" : "Native subagents (Task), each in its own context:"} ${summaryNativeNames.join(", ")}. Each agent's own description states when it applies. They read the repo and can run things; the peer critics below cannot, so reach for \`reviewer\` when an assessment needs execution or repo context and for a critic when you already hold the artifact.`,
33884
34248
  `A layer of MCP tools, background workers, and skills is injected into this session. Cross-lab peer critics under \`mcp__${key("peers")}__*\` (plus the \`peer-review-coordinator\` subagent) review plans and diffs adversarially, and Claude Code's built-in \`advisor\` catches approach drift. \`mcp__${key("search")}__code\` is meaning-first code search and \`mcp__${key("search")}__web\` returns citable web sources.`
33885
34249
  ];
33886
- if (opts.workerToolsAvailable) lines.push(`Background \`worker-*\` agents (explore, review, plan, implement, test) run delegated work in their own context without blocking your turn, and \`mcp__${key("orchestrate")}__*\` composes, verifies, and runs floor-raising workflows.`);
34250
+ if (opts.workerToolsAvailable) lines.push(`Background \`worker-*\` agents (explore, review, plan, implement, test${opts.browseAvailable ? ", browse" : ""}) run delegated work in their own context without blocking your turn, and \`mcp__${key("orchestrate")}__*\` composes, verifies, and runs floor-raising workflows.`);
33887
34251
  if (opts.standInAvailable) lines.push(`\`mcp__${key("decide")}__stand_in\` returns a three-lab consensus for a decision when the user is unavailable.`);
33888
34252
  if (opts.browseAvailable) lines.push(`\`mcp__${key("browser")}__*\` drives a real Chrome or Edge browser.`);
33889
34253
  if (opts.fleetAvailable) lines.push(`\`mcp__${key("fleet")}__*\` drives remote ai-or-die coding sessions.`);
@@ -34183,7 +34547,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
34183
34547
  toolNameHttp: "explore",
34184
34548
  group: "workers",
34185
34549
  capability: "worker",
34186
- description: "Runs as the background `worker-explore` agent. Dispatch via the Agent tool (subagent_type: worker-explore) so the turn is never blocked; the result arrives as a completion notification. Read-only investigation by an autonomous worker (Pi runtime; default model `gemini-3.6-flash` at high reasoning, override via the `model` arg with any Copilot-catalog model that advertises `tool_calls`). It has read, glob, grep, semantic-first code search, web search, fetch_url, advisor, update_plan, and read-only toolbelt tools, and it returns a single text answer. Use for bounded research, repo discovery, dependency investigation, or multi-file reading that would otherwise consume the lead context window. Not for implementation, test authoring, or verification of a concrete diff; use implement, test, or review for those scopes. Brief the investigation goal and constraints, not step-by-step tool semantics. Strictly read-only: it changes nothing on disk, and its returned text is the only artifact it produces — route to `implement` or `test` when a file actually needs to change. If the result is too large to relay it is truncated to a preview and the FULL text is written to a file, whose absolute path is in the returned text; read that file rather than re-running the worker.",
34550
+ description: "Runs as the background `worker-explore` agent. Dispatch via the Agent tool (subagent_type: worker-explore) so the turn is never blocked; the result arrives as a completion notification. Read-only investigation by an autonomous worker (Pi runtime; default model `gpt-5.6-luna` at high reasoning, override via the `model` arg with any Copilot-catalog model that advertises `tool_calls`). It has read, glob, grep, semantic-first code search, web search, fetch_url, advisor, update_plan, and read-only toolbelt tools, and it returns a single text answer. Use for bounded research, repo discovery, dependency investigation, or multi-file reading that would otherwise consume the lead context window. Not for implementation, test authoring, or verification of a concrete diff; use implement, test, or review for those scopes. Brief the investigation goal and constraints, not step-by-step tool semantics. Strictly read-only: it changes nothing on disk, and its returned text is the only artifact it produces — route to `implement` or `test` when a file actually needs to change. If the result is too large to relay it is truncated to a preview and the FULL text is written to a file, whose absolute path is in the returned text; read that file rather than re-running the worker.",
34187
34551
  inputSchema: {
34188
34552
  type: "object",
34189
34553
  required: ["prompt"],
@@ -34195,7 +34559,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
34195
34559
  },
34196
34560
  model: {
34197
34561
  type: "string",
34198
- description: "Optional Copilot catalog model id (defaults to gemini-3.6-flash). Must advertise tool_calls support; the engine emits an isError envelope listing the eligible catalog models on mismatch. Override by task weight: `gpt-5.6-sol` (heavy/deep), `gpt-5.6-terra` (moderate), `gemini-3.6-flash` (light/cheap) — all 1M context; pair with thinking:'high'."
34562
+ description: "Optional Copilot catalog model id (defaults to gpt-5.6-luna). Must advertise tool_calls support; the engine emits an isError envelope listing the eligible catalog models on mismatch. Override by task weight: `gpt-5.6-sol` (heavy/deep), `gpt-5.6-terra` (moderate), `gpt-5.6-luna` (light/cheap) — all 1M context; pair with thinking:'high'."
34199
34563
  },
34200
34564
  thinking: {
34201
34565
  type: "string",
@@ -34224,7 +34588,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
34224
34588
  toolNameHttp: "implement",
34225
34589
  group: "workers",
34226
34590
  capability: "worker",
34227
- description: "Runs as the background `worker-implement` agent. Dispatch via the Agent tool (subagent_type: worker-implement) so the turn is never blocked; the result arrives as a completion notification. Delegates a scoped coding task to an autonomous worker (Pi runtime; default model `gpt-5.6-sol` at xhigh reasoning, override via `model` with any Copilot-catalog model that advertises `tool_calls`). It has the explore read-only tools plus edit, write, bash, and codex_review, and it returns its final text with any changed files or worktree diff. Use for bounded implementation work that may take a while or benefits from isolated worker context. Not for pure research, planning, review, or independent test authoring; use explore, plan, review, or test for those scopes. ALWAYS runs in an isolated git worktree and returns the diff via a saved patch file (a `--stat` summary + a bounded preview + the patch path; a small diff is inlined in full) — it never edits your working tree, and it HARD-ERRORS if the workspace is not a git repository. For in-place edits, use the native `implementer` subagent. If the result is too large to relay it is truncated to a preview and the FULL text is written to a file, whose absolute path is in the returned text; read that file rather than re-running the worker.",
34591
+ description: "Runs as the background `worker-implement` agent. Dispatch via the Agent tool (subagent_type: worker-implement) so the turn is never blocked; the result arrives as a completion notification. Delegates a scoped coding task to an autonomous worker (Pi runtime; default model `gpt-5.6-sol` at high reasoning, override via `model` with any Copilot-catalog model that advertises `tool_calls`). It has the explore read-only tools plus edit, write, bash, and codex_review, and it returns its final text with any changed files or worktree diff. Use for bounded implementation work that may take a while or benefits from isolated worker context. Not for pure research, planning, review, or independent test authoring; use explore, plan, review, or test for those scopes. ALWAYS runs in an isolated git worktree and returns the diff via a saved patch file (a `--stat` summary + a bounded preview + the patch path; a small diff is inlined in full) — it never edits your working tree, and it HARD-ERRORS if the workspace is not a git repository. For in-place edits, use the native `implementer` subagent. If the result is too large to relay it is truncated to a preview and the FULL text is written to a file, whose absolute path is in the returned text; read that file rather than re-running the worker.",
34228
34592
  inputSchema: {
34229
34593
  type: "object",
34230
34594
  required: ["prompt"],
@@ -34240,7 +34604,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
34240
34604
  },
34241
34605
  model: {
34242
34606
  type: "string",
34243
- description: "Optional Copilot catalog model id (defaults to gpt-5.6-sol). Must advertise tool_calls support; the engine emits an isError envelope listing the eligible catalog models on mismatch. Override by task weight: `gpt-5.6-sol` (heavy/deep), `gpt-5.6-terra` (moderate), `gemini-3.6-flash` (light/cheap) — all 1M context; pair with thinking:'high'."
34607
+ description: "Optional Copilot catalog model id (defaults to gpt-5.6-sol). Must advertise tool_calls support; the engine emits an isError envelope listing the eligible catalog models on mismatch. Override by task weight: `gpt-5.6-sol` (heavy/deep), `gpt-5.6-terra` (moderate), `gpt-5.6-luna` (light/cheap) — all 1M context; pair with thinking:'high'."
34244
34608
  },
34245
34609
  thinking: {
34246
34610
  type: "string",
@@ -34281,7 +34645,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
34281
34645
  },
34282
34646
  model: {
34283
34647
  type: "string",
34284
- description: "Optional Copilot catalog model id (defaults to gemini-3.1-pro-preview). Must advertise tool_calls support; the engine emits an isError envelope listing the eligible catalog models on mismatch. Override by task weight: `gpt-5.6-sol` (heavy/deep), `gpt-5.6-terra` (moderate), `gemini-3.6-flash` (light/cheap) — all 1M context; pair with thinking:'high'."
34648
+ description: "Optional Copilot catalog model id (defaults to gemini-3.1-pro-preview). Must advertise tool_calls support; the engine emits an isError envelope listing the eligible catalog models on mismatch. Override by task weight: `gpt-5.6-sol` (heavy/deep), `gpt-5.6-terra` (moderate), `gpt-5.6-luna` (light/cheap) — all 1M context; pair with thinking:'high'."
34285
34649
  },
34286
34650
  thinking: {
34287
34651
  type: "string",
@@ -34310,7 +34674,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
34310
34674
  toolNameHttp: "plan",
34311
34675
  group: "workers",
34312
34676
  capability: "worker",
34313
- description: "Runs as the background `worker-plan` agent. Dispatch via the Agent tool (subagent_type: worker-plan) so the turn is never blocked; the result arrives as a completion notification. Read-only implementation planning by an autonomous worker (Pi runtime; default model `claude-opus-5` at xhigh reasoning, override via `model` with any Copilot-catalog model that advertises `tool_calls`). It has the same read-only toolset as explore and returns a concrete, ordered implementation plan covering files, approach, risks, and how acceptance criteria will be verified. Use before coding when the task needs repo-grounded sequencing or acceptance criteria translated into implementation steps. Not for editing files, running an implementation, writing tests, or adversarial review; use implement, test, or review for those scopes. Strictly read-only: it changes nothing on disk, and its returned text is the only artifact it produces — route to `implement` or `test` when a file actually needs to change. If the result is too large to relay it is truncated to a preview and the FULL text is written to a file, whose absolute path is in the returned text; read that file rather than re-running the worker.",
34677
+ description: "Runs as the background `worker-plan` agent. Dispatch via the Agent tool (subagent_type: worker-plan) so the turn is never blocked; the result arrives as a completion notification. Read-only implementation planning by an autonomous worker (Pi runtime; default model `claude-opus-5` at high reasoning, override via `model` with any Copilot-catalog model that advertises `tool_calls`). It has the same read-only toolset as explore and returns a concrete, ordered implementation plan covering files, approach, risks, and how acceptance criteria will be verified. Use before coding when the task needs repo-grounded sequencing or acceptance criteria translated into implementation steps. Not for editing files, running an implementation, writing tests, or adversarial review; use implement, test, or review for those scopes. Strictly read-only: it changes nothing on disk, and its returned text is the only artifact it produces — route to `implement` or `test` when a file actually needs to change. If the result is too large to relay it is truncated to a preview and the FULL text is written to a file, whose absolute path is in the returned text; read that file rather than re-running the worker.",
34314
34678
  inputSchema: {
34315
34679
  type: "object",
34316
34680
  required: ["prompt"],
@@ -34351,7 +34715,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
34351
34715
  toolNameHttp: "test",
34352
34716
  group: "workers",
34353
34717
  capability: "worker",
34354
- description: "Runs as the background `worker-test` agent. Dispatch via the Agent tool (subagent_type: worker-test) so the turn is never blocked; the result arrives as a completion notification. Independent adversarial test authoring by an autonomous worker (Pi runtime; default model `gpt-5.6-sol` at xhigh reasoning, override via `model` with any Copilot-catalog model that advertises `tool_calls`). It has the same read/write toolset as implement and writes tests that try to break the implementation through edge cases, error paths, and acceptance criteria, then runs them and reports pass/fail. Use when a separate test author should challenge an implementation without modifying the production code to make tests pass. Not for implementing fixes, broad research, or code review; use implement, explore, or review for those scopes. ALWAYS runs in an isolated git worktree and returns the test diff via a saved patch file (a `--stat` summary + a bounded preview + the patch path; a small diff is inlined in full) — it never edits your working tree, and it HARD-ERRORS if the workspace is not a git repository. For in-place test authoring, use the native `implementer` subagent. If the result is too large to relay it is truncated to a preview and the FULL text is written to a file, whose absolute path is in the returned text; read that file rather than re-running the worker.",
34718
+ description: "Runs as the background `worker-test` agent. Dispatch via the Agent tool (subagent_type: worker-test) so the turn is never blocked; the result arrives as a completion notification. Independent adversarial test authoring by an autonomous worker (Pi runtime; default model `gpt-5.6-sol` at high reasoning, override via `model` with any Copilot-catalog model that advertises `tool_calls`). It has the same read/write toolset as implement and writes tests that try to break the implementation through edge cases, error paths, and acceptance criteria, then runs them and reports pass/fail. Use when a separate test author should challenge an implementation without modifying the production code to make tests pass. Not for implementing fixes, broad research, or code review; use implement, explore, or review for those scopes. ALWAYS runs in an isolated git worktree and returns the test diff via a saved patch file (a `--stat` summary + a bounded preview + the patch path; a small diff is inlined in full) — it never edits your working tree, and it HARD-ERRORS if the workspace is not a git repository. For in-place test authoring, use the native `implementer` subagent. If the result is too large to relay it is truncated to a preview and the FULL text is written to a file, whose absolute path is in the returned text; read that file rather than re-running the worker.",
34355
34719
  inputSchema: {
34356
34720
  type: "object",
34357
34721
  required: ["prompt"],
@@ -34598,7 +34962,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
34598
34962
  toolNameHttp: "browse",
34599
34963
  group: "workers",
34600
34964
  capability: "browse_agent",
34601
- description: "Runs as the background `worker-browse` agent. Dispatch via the Agent tool (subagent_type: worker-browse) so the turn is never blocked; the result arrives as a completion notification. A Pi-driven autonomous browser worker (default model `gpt-5.4-mini`) drives a real browser to accomplish `task`, keeps raw DOM and page snapshots inside its own context, and returns a single text result. Use for delegated multi-step web tasks such as comparing prices, logging into a dashboard, or summarizing pages when the lead does not need to steer each click. Not for direct in-context browser control, screenshots, or precise element interactions; use the `browser` MCP tools for those. Pass `sessionId` to continue a prior browse session, or omit it for a fresh isolated session; multiple calls run as parallel sessions on the shared browser. If the result is too large to relay it is truncated to a preview and the FULL text is written to a file, whose absolute path is in the returned text; read that file rather than re-running the worker.",
34965
+ description: "Runs as the background `worker-browse` agent. Dispatch via the Agent tool (subagent_type: worker-browse) so the turn is never blocked; the result arrives as a completion notification. A Pi-driven autonomous browser worker (default model `gpt-5.6-luna`) drives a real browser to accomplish `task`, keeps raw DOM and page snapshots inside its own context, and returns a single text result. Use for delegated multi-step web tasks such as comparing prices, logging into a dashboard, or summarizing pages when the lead does not need to steer each click. Not for direct in-context browser control, screenshots, or precise element interactions; use the `browser` MCP tools for those. Pass `sessionId` to continue a prior browse session, or omit it for a fresh isolated session; multiple calls run as parallel sessions on the shared browser. If the result is too large to relay it is truncated to a preview and the FULL text is written to a file, whose absolute path is in the returned text; read that file rather than re-running the worker.",
34602
34966
  inputSchema: {
34603
34967
  type: "object",
34604
34968
  required: ["task"],
@@ -35057,6 +35421,6 @@ function enumerateInjectedMcpToolNames(groupKeys, opts = {}) {
35057
35421
  return [...new Set(names)];
35058
35422
  }
35059
35423
  //#endregion
35060
- export { browserToolsEnabled as $, searchWeb as A, collapsePathKeys as At, buildAnthropicErrorEvent as B, upstreamAllowH2 as Bt, buildToolbeltAwareness as C, provisionAndIndexColbert as Ct, TOOLBELT_TOOLS$1 as D, CONDENSED_OPERATING_SEQUENCE as Dt, vscodeRipgrepPath as E, warmTreeSitterPool as Et, isAdvisorRequested as F, DEFAULT_PORT as Ft, relayAnthropicStream as G, isControllerClosedError as H, withOneMSuffix as Ht, formatThinkingRepairDecline as I, UPSTREAM_FETCH_TIMEOUT_MS as It, agentToolsEnabled as J, handleMcpDelete as K, rememberThinkingHistoryRepair as L, UPSTREAM_INACTIVITY_TIMEOUT_MS as Lt, ADVISOR_TOOL_INSTRUCTIONS as M, DEFAULT_CLAUDE_MODEL_FALLBACKS as Mt, buildAdvisorStream as N, DEFAULT_CODEX_MODEL as Nt, assetFor as O, DEFINITION_OF_GREATNESS as Ot, injectAdvisorTool as P, DEFAULT_CODEX_MODEL_FALLBACKS as Pt, browserCompoundToolsEnabled as Q, repairKnownThinkingHistory as R, generateRandomPort as Rt, availableToolCommands as S, colbertDegradedWarning as St, toolbeltSkipSet as T, extractZipMember as Tt, logStreamError as U, withInstallLock as Ut, buildOpenAIErrorEvent as V, upstreamMaxConnections as Vt, readIteratorWithTimeout as W, brainstormModel as X, artifactToolsEnabled as Y, browseAgentEnabled as Z, appendPlanReminder as _, MAX_RESPONSE_BODY_BYTES as _t, buildPeerAwarenessSnippet as a, scribeModel as at, runWorkerAgent as b, provisionBrowserAssets as bt, personasFor as c, shimDefaultsToXhigh as ct, EXPLORE_DEFAULT_MODEL as d, getTokenCount as dt, fleetToolsEnabled as et, EXPLORE_DEFAULT_THINKING as f, assembleResponsesPayload as ft, TEST_DEFAULT_MODEL as g, createChatCompletions as gt, REVIEW_DEFAULT_MODEL as h, createResponses as ht, buildAgentPrompt as i, scoutModel as it, ADVISOR_INTERNAL_TOOL_NAME as j, toolbeltPathOverride as jt, satisfiesMinVersion as k, shouldUseInsecureTls as kt, BROWSE_DEFAULT_MODEL as l, countTokens as lt, PLAN_DEFAULT_MODEL as m, pickEndpoint as mt, MCP_GROUPS as n, nativeSubagentModel as nt, buildPeerAwarenessSummary as o, standInToolEnabled as ot, IMPLEMENT_DEFAULT_MODEL as p, resolveMcpToolTimeoutMs as pt, handleMcpPost as q, assertMcpToolSurfaceConsistent as r, reviewerModel as rt, enumerateInjectedMcpToolNames as s, workerToolsEnabled as st, GROUP_META as t, geminiAvailable as tt, DEFAULT_MODEL as u, createMessages as ut, resolveModeDefaults as v, readResponseBodyCapped as vt, toolbeltEnabled as w, extractTarGzMember as wt, buildEnv as x, hasSupportedBrowserInstalled as xt, resolveWorkerRunOpts as y, parseJsonOrDiagnose as yt, repairRejectedThinkingHistory as z, pickClaudeDefault as zt };
35424
+ export { browserCompoundToolsEnabled as $, satisfiesMinVersion as A, warmTreeSitterPool as At, repairRejectedThinkingHistory as B, DEFAULT_PORT as Bt, availableToolCommands as C, parseJsonOrDiagnose as Ct, vscodeRipgrepPath as D, provisionAndIndexColbert as Dt, toolbeltSkipSet as E, colbertDegradedWarning as Et, injectAdvisorTool as F, collapsePathKeys as Ft, readIteratorWithTimeout as G, upstreamAllowH2 as Gt, buildOpenAIErrorEvent as H, UPSTREAM_INACTIVITY_TIMEOUT_MS as Ht, isAdvisorRequested as I, toolbeltPathOverride as It, handleMcpPost as J, withInstallLock as Jt, relayAnthropicStream as K, upstreamMaxConnections as Kt, formatThinkingRepairDecline as L, DEFAULT_CLAUDE_MODEL_FALLBACKS as Lt, ADVISOR_INTERNAL_TOOL_NAME as M, CONDENSED_OPERATING_SEQUENCE as Mt, ADVISOR_TOOL_INSTRUCTIONS as N, DEFINITION_OF_GREATNESS as Nt, TOOLBELT_TOOLS$1 as O, extractTarGzMember as Ot, buildAdvisorStream as P, shouldUseInsecureTls as Pt, browseAgentEnabled as Q, rememberThinkingHistoryRepair as R, DEFAULT_CODEX_MODEL as Rt, buildEnv as S, readResponseBodyCapped as St, toolbeltEnabled as T, hasSupportedBrowserInstalled as Tt, isControllerClosedError as U, generateRandomPort as Ut, buildAnthropicErrorEvent as V, UPSTREAM_FETCH_TIMEOUT_MS as Vt, logStreamError as W, pickClaudeDefault as Wt, artifactToolsEnabled as X, agentToolsEnabled as Y, brainstormModel as Z, appendPlanReminder as _, resolveMcpToolTimeoutMs as _t, buildPeerAwarenessSnippet as a, nativeSubagentModel as at, resolveWorkerRunOpts as b, createChatCompletions as bt, personasFor as c, scribeModel as ct, EXPLORE_DEFAULT_MODEL as d, shimDefaultsToXhigh as dt, browserToolsEnabled as et, EXPLORE_DEFAULT_THINKING as f, countTokens as ft, TEST_DEFAULT_MODEL as g, warnOnTokenPriceDrift as gt, REVIEW_DEFAULT_MODEL as h, assembleResponsesPayload as ht, buildAgentPrompt as i, implementerFastModel as it, searchWeb as j, provisionTreeSitterAssets as jt, assetFor as k, extractZipMember as kt, BROWSE_DEFAULT_MODEL as l, standInToolEnabled as lt, PLAN_DEFAULT_MODEL as m, getTokenCount as mt, MCP_GROUPS as n, geminiAvailable as nt, buildPeerAwarenessSummary as o, reviewerModel as ot, IMPLEMENT_DEFAULT_MODEL as p, createMessages as pt, handleMcpDelete as q, withOneMSuffix as qt, assertMcpToolSurfaceConsistent as r, generalPurposeFastModel as rt, enumerateInjectedMcpToolNames as s, scoutModel as st, GROUP_META as t, fleetToolsEnabled as tt, DEFAULT_MODEL_CHAIN as u, workerToolsEnabled as ut, resolveDefaultModel as v, pickEndpoint as vt, buildToolbeltAwareness as w, provisionBrowserAssets as wt, runWorkerAgent as x, MAX_RESPONSE_BODY_BYTES as xt, resolveModeDefaults as y, createResponses as yt, repairKnownThinkingHistory as z, DEFAULT_CODEX_MODEL_FALLBACKS as zt };
35061
35425
 
35062
- //# sourceMappingURL=peer-mcp-personas-TMOZJhfy.js.map
35426
+ //# sourceMappingURL=peer-mcp-personas-l4P4s1fK.js.map