github-router 0.3.66 → 0.3.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,10 +34,10 @@ The server runs at `http://localhost:8787`. Now pick your tool below.
34
34
  npx github-router@latest claude
35
35
  ```
36
36
 
37
- Boots the proxy on a random port and spawns Claude Code wired to it. Sets `ANTHROPIC_MODEL=claude-opus-4-7` (Anthropic's dashed slug — Claude Code's `/model` UI displays this as menu entry "Opus 4.7 (1M context)"). The proxy translates to Copilot's `claude-opus-4.7-1m-internal` on enterprise tokens or `claude-opus-4.7` on Pro+/Business/Max at request time. Major.minor fallback chain: `claude-opus-4-6` → `claude-opus-4-5`. Override with `-m`:
37
+ Boots the proxy on a random port and spawns Claude Code wired to it. Sets `ANTHROPIC_MODEL=claude-opus-4-8` (Anthropic's dashed slug — Claude Code's `/model` UI displays this as menu entry "Opus 4.8 (1M context)"). The proxy translates to Copilot's `claude-opus-4.8` at request time (single base slug; the catalog entry's `max_context_window_tokens` already advertises 1M context — no `-1m` sibling needed for 4.8). Major.minor fallback chain: `claude-opus-4-7` → `claude-opus-4-6` → `claude-opus-4-5`. Override with `-m`:
38
38
 
39
39
  ```sh
