github-router 0.3.249 → 0.3.250

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.
@@ -183,7 +183,14 @@ async function toolScreenshot(args) {
183
183
  // reason. Real Chrome with a visible window has a surface and works
184
184
  // fine. If you're driving Chrome-for-Testing programmatically and
185
185
  // need screenshots, launch with `--headless=new`.
186
- const dataUrl = await chrome.tabs.captureVisibleTab(windowId, { format })
186
+ // `quality` (1-100) applies to JPEG only; Chrome ignores it for PNG. It is the
187
+ // model's lever for shrinking a capture when a full-size one is refused for
188
+ // exceeding a model's image-size limit — without it, "retake it smaller" is
189
+ // advice the caller cannot act on. An older extension build that predates this
190
+ // simply ignores the extra key and captures at default quality.
191
+ const captureOpts = { format }
192
+ if (typeof args.quality === "number") captureOpts.quality = args.quality
193
+ const dataUrl = await chrome.tabs.captureVisibleTab(windowId, captureOpts)
187
194
  // dataUrl: "data:image/png;base64,...."
188
195
  const m = /^data:([^;]+);base64,(.*)$/.exec(dataUrl)
189
196
  if (!m) throw new Error("browser_screenshot: captureVisibleTab returned unexpected shape")
@@ -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.249",
5
+ "version": "0.3.250",
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": {
@@ -0,0 +1,2 @@
1
+ import { W as runWorkerAgent } from "./peer-mcp-personas-BvommiSI.js";
2
+ export { runWorkerAgent };
package/dist/main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { $ as searchWeb, $t as DEFAULT_CLAUDE_MODEL_FALLBACKS, A as trustRepo, An as state, At as getTokenCount, Bt as hasSupportedBrowserInstalled, C as fileLastPromptStore, Cn as fetchWithTransientRetry, Ct as scoutModel, D as repoRoot, Dn as copilotBaseUrl, Dt as shimDefaultsToXhigh, E as repoFingerprint, En as GITHUB_API_BASE_URL, Et as workerToolsEnabled, Ft as createChatCompletions, G as buildEnv, Gt as CONDENSED_OPERATING_SEQUENCE, Ht as extractTarGzMember, It as MAX_RESPONSE_BODY_BYTES, J as toolbeltEnabled, Jt as ArtifactClient, K as availableToolCommands, Kt as DEFINITION_OF_GREATNESS, Lt as readResponseBodyCapped, M as resolveSealedGate, Mt as resolveMcpToolTimeoutMs, Nt as pickEndpoint, O as stopGateEnabledForRepo, On as copilotHeaders, Ot as countTokens, Pt as createResponses, Q as assetFor, Qt as toolbeltPathOverride, Rt as parseJsonOrDiagnose, S as fileFindingsStore, Sn as getGitHubUser, St as reviewerModel, T as isSubagentContext, Tn as forwardError, Tt as standInToolEnabled, Ut as extractZipMember, Vt as provisionAndIndexColbert, Wt as warmTreeSitterPool, X as vscodeRipgrepPath, Xt as buildWorkspaceHeaderJson, Y as toolbeltSkipSet, Yt as buildWorkspaceHeaderHelperCommand, Z as TOOLBELT_TOOLS, Zt as collapsePathKeys, _ as stopGateDisabled, _n as isNullish, _t as browserCompoundToolsEnabled, a as buildPeerAwarenessSnippet, an as generateRandomPort, at as buildAnthropicErrorEvent, b as stopReviewEnabled, bn as sleep$1, bt as geminiAvailable, c as personasFor, cn as withInstallLock, ct as logStreamError, d as buildStopHookCommand, dn as setupGitHubToken, dt as handleMcpDelete, en as DEFAULT_CODEX_MODEL, et as ADVISOR_INTERNAL_TOOL_NAME, f as captureLaunchBaseline, fn as tryRefreshAndRetry, ft as handleMcpPost, g as launchBaselineKey, gn as filterBetaHeader, gt as browseAgentEnabled, h as injectStopHookIntoSettingsFile, hn as cacheVSCodeVersion, ht as brainstormModel, i as buildAgentPrompt, in as UPSTREAM_INACTIVITY_TIMEOUT_MS, it as isAdvisorRequested, j as liveExec, jt as assembleResponsesPayload, k as stopReviewStateDir, kn as githubHeaders, kt as createMessages, l as buildArtifactOpenHookCommand, ln as setupCopilotToken, lt as readIteratorWithTimeout, m as fileBlockBudget, mn as cacheModels, mt as artifactToolsEnabled, n as MCP_GROUPS, nt as buildAdvisorStream, o as buildPeerAwarenessSummary, on as pickClaudeDefault, ot as buildOpenAIErrorEvent, p as decideStopHook, pn as cacheCopilotVersion, pt as agentToolsEnabled, q as buildToolbeltAwareness, qt as shouldUseInsecureTls, r as assertMcpToolSurfaceConsistent, rn as UPSTREAM_FETCH_TIMEOUT_MS, rt as injectAdvisorTool, s as enumerateInjectedMcpToolNames, sn as getPackageVersion$1, st as isControllerClosedError, t as GROUP_META, tn as DEFAULT_CODEX_MODEL_FALLBACKS, tt as ADVISOR_TOOL_INSTRUCTIONS, u as buildSessionBindHookCommand, un as setupGitHubAgentToken, ut as relayAnthropicStream, v as stopGateId, vn as resolveCodexModel, vt as browserToolsEnabled, w as fileReviewDebounce, wn as HTTPError, wt as scribeModel, x as fileBaselineStore, xn as getModels, xt as nativeSubagentModel, y as stopGatePlanMode, yn as resolveModel, yt as fleetToolsEnabled, zt as provisionBrowserAssets } from "./peer-mcp-personas-DJzLpfDJ.js";
2
+ import { $ as searchWeb, $t as DEFAULT_CLAUDE_MODEL_FALLBACKS, A as trustRepo, An as state, At as getTokenCount, Bt as hasSupportedBrowserInstalled, C as fileLastPromptStore, Cn as fetchWithTransientRetry, Ct as scoutModel, D as repoRoot, Dn as copilotBaseUrl, Dt as shimDefaultsToXhigh, E as repoFingerprint, En as GITHUB_API_BASE_URL, Et as workerToolsEnabled, Ft as createChatCompletions, G as buildEnv, Gt as CONDENSED_OPERATING_SEQUENCE, Ht as extractTarGzMember, It as MAX_RESPONSE_BODY_BYTES, J as toolbeltEnabled, Jt as ArtifactClient, K as availableToolCommands, Kt as DEFINITION_OF_GREATNESS, Lt as readResponseBodyCapped, M as resolveSealedGate, Mt as resolveMcpToolTimeoutMs, Nt as pickEndpoint, O as stopGateEnabledForRepo, On as copilotHeaders, Ot as countTokens, Pt as createResponses, Q as assetFor, Qt as toolbeltPathOverride, Rt as parseJsonOrDiagnose, S as fileFindingsStore, Sn as getGitHubUser, St as reviewerModel, T as isSubagentContext, Tn as forwardError, Tt as standInToolEnabled, Ut as extractZipMember, Vt as provisionAndIndexColbert, Wt as warmTreeSitterPool, X as vscodeRipgrepPath, Xt as buildWorkspaceHeaderJson, Y as toolbeltSkipSet, Yt as buildWorkspaceHeaderHelperCommand, Z as TOOLBELT_TOOLS, Zt as collapsePathKeys, _ as stopGateDisabled, _n as isNullish, _t as browserCompoundToolsEnabled, a as buildPeerAwarenessSnippet, an as generateRandomPort, at as buildAnthropicErrorEvent, b as stopReviewEnabled, bn as sleep$1, bt as geminiAvailable, c as personasFor, cn as withInstallLock, ct as logStreamError, d as buildStopHookCommand, dn as setupGitHubToken, dt as handleMcpDelete, en as DEFAULT_CODEX_MODEL, et as ADVISOR_INTERNAL_TOOL_NAME, f as captureLaunchBaseline, fn as tryRefreshAndRetry, ft as handleMcpPost, g as launchBaselineKey, gn as filterBetaHeader, gt as browseAgentEnabled, h as injectStopHookIntoSettingsFile, hn as cacheVSCodeVersion, ht as brainstormModel, i as buildAgentPrompt, in as UPSTREAM_INACTIVITY_TIMEOUT_MS, it as isAdvisorRequested, j as liveExec, jt as assembleResponsesPayload, k as stopReviewStateDir, kn as githubHeaders, kt as createMessages, l as buildArtifactOpenHookCommand, ln as setupCopilotToken, lt as readIteratorWithTimeout, m as fileBlockBudget, mn as cacheModels, mt as artifactToolsEnabled, n as MCP_GROUPS, nt as buildAdvisorStream, o as buildPeerAwarenessSummary, on as pickClaudeDefault, ot as buildOpenAIErrorEvent, p as decideStopHook, pn as cacheCopilotVersion, pt as agentToolsEnabled, q as buildToolbeltAwareness, qt as shouldUseInsecureTls, r as assertMcpToolSurfaceConsistent, rn as UPSTREAM_FETCH_TIMEOUT_MS, rt as injectAdvisorTool, s as enumerateInjectedMcpToolNames, sn as getPackageVersion$1, st as isControllerClosedError, t as GROUP_META, tn as DEFAULT_CODEX_MODEL_FALLBACKS, tt as ADVISOR_TOOL_INSTRUCTIONS, u as buildSessionBindHookCommand, un as setupGitHubAgentToken, ut as relayAnthropicStream, v as stopGateId, vn as resolveCodexModel, vt as browserToolsEnabled, w as fileReviewDebounce, wn as HTTPError, wt as scribeModel, x as fileBaselineStore, xn as getModels, xt as nativeSubagentModel, y as stopGatePlanMode, yn as resolveModel, yt as fleetToolsEnabled, zt as provisionBrowserAssets } from "./peer-mcp-personas-BvommiSI.js";
3
3
  import { a as isUnderClaudeConfigMirror, d as writeRuntimeFileSecure, i as ensurePaths, o as removeOwnClaudeConfigMirror, r as ensureClaudeConfigMirror, t as PATHS, u as writeArtifactCredsToMirror } from "./paths-BjTMI_xK.js";
4
4
  import { c as killManagedTree, d as resolveExecutable, f as runCommandCapture, l as parseBoolEnv, p as runCommandVoid, s as killChildProcessTree, u as parseIntEnv } from "./lifecycle-DHZsVN8j.js";
5
5
  import { a as sweepRegistry } from "./lifecycle-CUf1UDrH.js";
@@ -1397,7 +1397,7 @@ function buildPeerAgentDefinitions(opts) {
1397
1397
  ...modelField
1398
1398
  };
1399
1399
  out.reviewer = {
1400
- description: reviewerModel ? `Feedback subagent running ${reviewerModel}, a DIFFERENT lab from both the lead and the implementer, so its blind spots are decorrelated from whoever produced the work. Use proactively when something already exists and you want it assessed: a diff, a plan, a document, a failing test. Unlike the stateless peer critics, it reads the repo and can RUN things, so prefer it whenever the assessment needs execution or repo context (reproduce a failure, run the suite, bisect); prefer a peer critic when you already hold the artifact and want a fresh-context opinion on it. Model is overridable at spawn.` : `Feedback subagent (native tools, runs on the lead's model in its own context). Use proactively when something already exists and you want it assessed: a diff, a plan, a document, a failing test. Unlike the stateless peer critics, it reads the repo and can RUN things, so prefer it whenever the assessment needs execution or repo context; prefer a peer critic when you already hold the artifact and want a fresh-context opinion on it. Model is overridable at spawn.`,
1400
+ description: reviewerModel ? `Feedback subagent running ${reviewerModel}, a DIFFERENT lab from both the lead and the implementer, so its blind spots are decorrelated from whoever produced the work. Use proactively when something already exists and you want it assessed: a diff, a plan, a document, a failing test. Unlike the stateless peer critics, it reads the repo and can RUN things, so prefer it whenever the assessment needs execution or repo context (reproduce a failure, run the suite, bisect); prefer a peer critic when you already hold the artifact and want a fresh-context opinion on it. It can also REVIEW SCREENSHOTS and other images: just point it at the file and it will look at them (its model accepts up to 10 images per request, more than any other lane here). Model is overridable at spawn.` : `Feedback subagent (native tools, runs on the lead's model in its own context). Use proactively when something already exists and you want it assessed: a diff, a plan, a document, a failing test. Unlike the stateless peer critics, it reads the repo and can RUN things, so prefer it whenever the assessment needs execution or repo context; prefer a peer critic when you already hold the artifact and want a fresh-context opinion on it. Model is overridable at spawn.`,
1401
1401
  prompt: "You are a feedback subagent. Your job is to tell the caller what is actually true about the artifact you are given — code, a plan, a document, a failure report — and what is wrong with it. Verify against the ACTUAL code by reading it; never assume. Do whatever the assessment requires: reproduce a failure end to end as close to how a real user hits it as you can, form hypotheses and test them against the code and runtime, and isolate the true root cause rather than a symptom. Where the change warrants it, author tests that try to BREAK the implementation (edge cases, error paths, and the acceptance criteria as executable checks), run them, and report which pass and which fail; do NOT modify production code just to make tests pass. " + fileToolSteer("builds") + " Do the work yourself — do not spawn further subagents. Report severity-ranked findings with `file:line` citations, the evidence behind each, and end with a clear go/no-go.",
1402
1402
  ...reviewerModel ? { model: reviewerModel } : {}
1403
1403
  };
@@ -3088,7 +3088,7 @@ async function discoverGateCommands(cwd, opts) {
3088
3088
  if (files.length === 0) return null;
3089
3089
  let result;
3090
3090
  try {
3091
- const { runWorkerAgent } = await import("./engine-BuuHUb4t.js");
3091
+ const { runWorkerAgent } = await import("./engine-dOYoMQis.js");
3092
3092
  result = await runWorkerAgent({
3093
3093
  mode: "explore",
3094
3094
  workspace: root,
@@ -5561,7 +5561,7 @@ function initProxyFromEnv() {
5561
5561
  //#endregion
5562
5562
  //#region package.json
5563
5563
  var name = "github-router";
5564
- var version$1 = "0.3.249";
5564
+ var version$1 = "0.3.250";
5565
5565
  //#endregion
5566
5566
  //#region src/lib/approval.ts
5567
5567
  const awaitApproval = async () => {
@@ -6968,12 +6968,18 @@ function anthropicUsageFromChat(u) {
6968
6968
  * Map a chat/completions `finish_reason` to an Anthropic stop_reason. A
6969
6969
  * truncated (`length`) response is `max_tokens` even when a partial tool call
6970
6970
  * is present — the response was cut — mirroring the Responses egress precedence.
6971
- * `tool_calls` (or any buffered tool) → `tool_use`; everything else (`stop`,
6972
- * `content_filter`, null) → `end_turn`.
6971
+ * `tool_calls` (or any buffered tool) → `tool_use`.
6972
+ *
6973
+ * `content_filter` maps to Anthropic's `refusal`, NOT `end_turn`. It used to
6974
+ * collapse into `end_turn`, which made an upstream safety block indistinguishable
6975
+ * from a normal completion: the client saw a successful, usually empty, message
6976
+ * and had no way to tell that content had been withheld. `refusal` is the
6977
+ * documented Anthropic stop_reason for exactly this case.
6973
6978
  */
6974
6979
  function chatStopReason(finishReason, sawTool) {
6975
6980
  if (finishReason === "length") return "max_tokens";
6976
6981
  if (finishReason === "tool_calls" || sawTool) return "tool_use";
6982
+ if (finishReason === "content_filter") return "refusal";
6977
6983
  return "end_turn";
6978
6984
  }
6979
6985
  /**
@@ -6991,6 +6997,10 @@ function chatResponseToAnthropicMessage(resp, modelId) {
6991
6997
  type: "text",
6992
6998
  text: message.content
6993
6999
  });
7000
+ if (typeof message.refusal === "string" && message.refusal.length > 0) content.push({
7001
+ type: "text",
7002
+ text: message.refusal
7003
+ });
6994
7004
  if (Array.isArray(message.tool_calls)) for (const tc of message.tool_calls) {
6995
7005
  sawTool = true;
6996
7006
  const rawId = typeof tc.id === "string" ? tc.id : "";
@@ -7073,6 +7083,16 @@ async function* synthAnthropicFromChat(upstream, opts) {
7073
7083
  }
7074
7084
  yield makeTextDelta(activeTextIndex, delta.content);
7075
7085
  }
7086
+ if (delta && typeof delta.refusal === "string" && delta.refusal.length > 0) {
7087
+ if (activeTextIndex == null) {
7088
+ activeTextIndex = nextIndex++;
7089
+ yield makeContentBlockStart(activeTextIndex, {
7090
+ type: "text",
7091
+ text: ""
7092
+ });
7093
+ }
7094
+ yield makeTextDelta(activeTextIndex, delta.refusal);
7095
+ }
7076
7096
  if (delta && Array.isArray(delta.tool_calls) && delta.tool_calls.length > 0) {
7077
7097
  if (activeTextIndex != null) {
7078
7098
  yield makeContentBlockStop(activeTextIndex);