github-router 0.3.249 → 0.3.255

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 (95) hide show
  1. package/dist/attribution-settings-CegtE0TY.js +2347 -0
  2. package/dist/attribution-settings-CegtE0TY.js.map +1 -0
  3. package/dist/auth-CP4q2CjO.js +44 -0
  4. package/dist/auth-CP4q2CjO.js.map +1 -0
  5. package/dist/browser-ext/background.js +8 -1
  6. package/dist/browser-ext/manifest.json +1 -1
  7. package/dist/check-usage-6PB5IUFb.js +43 -0
  8. package/dist/check-usage-6PB5IUFb.js.map +1 -0
  9. package/dist/claude-BiZxoNWq.js +593 -0
  10. package/dist/claude-BiZxoNWq.js.map +1 -0
  11. package/dist/client-CQMfroGV.js +413 -0
  12. package/dist/client-CQMfroGV.js.map +1 -0
  13. package/dist/codex-ST21X3WF.js +85 -0
  14. package/dist/codex-ST21X3WF.js.map +1 -0
  15. package/dist/debug-CjmE9sgG.js +81 -0
  16. package/dist/debug-CjmE9sgG.js.map +1 -0
  17. package/dist/engine-DNCX0Hfd.js +2 -0
  18. package/dist/{lifecycle-DHZsVN8j.js → exec-DTO2oin0.js} +3 -130
  19. package/dist/exec-DTO2oin0.js.map +1 -0
  20. package/dist/file-log-reporter-IFQcL5IK.js +158 -0
  21. package/dist/file-log-reporter-IFQcL5IK.js.map +1 -0
  22. package/dist/gate-discovery-CepmbZnc.js +635 -0
  23. package/dist/gate-discovery-CepmbZnc.js.map +1 -0
  24. package/dist/get-copilot-usage-DD1N0Xlh.js +11 -0
  25. package/dist/get-copilot-usage-DD1N0Xlh.js.map +1 -0
  26. package/dist/hook-mcp-client-DBvm9608.js +136 -0
  27. package/dist/hook-mcp-client-DBvm9608.js.map +1 -0
  28. package/dist/internal-artifact-open-D2cQ2QCw.js +319 -0
  29. package/dist/internal-artifact-open-D2cQ2QCw.js.map +1 -0
  30. package/dist/internal-first-mate-guard-7v2CtMA6.js +2 -0
  31. package/dist/internal-first-mate-guard-La0tIjTU.js +126 -0
  32. package/dist/internal-first-mate-guard-La0tIjTU.js.map +1 -0
  33. package/dist/internal-plan-review-ipnT3bhj.js +114 -0
  34. package/dist/internal-plan-review-ipnT3bhj.js.map +1 -0
  35. package/dist/internal-prompt-submit-DOj75_hh.js +121 -0
  36. package/dist/internal-prompt-submit-DOj75_hh.js.map +1 -0
  37. package/dist/internal-session-bind-DwK2iGW0.js +133 -0
  38. package/dist/internal-session-bind-DwK2iGW0.js.map +1 -0
  39. package/dist/internal-stop-hook-CNPGJm63.js +212 -0
  40. package/dist/internal-stop-hook-CNPGJm63.js.map +1 -0
  41. package/dist/internal-stop-review-AUcFssrW.js +122 -0
  42. package/dist/internal-stop-review-AUcFssrW.js.map +1 -0
  43. package/dist/internal-worker-guard-Lu8VHj5k.js +75 -0
  44. package/dist/internal-worker-guard-Lu8VHj5k.js.map +1 -0
  45. package/dist/internal-workspace-header-BRMz0Yql.js +24 -0
  46. package/dist/internal-workspace-header-BRMz0Yql.js.map +1 -0
  47. package/dist/lifecycle-Byw5s1G8.js +134 -0
  48. package/dist/lifecycle-Byw5s1G8.js.map +1 -0
  49. package/dist/lifecycle-D80CaWie.js +2 -0
  50. package/dist/{lifecycle-CUf1UDrH.js → lifecycle-DD88ka3f.js} +3 -3
  51. package/dist/{lifecycle-CUf1UDrH.js.map → lifecycle-DD88ka3f.js.map} +1 -1
  52. package/dist/lifecycle-DzqCqDlM.js +2 -0
  53. package/dist/main.js +43 -12884
  54. package/dist/main.js.map +1 -1
  55. package/dist/mcp-workspace-header-CGJbNeHb.js +21 -0
  56. package/dist/mcp-workspace-header-CGJbNeHb.js.map +1 -0
  57. package/dist/models-B6UnGyRo.js +158 -0
  58. package/dist/models-B6UnGyRo.js.map +1 -0
  59. package/dist/orchestration-hRU4TdWr.js +39 -0
  60. package/dist/orchestration-hRU4TdWr.js.map +1 -0
  61. package/dist/{paths-BjTMI_xK.js → paths-C1cLZ7Ga.js} +52 -20
  62. package/dist/paths-C1cLZ7Ga.js.map +1 -0
  63. package/dist/paths-CwKwc2pi.js +2 -0
  64. package/dist/{peer-mcp-personas-DJzLpfDJ.js → peer-mcp-personas-BDet588n.js} +1006 -2488
  65. package/dist/peer-mcp-personas-BDet588n.js.map +1 -0
  66. package/dist/plan-review-hook-C8x0uKPf.js +159 -0
  67. package/dist/plan-review-hook-C8x0uKPf.js.map +1 -0
  68. package/dist/prompt-submit-hook-BrkkLAAB.js +153 -0
  69. package/dist/prompt-submit-hook-BrkkLAAB.js.map +1 -0
  70. package/dist/provision-DSkPa5hY.js +656 -0
  71. package/dist/provision-DSkPa5hY.js.map +1 -0
  72. package/dist/serve-sa_7c-yD.js +1511 -0
  73. package/dist/serve-sa_7c-yD.js.map +1 -0
  74. package/dist/server-setup-DcO9qvN3.js +4776 -0
  75. package/dist/server-setup-DcO9qvN3.js.map +1 -0
  76. package/dist/start-siGxuZhO.js +129 -0
  77. package/dist/start-siGxuZhO.js.map +1 -0
  78. package/dist/stop-gate-hook-DQc2KV7B.js +686 -0
  79. package/dist/stop-gate-hook-DQc2KV7B.js.map +1 -0
  80. package/dist/stop-gate-policy-CHwWbuF_.js +268 -0
  81. package/dist/stop-gate-policy-CHwWbuF_.js.map +1 -0
  82. package/dist/token-R2ocFC3M.js +1054 -0
  83. package/dist/token-R2ocFC3M.js.map +1 -0
  84. package/dist/version-_Q1WpsQp.js +32 -0
  85. package/dist/version-_Q1WpsQp.js.map +1 -0
  86. package/dist/worker-dispatch-Bj1uYyG9.js +222 -0
  87. package/dist/worker-dispatch-Bj1uYyG9.js.map +1 -0
  88. package/package.json +1 -1
  89. package/dist/engine-BuuHUb4t.js +0 -2
  90. package/dist/lifecycle-0rXrwjWk.js +0 -2
  91. package/dist/lifecycle-DHZsVN8j.js.map +0 -1
  92. package/dist/lifecycle-hzPwXc3I.js +0 -2
  93. package/dist/paths-BjTMI_xK.js.map +0 -1
  94. package/dist/paths-D3XgmTcQ.js +0 -2
  95. package/dist/peer-mcp-personas-DJzLpfDJ.js.map +0 -1
