github-router 0.3.138 → 0.3.151

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/dist/main.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { $ as readIteratorWithTimeout, $t as state, At as generateRandomPort, B as toolbeltSkipSet, Bt as filterBetaHeader, C as repoRoot, Ct as toolbeltPathOverride, D as resolveSealedGate, Dt as DEFAULT_PORT, E as trustRepo, Et as DEFAULT_CODEX_MODEL_FALLBACKS, Ft as setupGitHubToken, G as ADVISOR_INTERNAL_TOOL_NAME, Gt as getModels, H as TOOLBELT_TOOLS, Ht as resolveCodexModel, It as tryRefreshAndRetry, J as injectAdvisorTool, Jt as forwardError, K as ADVISOR_TOOL_INSTRUCTIONS, Kt as fetchWithTransientRetry, L as availableToolCommands, Lt as cacheCopilotVersion, Mt as getPackageVersion, Nt as withInstallLock, O as liveExec, Ot as UPSTREAM_FETCH_TIMEOUT_MS, Pt as setupCopilotToken, Q as logStreamError, Qt as githubHeaders, R as buildToolbeltAwareness, Rt as cacheModels, S as repoFingerprint, St as collapsePathKeys, T as stopReviewStateDir, Tt as DEFAULT_CODEX_MODEL, U as assetFor, Ut as resolveModel, V as vscodeRipgrepPath, Vt as isNullish, W as searchWeb, Wt as sleep, X as buildOpenAIErrorEvent, Xt as copilotBaseUrl, Y as isAdvisorRequested, Yt as GITHUB_API_BASE_URL, Z as isControllerClosedError, Zt as copilotHeaders, _ as fileBaselineStore, _t as provisionAndIndexColbert, a as buildPeerAwarenessSnippet, at as standInToolEnabled, b as fileReviewDebounce, bt as shouldUseInsecureTls, c as buildSessionBindHookCommand, ct as createMessages, d as decideStopHook, dt as createChatCompletions, et as relayAnthropicStream, f as fileBlockBudget, ft as MAX_RESPONSE_BODY_BYTES, g as stopReviewEnabled, gt as hasSupportedBrowserInstalled, h as stopGateId, ht as provisionBrowserAssets, i as buildAgentPrompt, it as fleetToolsEnabled, jt as pickClaudeDefault, kt as UPSTREAM_INACTIVITY_TIMEOUT_MS, l as buildStopHookCommand, lt as getTokenCount, m as launchBaselineKey, mt as parseJsonOrDiagnose, n as MCP_GROUPS, nt as handleMcpPost, o as personasFor, ot as workerToolsEnabled, p as injectStopHookIntoSettingsFile, pt as readResponseBodyCapped, q as buildAdvisorStream, qt as HTTPError, r as assertMcpToolSurfaceConsistent, rt as browserToolsEnabled, s as buildArtifactOpenHookCommand, st as countTokens, t as GROUP_META, tt as handleMcpDelete, u as captureLaunchBaseline, ut as createResponses, v as fileFindingsStore, vt as extractTarGzMember, w as stopGateEnabledForRepo, wt as DEFAULT_CLAUDE_MODEL_FALLBACKS, x as isSubagentContext, xt as ArtifactClient, y as fileLastPromptStore, yt as extractZipMember, z as toolbeltEnabled, zt as cacheVSCodeVersion } from "./peer-mcp-personas-CThUmeHE.js";
3
- import { a as removeOwnClaudeConfigMirror, i as isUnderClaudeConfigMirror, l as writeArtifactCredsToMirror, n as ensureClaudeConfigMirror, r as ensurePaths, t as PATHS, u as writeRuntimeFileSecure } from "./paths-Cn5OzmYL.js";
4
- import { c as killManagedTree, d as runCommandCapture, f as runCommandVoid, l as parseBoolEnv, s as killChildProcessTree, u as resolveExecutable } from "./lifecycle-Cqe8OQVX.js";
5
- import { a as sweepRegistry } from "./lifecycle-CeVDX6av.js";
2
+ import { $ as logStreamError, $t as copilotBaseUrl, At as UPSTREAM_FETCH_TIMEOUT_MS, B as toolbeltEnabled, Bt as cacheCopilotVersion, C as repoFingerprint, Ct as ArtifactClient, D as trustRepo, Dt as DEFAULT_CODEX_MODEL, E as stopReviewStateDir, Et as DEFAULT_CLAUDE_MODEL_FALLBACKS, Ft as withInstallLock, G as searchWeb, Gt as resolveCodexModel, H as vscodeRipgrepPath, Ht as cacheVSCodeVersion, It as setupCopilotToken, J as buildAdvisorStream, Jt as getModels, K as ADVISOR_INTERNAL_TOOL_NAME, Kt as resolveModel, Lt as setupGitHubAgentToken, Mt as generateRandomPort, Nt as pickClaudeDefault, O as resolveSealedGate, Ot as DEFAULT_CODEX_MODEL_FALLBACKS, Pt as getPackageVersion, Q as isControllerClosedError, Qt as GITHUB_API_BASE_URL, R as availableToolCommands, Rt as setupGitHubToken, S as isSubagentContext, St as shouldUseInsecureTls, T as stopGateEnabledForRepo, Tt as toolbeltPathOverride, U as TOOLBELT_TOOLS, Ut as filterBetaHeader, V as toolbeltSkipSet, Vt as cacheModels, W as assetFor, Wt as isNullish, X as isAdvisorRequested, Xt as HTTPError, Y as injectAdvisorTool, Yt as fetchWithTransientRetry, Z as buildOpenAIErrorEvent, Zt as forwardError, _ as stopReviewEnabled, _t as provisionBrowserAssets, a as buildPeerAwarenessSnippet, at as browserToolsEnabled, b as fileLastPromptStore, bt as extractTarGzMember, c as buildSessionBindHookCommand, ct as workerToolsEnabled, d as decideStopHook, dt as getTokenCount, en as copilotHeaders, et as readIteratorWithTimeout, f as fileBlockBudget, ft as createResponses, g as stopGateId, gt as parseJsonOrDiagnose, h as stopGateDisabled, ht as readResponseBodyCapped, i as buildAgentPrompt, it as agentToolsEnabled, jt as UPSTREAM_INACTIVITY_TIMEOUT_MS, k as liveExec, kt as DEFAULT_PORT, l as buildStopHookCommand, lt as countTokens, m as launchBaselineKey, mt as MAX_RESPONSE_BODY_BYTES, n as MCP_GROUPS, nn as state, nt as handleMcpDelete, o as personasFor, ot as fleetToolsEnabled, p as injectStopHookIntoSettingsFile, pt as createChatCompletions, q as ADVISOR_TOOL_INSTRUCTIONS, qt as sleep, r as assertMcpToolSurfaceConsistent, rt as handleMcpPost, s as buildArtifactOpenHookCommand, st as standInToolEnabled, t as GROUP_META, tn as githubHeaders, tt as relayAnthropicStream, u as captureLaunchBaseline, ut as createMessages, v as fileBaselineStore, vt as hasSupportedBrowserInstalled, w as repoRoot, wt as collapsePathKeys, x as fileReviewDebounce, xt as extractZipMember, y as fileFindingsStore, yt as provisionAndIndexColbert, z as buildToolbeltAwareness, zt as tryRefreshAndRetry } from "./peer-mcp-personas-Dm3UCpXz.js";
3
+ import { a as removeOwnClaudeConfigMirror, i as isUnderClaudeConfigMirror, l as writeArtifactCredsToMirror, n as ensureClaudeConfigMirror, r as ensurePaths, t as PATHS, u as writeRuntimeFileSecure } from "./paths-D0tJ_tms.js";
4
+ import { c as killManagedTree, d as runCommandCapture, f as runCommandVoid, l as parseBoolEnv, s as killChildProcessTree, u as resolveExecutable } from "./lifecycle-DyEXZu2z.js";
5
+ import { a as sweepRegistry } from "./lifecycle-DGvk4z63.js";
6
6
  import { defineCommand, runMain } from "citty";