40
- npx github-router@latest claude -m claude-opus-4-7
40
+ npx github-router@latest claude -m claude-opus-4-8
41
41
  ```
42
42
 
43
43
  The launcher sanitizes parent-env auth keys and sets `CLAUDE_CONFIG_DIR=$HOME/.claude` so the spawned `claude` ignores any persisted Console OAuth credential without requiring `claude /logout`. Settings, MCP servers, hooks, and CLAUDE.md auto-discovery still load from `~/.claude` as normal.
@@ -85,7 +85,7 @@ Each persona is exposed both as a Claude Code subagent (callable via the `Task`
85
85
  |---|---|---|---|
86
86
  | `codex-critic` | gpt-5.5 | `/v1/responses` | low \| medium \| high \| xhigh (xhigh) |
87
87
  | `codex-reviewer` | gpt-5.3-codex | `/v1/responses` | low \| medium \| high \| xhigh (xhigh) |
88
- | `opus-critic` | claude-opus-4-7 | `/v1/messages` | low \| medium \| high \| xhigh (xhigh) |
88
+ | `opus-critic` | claude-opus-4-6 | `/v1/messages` | low \| medium \| high (high) |
89
89
  | `gemini-critic` | gemini-3.1-pro-preview | `/v1/chat/completions` | low \| medium \| high (high) |
90
90
  | `peer-review-coordinator` | (meta) | — | — |
91
91
 
@@ -169,6 +169,7 @@ Anthropic endpoints are only available under `/v1/messages`.
169
169
  | gpt-4.1, gpt-4o | Yes | Yes | No |
170
170
  | gpt-5.5, gpt-5.4 | No | Yes | No |
171
171
  | gpt-5.3-codex, gpt-5.2-codex | No | Yes | No |
172
+ | claude-opus-4.8 (1M context as the single base slug) | Yes | No | Yes |
172
173
  | claude-opus-4.7-1m-internal (enterprise), claude-opus-4.7 | Yes | No | Yes |
173
174
  | claude-opus-4.6-1m, claude-opus-4.6, claude-sonnet-4.6 | Yes | No | Yes |
174
175
  | o3, o4-mini | Yes | Yes | No |
@@ -234,7 +235,7 @@ github-router debug Print diagnostic info
234
235
 
235
236
  The `claude` and `codex` subcommands accept all the shared flags below plus `-m`/`--model` to override the default model. Default models live in `src/lib/port.ts`:
236
237
 
237
- - `claude` → `claude-opus-4-7` (Anthropic dashed slug for UI compatibility; the proxy translates to Copilot's `claude-opus-4.7-1m-internal` on enterprise or `claude-opus-4.7` elsewhere). Major.minor fallback chain: `claude-opus-4-6` → `claude-opus-4-5`.
238
+ - `claude` → `claude-opus-4-8` (Anthropic dashed slug for UI compatibility; the proxy translates to Copilot's `claude-opus-4.8` the single base slug already advertises 1M context via `max_context_window_tokens`, so no `-1m` sibling exists). Major.minor fallback chain: `claude-opus-4-7` → `claude-opus-4-6` → `claude-opus-4-5`.
238
239
  - `codex` → `gpt-5.5` → `gpt-5.4` → `gpt-5.3-codex` → `gpt-5.2-codex`
239
240
 
240
241
  Fallback chains fire only on the implicit-default path; explicit `-m`/`--model` is always respected as-is.
@@ -257,7 +258,7 @@ Additional flags accepted only by the `claude` subcommand:
257
258
 
258
259
  | Flag | Description | Default |
259
260
  |---|---|---|
260
- | `--model, -m` | Override the default Claude model | claude-opus-4-7 |
261
+ | `--model, -m` | Override the default Claude model | claude-opus-4-8 |
261
262
  | `--codex-mcp` / `--no-codex-mcp` | Wire peer-MCP review subagents (codex-critic / opus-critic / gemini-critic / codex-reviewer / peer-review-coordinator) into the spawned session | true |
262
263
  | `--codex-cli` | Add a `codex mcp-server` stdio backend so `codex-implementer` can mutate files. Requires codex CLI 0.129+; falls back to HTTP-only if absent | false |
263
264
  | `--codex-mcp-only` | Pass `--strict-mcp-config` to Claude Code so only the proxy's MCP servers load (hides any user MCP servers in `~/.claude/mcp.json`) | false |
@@ -2,7 +2,7 @@
2
2
  "manifest_version": 3,
3
3
  "name": "github-router browser bridge",
4
4
  "short_name": "gh-router-browser",
5
- "version": "0.3.66",
5
+ "version": "0.3.68",
6
6
  "description": "Bridge between Claude (via github-router /mcp) and the browser. Implements tab control, navigation, clicks, form fill, downloads, screenshots, devtools eval. Blocks navigation to chrome://settings.",
7
7
  "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqJElxuBlonBS3TVW9FJN0mGTtShB3L1hoaYf6k39SOr1ogGYmF90EjRxy1i21k9wQQjPf26bcBu/9X67KrQjQV0uB38CaNukgiSeoLjfptN811u+PJHx6BP+jx3Qa6/3VenNPxHC8WEU0GXql8QSjIHEyCwKb6fMASXOK94JyB5Ywov2x8mt/+9ncqBBBMVzf6r5Sagy4PL1XnryLsuADD/vOEkPet8wXgH/Oj7v5tTsQQZ7U1JT51PoDs2BFnXc5v3TkVgZwd32k3ONh+nkDw1Hof+4zwUGOyJE6eMrlYzRlKM4Qxdf9JpavQvqfieAbTRWcyKeclnHeoIfE7cDBQIDAQAB",
8
8
  "background": {
package/dist/main.js CHANGED
@@ -931,15 +931,34 @@ async function autoUpdateClaude(latestVersion) {
931
931
  //#endregion
932
932
  //#region src/lib/port.ts
933
933
  const DEFAULT_PORT = 8787;
934
- const DEFAULT_CLAUDE_MODEL_FALLBACKS = ["claude-opus-4-6", "claude-opus-4-5"];
934
+ const DEFAULT_CLAUDE_MODEL_FALLBACKS = [
935
+ "claude-opus-4-7",
936
+ "claude-opus-4-6",
937
+ "claude-opus-4-5"
938
+ ];
935
939
  /**
936
940
  * Cap-aware default picker for `ANTHROPIC_MODEL` on the implicit-default
937
941
  * path. Returns `claude-opus-${family}[1m]` when the live Copilot catalog
938
- * contains an `opus-${family}-1m*` variant (enterprise tier), else the
939
- * bare `claude-opus-${family}` slug. `family` defaults to `"4.7"` so the
940
- * no-arg call preserves the original behavior; explicit values like
941
- * `"4.6"` or `"4.8"` are used to honor the `github-router claude
942
- * -m <version>` family shorthand.
942
+ * shows the family is 1M-capable, else the bare `claude-opus-${family}`
943
+ * slug. `family` defaults to `"4.8"` so the no-arg call selects the
944
+ * current default; explicit values like `"4.7"` or `"4.6"` are used to
945
+ * honor the `github-router claude -m <version>` family shorthand.
946
+ *
947
+ * **Dual-signal 1M detection**. The Opus families have evolved different
948
+ * shapes in Copilot's catalog over time:
949
+ * 1. **Sibling-slug signal** — `opus-${family}-1m` (or `opus-${family}-1m-internal`)
950
+ * exists as a separate catalog entry distinct from the base slug.
951
+ * This is how 4.6 and 4.7 ship (`claude-opus-4.6-1m`,
952
+ * `claude-opus-4.7-1m-internal`). Matched by the version-anchored
953
+ * regex below.
954
+ * 2. **Base-slug capability signal** — the catalog entry whose id IS
955
+ * the base `opus-${family}` slug advertises
956
+ * `capabilities.limits.max_context_window_tokens >= 1_000_000`. This
957
+ * is how 4.8 ships — there is no `-1m` sibling; the single
958
+ * `claude-opus-4.8` id is the 1M variant.
959
+ * Either signal flips on the `[1m]` decoration. Both signals together
960
+ * also flip it on (no double-counting). The breadcrumb log names which
961
+ * signal fired so users can spot catalog shape changes.
943
962
  *
944
963
  * The `[1m]` literal-bracket suffix is Claude Code's local 1M-context
945
964
  * unlock — cc-backup `src/utils/context.ts:35-40` matches `/\[1m\]/i`
@@ -949,14 +968,14 @@ const DEFAULT_CLAUDE_MODEL_FALLBACKS = ["claude-opus-4-6", "claude-opus-4-5"];
949
968
  * proxy routes the underlying request.
950
969
  *
951
970
  * Cap-awareness matters because on non-enterprise Copilot tiers there
952
- * is no `-1m` opus backend; sending `[1m]` there would either 400 at
971
+ * is no 1M opus backend; sending `[1m]` there would either 400 at
953
972
  * Copilot or (with `resolveModel`'s graceful-degrade) silently
954
973
  * downgrade upstream while Claude Code still over-accounts context.
955
974
  * This helper detects the catalog state at launch and only opts in
956
975
  * when the backend can actually serve 1M.
957
976
  *
958
977
  * Sonnet/Haiku families are intentionally NOT given `[1m]` defaults
959
- * because Copilot has no `-1m` backend for them (and Anthropic-side
978
+ * because Copilot has no 1M backend for them (and Anthropic-side
960
979
  * `modelSupports1M` doesn't list haiku at all). See
961
980
  * `src/lib/server-setup.ts:getClaudeCodeEnvVars` for the
962
981
  * `ANTHROPIC_DEFAULT_{SONNET,HAIKU,OPUS}_MODEL` tier defaults.
@@ -966,18 +985,25 @@ const DEFAULT_CLAUDE_MODEL_FALLBACKS = ["claude-opus-4-6", "claude-opus-4-5"];
966
985
  * can't tell the difference between "no catalog yet" and "no 1M
967
986
  * variant" — defaulting safe-side preserves the pre-change behavior).
968
987
  */
969
- const DEFAULT_OPUS_FAMILY = "4.7";
988
+ const DEFAULT_OPUS_FAMILY = "4.8";
989
+ const ONE_M_TOKENS = 1e6;
970
990
  function pickClaudeDefault(opusFamily = DEFAULT_OPUS_FAMILY) {
971
991
  const dotted = opusFamily.replace(/-/g, ".");
972
992
  const bareSlug = `claude-opus-${dotted.replace(/\./g, "-")}`;
973
993
  const versionPattern = dotted.replace(/\./g, "[.-]");
974
994
  const oneMRegex = new RegExp(`opus-${versionPattern}-1m(?:$|-)`, "i");
995
+ const baseSlugRegex = new RegExp(`^claude-opus-${versionPattern}$`, "i");
975
996
  const familyRegex = new RegExp(`opus-${versionPattern}(?:$|[-.])`, "i");
976
997
  const models$1 = state.models?.data ?? [];
977
- const has1m = models$1.some((m) => oneMRegex.test(m.id));
998
+ const siblingOneM = models$1.some((m) => oneMRegex.test(m.id));
999
+ const baseSlugMaxContext = models$1.reduce((max, m) => baseSlugRegex.test(m.id) ? Math.max(max, m.capabilities?.limits?.max_context_window_tokens ?? 0) : max, 0);
1000
+ const baseSlugOneM = baseSlugMaxContext >= ONE_M_TOKENS;
1001
+ const has1m = siblingOneM || baseSlugOneM;
978
1002
  if (opusFamily !== DEFAULT_OPUS_FAMILY && state.models && models$1.length > 0 && !models$1.some((m) => familyRegex.test(m.id))) consola.warn(`Requested Opus family "${dotted}" not found in Copilot catalog; using "${bareSlug}" anyway (resolveModel may not find a backend for it).`);
979
1003
  if (has1m) {
980
- consola.info(`Catalog contains opus-${dotted}-1m variant; defaulting ANTHROPIC_MODEL to "${bareSlug}[1m]" so Claude Code accounts for 1M context locally. Set CLAUDE_CODE_DISABLE_1M_CONTEXT=1 to opt out (HIPAA), or pass --model ${bareSlug} to pin 200K.`);
1004
+ const signal = siblingOneM ? baseSlugOneM ? "sibling-slug + base-slug 1M capability" : `sibling slug opus-${dotted}-1m` : `base slug ${bareSlug} (max_context_window_tokens=${baseSlugMaxContext})`;
1005
+ const pinHint = siblingOneM ? ` Pass --model ${bareSlug} to pin 200K.` : ` (No separate 200K variant of ${dotted} exists in the catalog — the bare slug IS the 1M backend.)`;
1006
+ consola.info(`Catalog signals opus-${dotted} is 1M-capable (${signal}); defaulting ANTHROPIC_MODEL to "${bareSlug}[1m]" so Claude Code accounts for 1M context locally. Set CLAUDE_CODE_DISABLE_1M_CONTEXT=1 to opt out (HIPAA).${pinHint}`);
981
1007
  return `${bareSlug}[1m]`;
982
1008
  }
983
1009
  return bareSlug;
@@ -8494,17 +8520,21 @@ function browserToolsEnabled() {
8494
8520
  return hasSupportedBrowserInstalled();
8495
8521
  }
8496
8522
  /**
8497
- * The 1M-context Opus variant (`claude-opus-4.7-1m-internal`,
8498
- * `max_prompt_tokens` 936K), gated `restricted_to: ["enterprise"]`.
8499
- * opus_critic prefers it so it can take large artifacts in one shot
8523
+ * The 1M-context Opus 4.6 variant (`claude-opus-4.6-1m`, `max_prompt_tokens`
8524
+ * 936K). opus_critic prefers it so it can take large artifacts in one shot
8500
8525
  * (the whole point of pairing it with gpt-5.5 as the big-window peers);
8501
- * falls back to the 200K `claude-opus-4-7` when the catalog (non-
8502
- * enterprise) doesn't carry a 1M opus slug.
8503
- */
8504
- const OPUS_1M_RE = /opus-4\.7.*1m/i;
8526
+ * falls back to the 200K `claude-opus-4-6` when the catalog doesn't carry
8527
+ * a 1M 4.6 slug. The regex is version-anchored to 4.6 AND requires a
8528
+ * `-1m` suffix boundary (not a permissive `.*1m`), so it does NOT
8529
+ * false-positive on `claude-opus-4.7-1m-internal` (stand_in's pinned
8530
+ * 4.7 row), `claude-opus-4.6-1max` (hypothetical), or `claude-opus-4.8`
8531
+ * (1M-without-sibling). Tolerates dotted (`opus-4.6-1m`) and dashed
8532
+ * (`opus-4-6-1m`) catalog separators.
8533
+ */
8534
+ const OPUS_1M_RE = /opus-4[.-]6-1m(?:$|-)/i;
8505
8535
  function resolveOpusCriticModel() {
8506
8536
  const oneM = state.models?.data?.find((m) => OPUS_1M_RE.test(m.id));
8507
- return oneM ? oneM.id : "claude-opus-4-7";
8537
+ return oneM ? oneM.id : "claude-opus-4-6";
8508
8538
  }
8509
8539
  function activePersonas() {
8510
8540
  return PERSONAS_READ.filter((p) => !p.requiresGeminiCatalog || geminiAvailable()).map((p) => p.toolNameHttp === "opus_critic" ? {
@@ -8600,6 +8630,8 @@ function toolError(message) {
8600
8630
  * gpt-5.3-codex high on ~600B = 16.0s → ~64s on 12KB
8601
8631
  * claude-opus-4-7 medium (thinking=3000) on a trivial prompt = 22.5s
8602
8632
  * but model self-paces budget → ~50s+ on a real ~6KB review
8633
+ * (still applicable to stand_in's 4.7 row; opus_critic now runs on
8634
+ * 4.6 with similar empirical shape)
8603
8635
  *
8604
8636
  * Returns `{tooLong: true, capBytes}` when the (persona, effort, briefBytes)
8605
8637
  * tuple is empirically predicted to bust the 60s ceiling.
@@ -12082,10 +12114,11 @@ function round2(n) {
12082
12114
  * **xhigh on long-running personas works via SSE-streamed /mcp responses**
12083
12115
  * (handler.ts:handleToolsCallSSE). Claude Code's MCP HTTP client honors
12084
12116
  * `text/event-stream` responses without applying the ~60s per-tool-call
12085
- * timer that previously broke xhigh on gpt-5.5 (~56s wall) and
12086
- * claude-opus-4-7 (high+ thinking budgets). All four personas now expose
12087
- * all four effort tiers with `high` default; SSE handles the long tail
12088
- * transparently to the user.
12117
+ * timer that previously broke xhigh on gpt-5.5 (~56s wall) and on
12118
+ * Anthropic Opus families (high+ thinking budgets). opus-critic itself
12119
+ * now runs on claude-opus-4-6 which doesn't advertise xhigh, so the
12120
+ * SSE long-tail concern there is moot; the SSE machinery still applies
12121
+ * to the other personas that do expose xhigh.
12089
12122
  */
12090
12123
  const EFFORT_LEVELS = [
12091
12124
  "low",
@@ -12263,9 +12296,9 @@ const PERSONAS_READ = Object.freeze([
12263
12296
  {
12264
12297
  agentName: "opus-critic",
12265
12298
  toolNameHttp: "opus_critic",
12266
- model: "claude-opus-4-7",
12299
+ model: "claude-opus-4-6",
12267
12300
  endpoint: "/v1/messages",
12268
- description: "Adversarial second opinion from a fresh-context Opus 4.7 — same lab as the lead, limited blind-spot diversity vs cross-lab critics. On enterprise catalogs that carry Opus-4.7-1M it runs with a ≈936K-token input window and handles large artifacts without decomposition; otherwise ≈168K. Fast (~22s), catches confabulation and motivated reasoning. Pass artifact verbatim.",
12301
+ description: "Adversarial second opinion from a fresh-context Opus 4.6 — same lab as the lead, limited blind-spot diversity vs cross-lab critics. On enterprise catalogs that carry Opus-4.6-1M it runs with a ≈936K-token input window; otherwise ≈168K. Pinned one minor behind the default Opus so the panel spans more of the version curve. Catches confabulation. Pass artifact verbatim.",
12269
12302
  baseInstructions: OPUS_CRITIC_BASE,
12270
12303
  agentPrompt: "",
12271
12304
  writeCapable: false,
@@ -12273,10 +12306,9 @@ const PERSONAS_READ = Object.freeze([
12273
12306
  allowedEfforts: [
12274
12307
  "low",
12275
12308
  "medium",
12276
- "high",
12277
- "xhigh"
12309
+ "high"
12278
12310
  ],
12279
- defaultEffort: "xhigh"
12311
+ defaultEffort: "high"
12280
12312
  }
12281
12313
  ]);
12282
12314
  const PERSONAS_WRITE = Object.freeze([{
@@ -13855,7 +13887,7 @@ function initProxyFromEnv() {
13855
13887
  //#endregion
13856
13888
  //#region package.json
13857
13889
  var name = "github-router";
13858
- var version$1 = "0.3.66";
13890
+ var version$1 = "0.3.68";
13859
13891
 
13860
13892
  //#endregion
13861
13893
  //#region src/lib/approval.ts
@@ -15792,10 +15824,10 @@ function getClaudeCodeEnvVars(serverUrl, model) {
15792
15824
  DISABLE_TELEMETRY: "1"
15793
15825
  };
15794
15826
  if (model) vars.ANTHROPIC_MODEL = model;
15795
- if (process.env.ANTHROPIC_SMALL_FAST_MODEL === void 0) vars.ANTHROPIC_SMALL_FAST_MODEL = "claude-haiku-4-5";
15827
+ if (process.env.ANTHROPIC_SMALL_FAST_MODEL === void 0) vars.ANTHROPIC_SMALL_FAST_MODEL = "claude-sonnet-4-6";
15796
15828
  if (process.env.ANTHROPIC_DEFAULT_SONNET_MODEL === void 0) vars.ANTHROPIC_DEFAULT_SONNET_MODEL = "claude-sonnet-4-6";
15797
15829
  if (process.env.ANTHROPIC_DEFAULT_HAIKU_MODEL === void 0) vars.ANTHROPIC_DEFAULT_HAIKU_MODEL = "claude-haiku-4-5";
15798
- if (process.env.ANTHROPIC_DEFAULT_OPUS_MODEL === void 0) vars.ANTHROPIC_DEFAULT_OPUS_MODEL = "claude-opus-4-7";
15830
+ if (process.env.ANTHROPIC_DEFAULT_OPUS_MODEL === void 0) vars.ANTHROPIC_DEFAULT_OPUS_MODEL = "claude-opus-4-8";
15799
15831
  if (process.env.CLAUDE_CODE_PLAN_V2_AGENT_COUNT === void 0) vars.CLAUDE_CODE_PLAN_V2_AGENT_COUNT = "7";
15800
15832
  for (const key of [
15801
15833
  "CLAUDE_CODE_ENABLE_EXPERIMENTAL_ADVISOR_TOOL",