@@ -0,0 +1,21 @@
1
+ //#region src/lib/mcp-workspace-header.ts
2
+ /** Header the per-session MCP headersHelper emits, carrying the calling Claude
3
+ * session's working directory. The /mcp handler uses it as the default
4
+ * `workspace` for repo-scoped tools so a machine-wide `serve` targets the
5
+ * active repo, not the proxy launch cwd. */
6
+ const MCP_WORKSPACE_HEADER = "X-GH-Workspace";
7
+ /** stdout JSON the headersHelper prints; Claude merges it into the connection
8
+ * headers. `cwd` is the helper's own process cwd = the session's project dir. */
9
+ function buildWorkspaceHeaderJson(cwd) {
10
+ return JSON.stringify({ [MCP_WORKSPACE_HEADER]: cwd });
11
+ }
12
+ /** Command string Claude runs as the headersHelper. Mirrors
13
+ * buildPromptSubmitHookCommand's quoting (src/lib/orchestration/prompt-submit-hook.ts). */
14
+ function buildWorkspaceHeaderHelperCommand(execPath, scriptPath) {
15
+ const q = (s) => `"${s}"`;
16
+ return scriptPath && scriptPath !== execPath ? `${q(execPath)} ${q(scriptPath)} internal-workspace-header` : `${q(execPath)} internal-workspace-header`;
17
+ }
18
+ //#endregion
19
+ export { buildWorkspaceHeaderHelperCommand as n, buildWorkspaceHeaderJson as r, MCP_WORKSPACE_HEADER as t };
20
+
21
+ //# sourceMappingURL=mcp-workspace-header-CGJbNeHb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-workspace-header-CGJbNeHb.js","names":[],"sources":["../src/lib/mcp-workspace-header.ts"],"sourcesContent":["/** Header the per-session MCP headersHelper emits, carrying the calling Claude\n * session's working directory. The /mcp handler uses it as the default\n * `workspace` for repo-scoped tools so a machine-wide `serve` targets the\n * active repo, not the proxy launch cwd. */\nexport const MCP_WORKSPACE_HEADER = \"X-GH-Workspace\"\n\n/** stdout JSON the headersHelper prints; Claude merges it into the connection\n * headers. `cwd` is the helper's own process cwd = the session's project dir. */\nexport function buildWorkspaceHeaderJson(cwd: string): string {\n return JSON.stringify({ [MCP_WORKSPACE_HEADER]: cwd })\n}\n\n/** Command string Claude runs as the headersHelper. Mirrors\n * buildPromptSubmitHookCommand's quoting (src/lib/orchestration/prompt-submit-hook.ts). */\nexport function buildWorkspaceHeaderHelperCommand(execPath: string, scriptPath: string | undefined): string {\n const q = (s: string): string => `\"${s}\"`\n return scriptPath && scriptPath !== execPath\n ? `${q(execPath)} ${q(scriptPath)} internal-workspace-header`\n : `${q(execPath)} internal-workspace-header`\n}\n"],"mappings":";;;;;AAIA,MAAa,uBAAuB;;;AAIpC,SAAgB,yBAAyB,KAAqB;CAC5D,OAAO,KAAK,UAAU,GAAG,uBAAuB,IAAI,CAAC;AACvD;;;AAIA,SAAgB,kCAAkC,UAAkB,YAAwC;CAC1G,MAAM,KAAK,MAAsB,IAAI,EAAE;CACvC,OAAO,cAAc,eAAe,WAChC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,8BAChC,GAAG,EAAE,QAAQ,EAAE;AACrB"}
@@ -0,0 +1,158 @@
1
+ import { i as ensurePaths } from "./paths-C1cLZ7Ga.js";
2
+ import { p as getModels, r as setupGitHubToken, t as setupCopilotToken } from "./token-R2ocFC3M.js";
3
+ import { defineCommand } from "citty";
4
+ import consola from "consola";
5
+ //#region src/models.ts
6
+ const models = defineCommand({
7
+ meta: {
8
+ name: "models",
9
+ description: "List available GitHub Copilot models and their capabilities. Pass an optional pattern to filter (case-insensitive substring match on id, name, vendor, family)."
10
+ },
11
+ args: {
12
+ pattern: {
13
+ type: "positional",
14
+ required: false,
15
+ description: "Substring to filter models by (matches id, name, vendor, or family)."
16
+ },
17
+ json: {
18
+ type: "boolean",
19
+ default: false,
20
+ description: "Emit raw JSON instead of the pretty layout."
21
+ }
22
+ },
23
+ async run({ args }) {
24
+ await ensurePaths();
25
+ await setupGitHubToken();
26
+ try {
27
+ await setupCopilotToken();
28
+ } catch (err) {
29
+ consola.error("Failed to obtain Copilot token:", err);
30
+ process.exit(1);
31
+ }
32
+ let catalog;
33
+ try {
34
+ catalog = await getModels();
35
+ } catch (err) {
36
+ consola.error("Failed to fetch Copilot model catalog:", err);
37
+ process.exit(1);
38
+ }
39
+ const all = catalog.data;
40
+ const pattern = args.pattern?.toString().trim();
41
+ const filtered = pattern ? filterModels(all, pattern) : all;
42
+ if (args.json) {
43
+ process.stdout.write(`${JSON.stringify(filtered, null, 2)}\n`);
44
+ return;
45
+ }
46
+ if (filtered.length === 0) {
47
+ consola.warn(`No models matched "${pattern}". ${all.length} models available — try a different substring or run without an argument to list everything.`);
48
+ process.exit(1);
49
+ }
50
+ const grouped = groupByVendor(filtered);
51
+ const lines = [];
52
+ const header = pattern ? `${filtered.length}/${all.length} models match "${pattern}"` : `${all.length} models available`;
53
+ lines.push(header);
54
+ lines.push("");
55
+ for (const [vendor, list] of grouped) {
56
+ lines.push(`▾ ${vendor} (${list.length})`);
57
+ for (const model of list) lines.push(...formatModel(model));
58
+ lines.push("");
59
+ }
60
+ process.stdout.write(lines.join("\n"));
61
+ }
62
+ });
63
+ function filterModels(models, pattern) {
64
+ const needle = pattern.toLowerCase();
65
+ return models.filter((m) => {
66
+ return [
67
+ m.id,
68
+ m.name,
69
+ m.vendor,
70
+ m.capabilities.family,
71
+ m.capabilities.type,
72
+ m.model_picker_category ?? ""
73
+ ].join(" ").toLowerCase().includes(needle);
74
+ });
75
+ }
76
+ function groupByVendor(models) {
77
+ const map = /* @__PURE__ */ new Map();
78
+ for (const m of models) {
79
+ const key = m.vendor || "(unknown vendor)";
80
+ const bucket = map.get(key);
81
+ if (bucket) bucket.push(m);
82
+ else map.set(key, [m]);
83
+ }
84
+ return [...map.entries()].sort(([a], [b]) => a.localeCompare(b));
85
+ }
86
+ function formatModel(model) {
87
+ const lines = [];
88
+ const tags = [];
89
+ if (model.preview) tags.push("preview");
90
+ if (model.is_chat_default) tags.push("chat-default");
91
+ if (model.is_chat_fallback) tags.push("chat-fallback");
92
+ if (model.billing?.is_premium) tags.push("premium");
93
+ if (model.billing?.restricted_to?.length) tags.push(`restricted:${model.billing.restricted_to.join("/")}`);
94
+ if (model.policy && model.policy.state !== "enabled") tags.push(`policy:${model.policy.state}`);
95
+ const tagStr = tags.length > 0 ? ` [${tags.join(", ")}]` : "";
96
+ lines.push(` • ${model.id}${tagStr}`);
97
+ if (model.name && model.name !== model.id) lines.push(` name: ${model.name}`);
98
+ const meta = [`family: ${model.capabilities.family}`, `type: ${model.capabilities.type}`];
99
+ if (model.capabilities.tokenizer) meta.push(`tokenizer: ${model.capabilities.tokenizer}`);
100
+ if (model.version) meta.push(`version: ${model.version}`);
101
+ lines.push(` ${meta.join(" · ")}`);
102
+ const limits = model.capabilities.limits;
103
+ const limitParts = [];
104
+ if (limits) {
105
+ if (limits.max_context_window_tokens) limitParts.push(`ctx ${formatTokens(limits.max_context_window_tokens)}`);
106
+ else if (limits.max_prompt_tokens) limitParts.push(`prompt ${formatTokens(limits.max_prompt_tokens)}`);
107
+ if (limits.max_output_tokens) limitParts.push(`out ${formatTokens(limits.max_output_tokens)}`);
108
+ if (limits.max_non_streaming_output_tokens && limits.max_non_streaming_output_tokens !== limits.max_output_tokens) limitParts.push(`out-non-stream ${formatTokens(limits.max_non_streaming_output_tokens)}`);
109
+ if (limits.max_inputs) limitParts.push(`inputs ${limits.max_inputs}`);
110
+ if (limits.vision?.max_prompt_images) limitParts.push(`images ${limits.vision.max_prompt_images}`);
111
+ }
112
+ if (limitParts.length > 0) lines.push(` limits: ${limitParts.join(" · ")}`);
113
+ const supports = model.capabilities.supports;
114
+ const supportFlags = [];
115
+ if (supports) {
116
+ if (supports.tool_calls) supportFlags.push("tools");
117
+ if (supports.parallel_tool_calls) supportFlags.push("parallel-tools");
118
+ if (supports.streaming) supportFlags.push("streaming");
119
+ if (supports.vision) supportFlags.push("vision");
120
+ if (supports.structured_outputs) supportFlags.push("structured-outputs");
121
+ if (supports.dimensions) supportFlags.push("dimensions");
122
+ if (supports.adaptive_thinking) {
123
+ const min = supports.min_thinking_budget;
124
+ const max = supports.max_thinking_budget;
125
+ const range = min !== void 0 && max !== void 0 ? `(${formatTokens(min)}-${formatTokens(max)})` : "";
126
+ supportFlags.push(`adaptive-thinking${range}`);
127
+ }
128
+ if (supports.reasoning_effort && supports.reasoning_effort.length > 0) supportFlags.push(`reasoning:${supports.reasoning_effort.join("/")}`);
129
+ }
130
+ if (supportFlags.length > 0) lines.push(` supports: ${supportFlags.join(", ")}`);
131
+ if (model.supported_endpoints && model.supported_endpoints.length > 0) lines.push(` endpoints: ${model.supported_endpoints.join(", ")}`);
132
+ if (model.billing) {
133
+ const billParts = [];
134
+ if (model.billing.is_premium) billParts.push("premium");
135
+ if (typeof model.billing.multiplier === "number") billParts.push(`×${model.billing.multiplier}`);
136
+ if (billParts.length > 0) lines.push(` billing: ${billParts.join(" ")}`);
137
+ }
138
+ return lines;
139
+ }
140
+ /**
141
+ * Format a token count in a compact human-readable form: `1024` →
142
+ * `1k`, `4096` → `4k`, `131072` → `128k`, `1048576` → `1M`. Prefer
143
+ * binary multiples (mebi, kibi) since Claude Code / Copilot context
144
+ * windows are reported in binary units (`1M context` = 1024 × 1024
145
+ * tokens). Fall back to decimal (`64k` for `64000`) when the value
146
+ * is a clean decimal multiple but not binary.
147
+ */
148
+ function formatTokens(n) {
149
+ if (n >= 1048576 && n % 1048576 === 0) return `${n / 1048576}M`;
150
+ if (n >= 1024 && n % 1024 === 0) return `${n / 1024}k`;
151
+ if (n >= 1e6 && n % 1e6 === 0) return `${n / 1e6}M`;
152
+ if (n >= 1e3 && n % 1e3 === 0) return `${n / 1e3}k`;
153
+ return `${n}`;
154
+ }
155
+ //#endregion
156
+ export { models };
157
+
158
+ //# sourceMappingURL=models-B6UnGyRo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models-B6UnGyRo.js","names":[],"sources":["../src/models.ts"],"sourcesContent":["import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths } from \"./lib/paths\"\nimport { setupCopilotToken, setupGitHubToken } from \"./lib/token\"\nimport { getModels, type Model } from \"./services/copilot/get-models\"\n\nexport const models = defineCommand({\n meta: {\n name: \"models\",\n description:\n \"List available GitHub Copilot models and their capabilities. Pass an optional pattern to filter (case-insensitive substring match on id, name, vendor, family).\",\n },\n args: {\n pattern: {\n type: \"positional\",\n required: false,\n description:\n \"Substring to filter models by (matches id, name, vendor, or family).\",\n },\n json: {\n type: \"boolean\",\n default: false,\n description: \"Emit raw JSON instead of the pretty layout.\",\n },\n },\n async run({ args }) {\n await ensurePaths()\n await setupGitHubToken()\n try {\n await setupCopilotToken()\n } catch (err) {\n consola.error(\"Failed to obtain Copilot token:\", err)\n process.exit(1)\n }\n\n let catalog: Awaited<ReturnType<typeof getModels>>\n try {\n catalog = await getModels()\n } catch (err) {\n consola.error(\"Failed to fetch Copilot model catalog:\", err)\n process.exit(1)\n }\n\n const all = catalog.data\n const pattern = args.pattern?.toString().trim()\n const filtered = pattern ? filterModels(all, pattern) : all\n\n if (args.json) {\n process.stdout.write(`${JSON.stringify(filtered, null, 2)}\\n`)\n return\n }\n\n if (filtered.length === 0) {\n consola.warn(\n `No models matched \"${pattern}\". ${all.length} models available — try a different substring or run without an argument to list everything.`,\n )\n process.exit(1)\n }\n\n const grouped = groupByVendor(filtered)\n const lines: Array<string> = []\n const header = pattern\n ? `${filtered.length}/${all.length} models match \"${pattern}\"`\n : `${all.length} models available`\n lines.push(header)\n lines.push(\"\")\n for (const [vendor, list] of grouped) {\n lines.push(`▾ ${vendor} (${list.length})`)\n for (const model of list) {\n lines.push(...formatModel(model))\n }\n lines.push(\"\")\n }\n process.stdout.write(lines.join(\"\\n\"))\n },\n})\n\nfunction filterModels(models: Array<Model>, pattern: string): Array<Model> {\n const needle = pattern.toLowerCase()\n return models.filter((m) => {\n const haystack = [\n m.id,\n m.name,\n m.vendor,\n m.capabilities.family,\n m.capabilities.type,\n m.model_picker_category ?? \"\",\n ]\n .join(\" \")\n .toLowerCase()\n return haystack.includes(needle)\n })\n}\n\nfunction groupByVendor(models: Array<Model>): Array<[string, Array<Model>]> {\n const map = new Map<string, Array<Model>>()\n for (const m of models) {\n const key = m.vendor || \"(unknown vendor)\"\n const bucket = map.get(key)\n if (bucket) bucket.push(m)\n else map.set(key, [m])\n }\n // Stable vendor order: alphabetical for predictability.\n return [...map.entries()].sort(([a], [b]) => a.localeCompare(b))\n}\n\n/**\n * Test-only exports. Not part of the public CLI surface — kept out of\n * the default export so they don't show up in IDE autocomplete on\n * `import { ... } from \"github-router/models\"` consumers.\n */\nexport const __testing = { filterModels, groupByVendor, formatModel, formatTokens }\n\nfunction formatModel(model: Model): Array<string> {\n const lines: Array<string> = []\n const tags: Array<string> = []\n if (model.preview) tags.push(\"preview\")\n if (model.is_chat_default) tags.push(\"chat-default\")\n if (model.is_chat_fallback) tags.push(\"chat-fallback\")\n if (model.billing?.is_premium) tags.push(\"premium\")\n if (model.billing?.restricted_to?.length) {\n tags.push(`restricted:${model.billing.restricted_to.join(\"/\")}`)\n }\n if (model.policy && model.policy.state !== \"enabled\") {\n tags.push(`policy:${model.policy.state}`)\n }\n const tagStr = tags.length > 0 ? ` [${tags.join(\", \")}]` : \"\"\n lines.push(` • ${model.id}${tagStr}`)\n if (model.name && model.name !== model.id) {\n lines.push(` name: ${model.name}`)\n }\n const meta: Array<string> = [\n `family: ${model.capabilities.family}`,\n `type: ${model.capabilities.type}`,\n ]\n if (model.capabilities.tokenizer) {\n meta.push(`tokenizer: ${model.capabilities.tokenizer}`)\n }\n if (model.version) {\n meta.push(`version: ${model.version}`)\n }\n lines.push(` ${meta.join(\" · \")}`)\n\n const limits = model.capabilities.limits\n const limitParts: Array<string> = []\n if (limits) {\n if (limits.max_context_window_tokens) {\n limitParts.push(`ctx ${formatTokens(limits.max_context_window_tokens)}`)\n } else if (limits.max_prompt_tokens) {\n limitParts.push(`prompt ${formatTokens(limits.max_prompt_tokens)}`)\n }\n if (limits.max_output_tokens) {\n limitParts.push(`out ${formatTokens(limits.max_output_tokens)}`)\n }\n if (\n limits.max_non_streaming_output_tokens\n && limits.max_non_streaming_output_tokens !== limits.max_output_tokens\n ) {\n limitParts.push(\n `out-non-stream ${formatTokens(limits.max_non_streaming_output_tokens)}`,\n )\n }\n if (limits.max_inputs) limitParts.push(`inputs ${limits.max_inputs}`)\n if (limits.vision?.max_prompt_images) {\n limitParts.push(`images ${limits.vision.max_prompt_images}`)\n }\n }\n if (limitParts.length > 0) {\n lines.push(` limits: ${limitParts.join(\" · \")}`)\n }\n\n const supports = model.capabilities.supports\n const supportFlags: Array<string> = []\n if (supports) {\n if (supports.tool_calls) supportFlags.push(\"tools\")\n if (supports.parallel_tool_calls) supportFlags.push(\"parallel-tools\")\n if (supports.streaming) supportFlags.push(\"streaming\")\n if (supports.vision) supportFlags.push(\"vision\")\n if (supports.structured_outputs) supportFlags.push(\"structured-outputs\")\n if (supports.dimensions) supportFlags.push(\"dimensions\")\n if (supports.adaptive_thinking) {\n const min = supports.min_thinking_budget\n const max = supports.max_thinking_budget\n const range\n = min !== undefined && max !== undefined\n ? `(${formatTokens(min)}-${formatTokens(max)})`\n : \"\"\n supportFlags.push(`adaptive-thinking${range}`)\n }\n if (supports.reasoning_effort && supports.reasoning_effort.length > 0) {\n supportFlags.push(`reasoning:${supports.reasoning_effort.join(\"/\")}`)\n }\n }\n if (supportFlags.length > 0) {\n lines.push(` supports: ${supportFlags.join(\", \")}`)\n }\n\n if (model.supported_endpoints && model.supported_endpoints.length > 0) {\n lines.push(` endpoints: ${model.supported_endpoints.join(\", \")}`)\n }\n if (model.billing) {\n const billParts: Array<string> = []\n if (model.billing.is_premium) billParts.push(\"premium\")\n if (typeof model.billing.multiplier === \"number\") {\n billParts.push(`×${model.billing.multiplier}`)\n }\n if (billParts.length > 0) {\n lines.push(` billing: ${billParts.join(\" \")}`)\n }\n }\n return lines\n}\n\n/**\n * Format a token count in a compact human-readable form: `1024` →\n * `1k`, `4096` → `4k`, `131072` → `128k`, `1048576` → `1M`. Prefer\n * binary multiples (mebi, kibi) since Claude Code / Copilot context\n * windows are reported in binary units (`1M context` = 1024 × 1024\n * tokens). Fall back to decimal (`64k` for `64000`) when the value\n * is a clean decimal multiple but not binary.\n */\nfunction formatTokens(n: number): string {\n if (n >= 1_048_576 && n % 1_048_576 === 0) return `${n / 1_048_576}M`\n if (n >= 1024 && n % 1024 === 0) return `${n / 1024}k`\n if (n >= 1_000_000 && n % 1_000_000 === 0) return `${n / 1_000_000}M`\n if (n >= 1000 && n % 1000 === 0) return `${n / 1000}k`\n return `${n}`\n}\n"],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { i as parseIntEnv, o as runCommandCapture } from "./exec-DTO2oin0.js";
2
+ import "./stop-gate-hook-DQc2KV7B.js";
3
+ //#region src/lib/orchestration/live-exec.ts
4
+ /**
5
+ * Live `ExecFn` for the gate runner — runs the kernel's SEALED gate command in a
6
+ * workspace via the project's Windows-safe exec helper (`runCommandCapture` →
7
+ * `buildExecInvocation`, which handles cmd.exe quoting on Windows). Only the
8
+ * kernel's sealed gate commands flow through here (tests/types/lint/build),
9
+ * never a producer-authored string, so a simple whitespace split into argv is
10
+ * safe for these fixed commands. A command that can't run (spawn error / killed)
11
+ * counts as a non-zero exit, never a throw — the gate runner treats it as
12
+ * not-passed.
13
+ *
14
+ * This is the one piece of the gate engine that touches a real subprocess; it is
15
+ * model-free and cross-platform, so it is exercised directly in CI (unlike the
16
+ * worker/worktree/model adapters, which need the gated E2E harness).
17
+ */
18
+ /** Per-command wall-clock cap so a hung gate command (watch-mode test, a process
19
+ * waiting on stdin, a stale lockfile) is tree-killed instead of hanging the
20
+ * caller forever. Generous (a real typecheck/test/lint can take minutes) but
21
+ * bounded; override with GH_ROUTER_GATE_CMD_TIMEOUT_MS. A timeout kills the
22
+ * command (code null) which the gate runner treats as not-passed. */
23
+ const CMD_TIMEOUT_MS = parseIntEnv(process.env.GH_ROUTER_GATE_CMD_TIMEOUT_MS) ?? 6e5;
24
+ const liveExec = async ({ command, cwd }) => {
25
+ const argv = command.trim().split(/\s+/).filter(Boolean);
26
+ if (argv.length === 0) return { exitCode: 1 };
27
+ try {
28
+ return { exitCode: (await runCommandCapture(argv, {
29
+ cwd,
30
+ timeoutMs: CMD_TIMEOUT_MS
31
+ })).code ?? 1 };
32
+ } catch {
33
+ return { exitCode: 1 };
34
+ }
35
+ };
36
+ //#endregion
37
+ export { liveExec as t };
38
+
39
+ //# sourceMappingURL=orchestration-hRU4TdWr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestration-hRU4TdWr.js","names":[],"sources":["../src/lib/orchestration/live-exec.ts"],"sourcesContent":["/**\n * Live `ExecFn` for the gate runner — runs the kernel's SEALED gate command in a\n * workspace via the project's Windows-safe exec helper (`runCommandCapture` →\n * `buildExecInvocation`, which handles cmd.exe quoting on Windows). Only the\n * kernel's sealed gate commands flow through here (tests/types/lint/build),\n * never a producer-authored string, so a simple whitespace split into argv is\n * safe for these fixed commands. A command that can't run (spawn error / killed)\n * counts as a non-zero exit, never a throw — the gate runner treats it as\n * not-passed.\n *\n * This is the one piece of the gate engine that touches a real subprocess; it is\n * model-free and cross-platform, so it is exercised directly in CI (unlike the\n * worker/worktree/model adapters, which need the gated E2E harness).\n */\n\nimport { runCommandCapture } from \"~/lib/exec\"\n\nimport { type ExecFn } from \"./gate-runner\"\nimport { parseIntEnv } from \"../exec\"\n\n/** Per-command wall-clock cap so a hung gate command (watch-mode test, a process\n * waiting on stdin, a stale lockfile) is tree-killed instead of hanging the\n * caller forever. Generous (a real typecheck/test/lint can take minutes) but\n * bounded; override with GH_ROUTER_GATE_CMD_TIMEOUT_MS. A timeout kills the\n * command (code null) which the gate runner treats as not-passed. */\nconst CMD_TIMEOUT_MS =\n parseIntEnv(process.env.GH_ROUTER_GATE_CMD_TIMEOUT_MS) ?? 600_000\n\nexport const liveExec: ExecFn = async ({ command, cwd }) => {\n const argv = command.trim().split(/\\s+/).filter(Boolean)\n if (argv.length === 0) return { exitCode: 1 }\n try {\n const r = await runCommandCapture(argv, { cwd, timeoutMs: CMD_TIMEOUT_MS })\n // `code` is null when killed by signal/timeout → treat as a failed gate.\n return { exitCode: r.code ?? 1 }\n } catch {\n return { exitCode: 1 }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAM,iBACJ,YAAY,QAAQ,IAAI,6BAA6B,KAAK;AAE5D,MAAa,WAAmB,OAAO,EAAE,SAAS,UAAU;CAC1D,MAAM,OAAO,QAAQ,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO;CACvD,IAAI,KAAK,WAAW,GAAG,OAAO,EAAE,UAAU,EAAE;CAC5C,IAAI;EAGF,OAAO,EAAE,WAAU,MAFH,kBAAkB,MAAM;GAAE;GAAK,WAAW;EAAe,CAAC,EAAA,CAErD,QAAQ,EAAE;CACjC,QAAQ;EACN,OAAO,EAAE,UAAU,EAAE;CACvB;AACF"}
@@ -1,8 +1,8 @@
1
1
  import consola from "consola";