7
7
  import consola from "consola";
8
8
  import { createHash, randomBytes, randomUUID } from "node:crypto";
@@ -2036,7 +2036,7 @@ async function discoverGateCommands(cwd, opts) {
2036
2036
  if (files.length === 0) return null;
2037
2037
  let result;
2038
2038
  try {
2039
- const { runWorkerAgent } = await import("./engine-kSGZBPRK.js");
2039
+ const { runWorkerAgent } = await import("./engine-DBIfCSAl.js");
2040
2040
  result = await runWorkerAgent({
2041
2041
  mode: "explore",
2042
2042
  workspace: root,
@@ -2190,6 +2190,137 @@ function buildPromptSubmitHookCommand(execPath, scriptPath) {
2190
2190
  return `${q(execPath)} internal-prompt-submit`;
2191
2191
  }
2192
2192
 
2193
+ //#endregion
2194
+ //#region src/lib/injected-skills/first-mate-skill.ts
2195
+ const FIRST_MATE_SKILL = {
2196
+ name: "gh-first-mate",
2197
+ md: `---
2198
+ name: gh-first-mate
2199
+ description: Thin operating protocol for the first-mate GitHub cloud-agent controller: start missions, wake the durable controller loop, answer model and human requests, keep context compact, and report from the board/ledger rather than rereading full diffs or logs.
2200
+ user-invocable: true
2201
+ ---
2202
+
2203
+ # gh-first-mate: durable cloud-agent controller loop
2204
+
2205
+ Use this skill when the user wants first-mate to drive GitHub cloud coding agents across one or more repositories.
2206
+ The first-mate controller is the durable system of record: missions, units, decisions, handles, and controller state live in its registry and ledger.
2207
+ Your job is to run the thin protocol, not to hold the mission in context.
2208
+
2209
+ ## Start a mission
2210
+
2211
+ For a new goal, call mcp__first-mate__start_mission with:
2212
+
2213
+ - goal: the user's goal in one sentence.
2214
+ - repos: repository strings as owner/name.
2215
+ - acceptance_criteria: explicit user-blessed acceptance criteria.
2216
+ - priority and house_rules only when the user supplied them or they are necessary constraints.
2217
+
2218
+ If acceptance criteria are missing or ambiguous, ask the user before starting.
2219
+ Do not decompose the mission yourself at start time; v1 mission registration is intentionally simple and later controller wakes/model requests drive decomposition and steering.
2220
+
2221
+ Invariant (closes the stranding hole): work only ever becomes active inside a turn — start_mission is a tool call, nothing activates a mission server-side. So immediately after start_mission, run one loop turn (advance, then arm the heartbeat) in the SAME turn, before you yield. Never register a mission and stop without arming; otherwise nothing will wake to drive it.
2222
+
2223
+ ## Controller loop (push-based, self-driving)
2224
+
2225
+ The loop is push-based: each turn you DRAIN all ready work, then ARM the next wake and YIELD the turn. You never sit polling advance in a tight loop — that does not scale and wastes context. A durable heartbeat re-invokes this skill while the session is idle, and one advance call sweeps the WHOLE portfolio (every mission, every repo) at once, so a single heartbeat drives everything.
2226
+
2227
+ Each turn:
2228
+
2229
+ 1. Call mcp__first-mate__advance, batching any answers you already have.
2230
+ 2. Read the compact response: board, needsModel, needsHuman, applied_count, nextWakeAt, and nextWakeSeconds.
2231
+ 3. Answer every needsModel item with the typed verdict for its kind, and courier every needsHuman packet. If you produced any model_answers this turn, call advance again to apply them and pick up the resulting state. Stop this inner drain once advance returns no new needsModel you can answer without the user; keep it bounded (at most a few iterations), never a busy loop.
2232
+ 4. Manage the heartbeat from nextWakeSeconds (see "Self-driving heartbeat").
2233
+ 5. Report compactly from the board, then YIELD. Do not call advance again until the next scheduled wake or a new user message.
2234
+
2235
+ When submitting answers, batch what you have:
2236
+
2237
+ - model_answers: [{ requestId, verdict }]
2238
+ - human_decisions: [{ requestId, choice }]
2239
+
2240
+ Keep verdicts small and typed to the request kind.
2241
+
2242
+ ## Model request verdicts
2243
+
2244
+ Use the request's kind and payload as the contract:
2245
+
2246
+ - review_plan: review the plan against the mission goal, acceptance criteria, and house rules. Return { decision: "approve" } when the plan is good enough to implement, or { decision: "refine", instruction: "..." } with a short actionable refinement.
2247
+ - answer_agent_question: answer only from the acceptance criteria and supplied context. Return { answer: "..." }. If the answer is not derivable, do not invent policy; escalate by leaving a short answer that says what the human must decide.
2248
+ - author_fix: author a concise fix instruction for the cloud agent. Return { instruction: "..." } with the failure, expected behavior, and any bounded check to run.
2249
+ - judge_review: judge whether review/CI/floor evidence is sufficient. Return { pass: true } only when the acceptance criteria and floor are satisfied; otherwise return { pass: false } with a compact reason when useful.
2250
+
2251
+ Delegate heavy reading to workers:
2252
+
2253
+ - Use mcp__workers__explore for focused source or history gathering.
2254
+ - Use mcp__workers__review for compact review of a specific plan, PR summary, or suspicious change.
2255
+ - Use mcp__workers__test when a missing executable check is the blocker.
2256
+
2257
+ Do not read a full diff, full CI log, or full transcript in the lead context. Ask workers for narrow facts and compact excerpts. The ledger is durable memory; context is not.
2258
+
2259
+ ## Human requests
2260
+
2261
+ For each needsHuman item:
2262
+
2263
+ 1. If packetHtmlPath is present, open that HTML file in the ai-or-die artifact panel for the user.
2264
+ 2. Tell the user the reason, repo, issue/PR handles, and the available decision choices.
2265
+ 3. Wait for the user's decision.
2266
+ 4. Submit the choice back with mcp__first-mate__advance({ human_decisions: [...] }).
2267
+
2268
+ If an artifact-panel tool is unavailable, give the user the local packetHtmlPath and the compact summary from needsHuman.
2269
+ Never decide a merge approval or abandonment choice on the user's behalf.
2270
+
2271
+ ## Self-driving heartbeat (arm / disarm)
2272
+
2273
+ The loop keeps itself alive with ONE durable cron job — a dead-man's-switch that survives idle, compaction, restart, and /clear because it lives on disk, not in your context. The controller hands you nextWakeSeconds so you never do arithmetic: it is a ready-to-use delay in seconds, or null when the whole portfolio is idle. Every heartbeat carries the exact marker token [fm-heartbeat] in its prompt so you can identify it unambiguously (never a fuzzy match against unrelated crons). Manage exactly one heartbeat:
2274
+
2275
+ Arm — "create fresh, then reap the rest" (nextWakeSeconds is a number, i.e. there is active work):
2276
+
2277
+ 1. Pick the cadence bucket from nextWakeSeconds (fixed cron expressions, no time math), so the heartbeat tracks the controller's own cadence:
2278
+ - nextWakeSeconds <= 120 → "1-59/2 * * * *" (about every 2 min)
2279
+ - nextWakeSeconds <= 600 → "2,7,12,17,22,27,32,37,42,47,52,57 * * * *" (about every 5 min)
2280
+ - otherwise → "3,13,23,33,43,53 * * * *" (about every 10 min)
2281
+ 2. CronCreate the new heartbeat and capture its id: durable: true, recurring: true, the chosen cron, prompt "/gh-first-mate [fm-heartbeat] wake the controller loop, answer ready requests, reschedule." Creating first (before deleting) guarantees at least one heartbeat always exists.
2282
+ 3. CronList, then CronDelete every job whose prompt contains [fm-heartbeat] EXCEPT the id you just created. This converges to exactly one, reaps duplicates and old-version orphans, and — because you recreate each wake — resets the 7-day recurring-cron expiry so a long mission never silently stops.
2283
+
2284
+ Disarm (nextWakeSeconds is null AND there are no pending needsHuman): nothing is active. CronList and CronDelete every [fm-heartbeat] job. Report that first-mate is idle and resumes when the user next starts or advances a mission (safe because, per the Start-a-mission invariant, only a turn can reactivate work, and that turn re-arms).
2285
+
2286
+ Responsiveness (optional): the buckets above already tighten cadence to ~2 min for imminent work. If this session is a /loop you MAY additionally ScheduleWakeup(delaySeconds: nextWakeSeconds, ...) for an exact one-shot; keep at most one outstanding.
2287
+
2288
+ Guardrails: never leave more than one [fm-heartbeat] job; never busy-loop advance; if no scheduler tool is available, tell the user the next wake is in nextWakeSeconds seconds and stop.
2289
+
2290
+ ## Board reports
2291
+
2292
+ Use mcp__first-mate__board or mcp__first-mate__mission_status for read-only status checks.
2293
+ Report compactly:
2294
+
2295
+ - mission id and title
2296
+ - repositories
2297
+ - phase counts
2298
+ - blocked count and why, when available
2299
+ - next wake time or the next requested action
2300
+
2301
+ Never reconstruct status by rereading raw logs when the controller board already has the handles.
2302
+
2303
+ ## Context discipline
2304
+
2305
+ - The ledger is the durable memory; do not paste large artifacts into the chat.
2306
+ - Never read a full diff/log/transcript unless the user explicitly asks and it is essential.
2307
+ - Prefer handles: mission id, repo, issue, PR, request id, packet path.
2308
+ - Keep every answer to first-mate compact and action-oriented.
2309
+ - If controller state and chat memory disagree, trust the controller state and ask for clarification only when it affects acceptance criteria or human approval.
2310
+
2311
+ ## Return format
2312
+
2313
+ When reporting progress, return:
2314
+
2315
+ - Mission: id and one-line goal.
2316
+ - Board: compact phase counts and blocked count.
2317
+ - Applied: count or short list of important controller actions.
2318
+ - Needs model: request ids and kinds answered or pending.
2319
+ - Needs human: decision ids/packet paths and the user's required choice.
2320
+ - Next wake: the heartbeat state — armed and next check in nextWakeSeconds seconds, or idle (disarmed).
2321
+ `
2322
+ };
2323
+
2193
2324
  //#endregion
2194
2325
  //#region src/lib/injected-skills/floor-keeper-skill.ts
2195
2326
  const FLOOR_KEEPER_SKILL = {
@@ -3051,8 +3182,8 @@ const ERROR_CODE = "INJECTED_SKILL_WRITE";
3051
3182
  /**
3052
3183
  * Strict skill-name allowlist. Lowercase kebab so the folder name is a safe path
3053
3184
  * segment AND a valid Claude Code skill `name` (loader asserts folder == name).
3054
- * All our injected skills (`gh-research`, `gh-orchestrate`, `gh-floor-keeper`)
3055
- * pass.
3185
+ * All our injected skills (`gh-research`, `gh-orchestrate`, `gh-floor-keeper`,
3186
+ * `gh-first-mate`) pass.
3056
3187
  */
3057
3188
  const VALID_SKILL_NAME = /^[a-z][a-z0-9-]*$/;
3058
3189
  /**
@@ -3103,7 +3234,8 @@ async function writeInjectedSkill(name$1, md) {
3103
3234
  const INJECTED_SKILLS = [
3104
3235
  RESEARCH_SKILL,
3105
3236
  ORCHESTRATE_SKILL,
3106
- FLOOR_KEEPER_SKILL
3237
+ FLOOR_KEEPER_SKILL,
3238
+ FIRST_MATE_SKILL
3107
3239
  ];
3108
3240
 
3109
3241
  //#endregion
@@ -3585,7 +3717,7 @@ function initProxyFromEnv() {
3585
3717
  //#endregion
3586
3718
  //#region package.json
3587
3719
  var name = "github-router";
3588
- var version$1 = "0.3.138";
3720
+ var version$1 = "0.3.151";
3589
3721
 
3590
3722
  //#endregion
3591
3723
  //#region src/lib/approval.ts
@@ -5323,6 +5455,7 @@ async function setupAndServe(options) {
5323
5455
  state.extendedBetas = options.extendedBetas;
5324
5456
  state.browseEnabled = options.browseEnabled || process.env.GH_ROUTER_ENABLE_BROWSE === "1";
5325
5457
  state.fleetEnabled = options.fleetEnabled || process.env.GH_ROUTER_ENABLE_FLEET === "1";
5458
+ state.agentsEnabled = options.agentsEnabled || process.env.GH_ROUTER_ENABLE_AGENTS === "1";
5326
5459
  state.powerBrowseEnabled = options.powerBrowseEnabled || process.env.GH_ROUTER_ENABLE_POWER_BROWSE === "1";
5327
5460
  if (state.powerBrowseEnabled) state.browseEnabled = true;
5328
5461
  if (process.env.GH_ROUTER_BROWSER_NO_HUMANLIKE === "1") state.humanlikeForce = "off";
@@ -5336,6 +5469,7 @@ async function setupAndServe(options) {
5336
5469
  state.githubToken = options.githubToken;
5337
5470
  consola.info("Using provided GitHub token");
5338
5471
  } else await setupGitHubToken();
5472
+ if (state.agentsEnabled) await setupGitHubAgentToken();
5339
5473
  await setupCopilotToken();
5340
5474
  await cacheModels();
5341
5475
  consola.debug(`Available models: \n${state.models?.data.map((model) => `- ${model.id}`).join("\n")}`);
@@ -5441,6 +5575,11 @@ const sharedServerArgs = {
5441
5575
  default: false,
5442
5576
  description: "Enable the fleet session-control MCP tools (mcp__fleet__*) on /mcp for driving sessions across remote ai-or-die instances over their tunnels. Off by default; also enabled with GH_ROUTER_ENABLE_FLEET=1."
5443
5577
  },
5578
+ agents: {
5579
+ type: "boolean",
5580
+ default: false,
5581
+ description: "Enable the first-mate cloud-agent orchestration surface (mcp__first-mate__*): a durable controller that drives GitHub cloud coding agents (Copilot/Anthropic/OpenAI) across research/plan/implement/test/merge. Triggers a second GitHub device-login for a write-capable token (repo, workflow, read:org). Off by default; also enabled with GH_ROUTER_ENABLE_AGENTS=1."
5582
+ },
5444
5583
  "power-browse": {
5445
5584
  type: "boolean",
5446
5585
  default: false,
@@ -5494,6 +5633,7 @@ function parseSharedArgs(args) {
5494
5633
  extendedBetas: args["extended-betas"],
5495
5634
  browseEnabled: args.browse,
5496
5635
  fleetEnabled: args.fleet,
5636
+ agentsEnabled: args.agents,
5497
5637
  powerBrowseEnabled: args["power-browse"],
5498
5638
  humanlikeEnabled: args.humanlike
5499
5639
  };
@@ -5625,6 +5765,11 @@ const claude = defineCommand({
5625
5765
  default: false,
5626
5766
  description: "Explicitly record consent for the structural Stop-gate in THIS repo (pinned to the repo's root-commit). The gate is ON BY DEFAULT when a harness is detected (consent-by-launching), so this is now mostly redundant; it stays for explicit/scripted use. Disable the gate entirely with GH_ROUTER_DISABLE_STOP_GATE=1."
5627
5767
  },
5768
+ "no-stop-gate": {
5769
+ type: "boolean",
5770
+ default: false,
5771
+ description: "Disable the structural Stop-gate for THIS session (same effect as GH_ROUTER_DISABLE_STOP_GATE=1). Intended for driven/automated sessions where a blocking Stop hook would hang the turn-end while a fleet driver waits."
5772
+ },
5628
5773
  "auto-update": {
5629
5774
  type: "boolean",
5630
5775
  default: true,
@@ -5740,6 +5885,7 @@ const claude = defineCommand({
5740
5885
  if (standInToolEnabled()) enabledGroups.push("decide");
5741
5886
  if (browserToolsEnabled()) enabledGroups.push("browser");
5742
5887
  if (fleetToolsEnabled()) enabledGroups.push("fleet");
5888
+ if (agentToolsEnabled()) enabledGroups.push("first-mate");
5743
5889
  const { keys: groupKeys, skipped: skippedGroups } = await resolveGroupKeysFromMirror(enabledGroups);
5744
5890
  const runtime = await writePeerMcpRuntimeFiles(serverUrl, {
5745
5891
  codexCli: backend === "cli",
@@ -5769,15 +5915,18 @@ const claude = defineCommand({
5769
5915
  process$1.stderr.write(`Peer MCP wired (backend=${backend}, personas=[${personaNames}], subagent .md files=${runtime.agentMdPaths.length}, ${subagentVisibility}).${skippedNote}\n`);
5770
5916
  const sessionCwd = process$1.cwd();
5771
5917
  if (workerToolsEnabled()) {
5918
+ const skillsToWrite = INJECTED_SKILLS.filter((s) => s.name !== "gh-first-mate" || agentToolsEnabled());
5772
5919
  let skillsWritten = 0;
5773
- for (const s of INJECTED_SKILLS) if ((await writeInjectedSkill(s.name, s.md).catch(() => ({ written: false }))).written) skillsWritten++;
5920
+ for (const s of skillsToWrite) if ((await writeInjectedSkill(s.name, s.md).catch(() => ({ written: false }))).written) skillsWritten++;
5774
5921
  try {
5775
5922
  await injectStopHookIntoSettingsFile(nodePath.join(PATHS.CLAUDE_CONFIG_DIR, "settings.json"), buildPromptSubmitHookCommand(process$1.execPath, process$1.argv[1]), "UserPromptSubmit", 45);
5776
5923
  } catch (err) {
5777
5924
  consola.warn(`Could not register the UserPromptSubmit hook: ${String(err)}`);
5778
5925
  }
5779
- if (skillsWritten > 0) process$1.stderr.write(`Floor-raising skills injected (${skillsWritten}/${INJECTED_SKILLS.length}): /gh-research, /gh-orchestrate, /gh-floor-keeper.
5780
- `);
5926
+ if (skillsWritten > 0) {
5927
+ const skillNames = skillsToWrite.map((s) => `/${s.name}`).join(", ");
5928
+ process$1.stderr.write(`Injected skills (${skillsWritten}/${skillsToWrite.length}): ${skillNames}.\n`);
5929
+ }
5781
5930
  }
5782
5931
  const aiordieSidecar = (process$1.env.AIORDIE_CLAUDE_BIND ?? "").trim();
5783
5932
  if (aiordieSidecar.length > 0 && !aiordieSidecar.includes("\"")) try {
@@ -5808,7 +5957,7 @@ const claude = defineCommand({
5808
5957
  } catch (err) {
5809
5958
  consola.warn(`Could not record gate trust: ${String(err)}`);
5810
5959
  }
5811
- const gateDisabled = parseBoolEnv(process$1.env.GH_ROUTER_DISABLE_STOP_GATE) === true;
5960
+ const gateDisabled = stopGateDisabled(args);
5812
5961
  const forceEnabled = parseBoolEnv(process$1.env.GH_ROUTER_ENABLE_STOP_GATE) === true;
5813
5962
  const includeTests = parseBoolEnv(process$1.env.GH_ROUTER_STOP_GATE_RUN_TESTS) === true;
5814
5963
  const gateRoot = await repoRoot(sessionCwd).catch(() => sessionCwd);
@@ -5910,6 +6059,7 @@ const claude = defineCommand({
5910
6059
  standInAvailable: standInToolEnabled(),
5911
6060
  browseAvailable: state.browseEnabled,
5912
6061
  powerBrowseAvailable: state.powerBrowseEnabled,
6062
+ agentToolsAvailable: agentToolsEnabled(),
5913
6063
  groupKeys
5914
6064
  });
5915
6065
  extraArgs.push("--append-system-prompt", peerSnippet);