2
+ import path from "node:path";
2
3
  import { randomBytes } from "node:crypto";
3
4
  import fs from "node:fs/promises";
4
5
  import os from "node:os";
5
- import path from "node:path";
6
6
  //#region src/lib/paths.ts
7
7
  function appDir() {
8
8
  return path.join(os.homedir(), ".local", "share", "github-router");
@@ -221,12 +221,12 @@ async function ensurePaths() {
221
221
  consola.debug("Peer-agent .md sweep skipped:", err);
222
222
  });
223
223
  await (async () => {
224
- await (await import("./lifecycle-hzPwXc3I.js")).sweepStaleWorktreesAtBoot();
224
+ await (await import("./lifecycle-DzqCqDlM.js")).sweepStaleWorktreesAtBoot();
225
225
  })().catch((err) => {
226
226
  consola.debug("Worker worktree boot sweep skipped:", err);
227
227
  });
228
228
  await (async () => {
229
- await (await import("./lifecycle-0rXrwjWk.js")).sweepStaleColbertMetaAtBoot();
229
+ await (await import("./lifecycle-D80CaWie.js")).sweepStaleColbertMetaAtBoot();
230
230
  })().catch((err) => {
231
231
  consola.debug("ColBERT meta boot sweep skipped:", err);
232
232
  });
@@ -717,58 +717,90 @@ async function assertOnboardingGateInjected(targetDir) {
717
717
  * of `sourceDir` and we don't reintroduce a confused-deputy vector.
718
718
  * - Files copy only if source mtime > target mtime (idempotent).
719
719
  */
720
- async function mirrorDirRecursive(sourceDir, targetDir, relPath) {
720
+ /**
721
+ * Max file operations in flight across the WHOLE mirror walk.
722
+ *
723
+ * The walk is I/O-bound over hundreds of independent small files, so it
724
+ * parallelizes well: measured 1021ms serial vs 311ms at this limit for a real
725
+ * 394-file / 4.7MB `~/.claude` (Windows 11, 16 cores). It must be BOUNDED
726
+ * rather than a bare `Promise.all` over every entry — the mirror is re-copied
727
+ * on every launch (the target is a fresh per-launch dir, so the mtime skip
728
+ * below never fires across launches), and firing hundreds of simultaneous
729
+ * `copyFile`s just trades one bottleneck for file-handle exhaustion.
730
+ *
731
+ * The limit is shared across the recursion via a semaphore rather than applied
732
+ * per-directory: a per-directory bound would multiply with nesting depth and
733
+ * stop being a bound at all.
734
+ */
735
+ const MIRROR_COPY_CONCURRENCY = 16;
736
+ /** Counting semaphore. FIFO, so a deep subtree cannot starve a shallow one. */
737
+ function createSemaphore(limit) {
738
+ let active = 0;
739
+ const waiters = [];
740
+ return async function withSlot(fn) {
741
+ if (active >= limit) await new Promise((resolve) => waiters.push(resolve));
742
+ else active++;
743
+ try {
744
+ return await fn();
745
+ } finally {
746
+ const next = waiters.shift();
747
+ if (next) next();
748
+ else active--;
749
+ }
750
+ };
751
+ }
752
+ async function mirrorDirRecursive(sourceDir, targetDir, relPath, withSlot = createSemaphore(MIRROR_COPY_CONCURRENCY)) {
721
753
  const sourcePath = path.join(sourceDir, relPath);
722
754
  let entries;
723
755
  try {
724
- entries = await fs.readdir(sourcePath);
756
+ entries = await withSlot(() => fs.readdir(sourcePath));
725
757
  } catch (err) {
726
758
  if (err.code === "ENOENT") return;
727
759
  consola.debug(`mirrorDirRecursive: cannot readdir ${sourcePath}:`, err);
728
760
  return;
729
761
  }
730
- for (const name of entries) {
762
+ await Promise.all(entries.map(async (name) => {
731
763
  if (relPath === "") {
732
764
  const policy = policyFor(name);
733
- if (policy === "ISOLATED" || policy === "SHARED") continue;
765
+ if (policy === "ISOLATED" || policy === "SHARED") return;
734
766
  }
735
767
  const childRel = relPath === "" ? name : path.join(relPath, name);
736
- if (relPath === "agents" && PEER_AGENT_MD_FILENAME.test(name)) continue;
768
+ if (relPath === "agents" && PEER_AGENT_MD_FILENAME.test(name)) return;
737
769
  const childSource = path.join(sourceDir, childRel);
738
770
  const childTarget = path.join(targetDir, childRel);
739
771
  let stats;
740
772
  try {
741
- stats = await fs.lstat(childSource);
773
+ stats = await withSlot(() => fs.lstat(childSource));
742
774
  } catch (err) {
743
775
  consola.debug(`mirrorDirRecursive: cannot lstat ${childSource}:`, err);
744
- continue;
776
+ return;
745
777
  }
746
778
  if (stats.isSymbolicLink()) {
747
779
  consola.debug(`mirrorDirRecursive: skipping symlink ${childSource} (security policy)`);
748
- continue;
780
+ return;
749
781
  }
750
782
  if (stats.isDirectory()) {
751
- await fs.mkdir(childTarget, { recursive: true });
752
- await mirrorDirRecursive(sourceDir, targetDir, childRel);
753
- continue;
783
+ await withSlot(() => fs.mkdir(childTarget, { recursive: true }));
784
+ await mirrorDirRecursive(sourceDir, targetDir, childRel, withSlot);
785
+ return;
754
786
  }
755
787
  if (stats.isFile()) {
756
788
  let needsCopy = true;
757
789
  try {
758
- const targetStat = await fs.lstat(childTarget);
790
+ const targetStat = await withSlot(() => fs.lstat(childTarget));
759
791
  if (targetStat.isFile() && targetStat.mtimeMs >= stats.mtimeMs) needsCopy = false;
760
792
  } catch (err) {
761
793
  if (err.code !== "ENOENT") consola.debug(`mirrorDirRecursive: lstat target ${childTarget}:`, err);
762
794
  }
763
- if (!needsCopy) continue;
795
+ if (!needsCopy) return;
764
796
  try {
765
- await fs.copyFile(childSource, childTarget, fs.constants.COPYFILE_FICLONE);
797
+ await withSlot(() => fs.copyFile(childSource, childTarget, fs.constants.COPYFILE_FICLONE));
766
798
  } catch (err) {
767
799
  consola.debug(`mirrorDirRecursive: copy ${childSource} → ${childTarget}:`, err);
768
800
  }
769
- continue;
801
+ return;
770
802
  }
771
- }
803
+ }));
772
804
  }
773
805
  /**
774
806
  * Create or refresh a directory symlink `<mirrorDir>/<name>` →
@@ -1110,4 +1142,4 @@ async function removeOwnClaudeConfigMirror() {
1110
1142
  //#endregion
1111
1143
  export { isUnderClaudeConfigMirror as a, sweepStalePeerAgentMdFiles as c, writeRuntimeFileSecure as d, ensurePaths as i, sweepStaleRuntimeFiles as l, PEER_AGENT_MD_FILENAME as n, removeOwnClaudeConfigMirror as o, ensureClaudeConfigMirror as r, sweepStaleClaudeConfigMirrors as s, PATHS as t, writeArtifactCredsToMirror as u };
1112
1144
 
1113
- //# sourceMappingURL=paths-BjTMI_xK.js.map
1145
+ //# sourceMappingURL=paths-C1cLZ7Ga.js.map