github-router 0.3.138 → 0.3.150

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 readIteratorWithTimeout, $t as copilotHeaders, At as UPSTREAM_INACTIVITY_TIMEOUT_MS, B as toolbeltSkipSet, Bt as cacheModels, C as repoRoot, Ct as collapsePathKeys, D as resolveSealedGate, Dt as DEFAULT_CODEX_MODEL_FALLBACKS, E as trustRepo, Et as DEFAULT_CODEX_MODEL, Ft as setupCopilotToken, G as ADVISOR_INTERNAL_TOOL_NAME, Gt as resolveModel, H as TOOLBELT_TOOLS, Ht as filterBetaHeader, It as setupGitHubAgentToken, J as injectAdvisorTool, Jt as fetchWithTransientRetry, K as ADVISOR_TOOL_INSTRUCTIONS, Kt as sleep, L as availableToolCommands, Lt as setupGitHubToken, Mt as pickClaudeDefault, Nt as getPackageVersion, O as liveExec, Ot as DEFAULT_PORT, Pt as withInstallLock, Q as logStreamError, Qt as copilotBaseUrl, R as buildToolbeltAwareness, Rt as tryRefreshAndRetry, S as repoFingerprint, St as ArtifactClient, T as stopReviewStateDir, Tt as DEFAULT_CLAUDE_MODEL_FALLBACKS, U as assetFor, Ut as isNullish, V as vscodeRipgrepPath, Vt as cacheVSCodeVersion, W as searchWeb, Wt as resolveCodexModel, X as buildOpenAIErrorEvent, Xt as forwardError, Y as isAdvisorRequested, Yt as HTTPError, Z as isControllerClosedError, Zt as GITHUB_API_BASE_URL, _ as fileBaselineStore, _t as hasSupportedBrowserInstalled, a as buildPeerAwarenessSnippet, at as fleetToolsEnabled, b as fileReviewDebounce, bt as extractZipMember, c as buildSessionBindHookCommand, ct as countTokens, d as decideStopHook, dt as createResponses, en as githubHeaders, et as relayAnthropicStream, f as fileBlockBudget, ft as createChatCompletions, g as stopReviewEnabled, gt as provisionBrowserAssets, h as stopGateId, ht as parseJsonOrDiagnose, i as buildAgentPrompt, it as browserToolsEnabled, jt as generateRandomPort, kt as UPSTREAM_FETCH_TIMEOUT_MS, l as buildStopHookCommand, lt as createMessages, m as launchBaselineKey, mt as readResponseBodyCapped, n as MCP_GROUPS, nt as handleMcpPost, o as personasFor, ot as standInToolEnabled, p as injectStopHookIntoSettingsFile, pt as MAX_RESPONSE_BODY_BYTES, q as buildAdvisorStream, qt as getModels, r as assertMcpToolSurfaceConsistent, rt as agentToolsEnabled, s as buildArtifactOpenHookCommand, st as workerToolsEnabled, t as GROUP_META, tn as state, tt as handleMcpDelete, u as captureLaunchBaseline, ut as getTokenCount, v as fileFindingsStore, vt as provisionAndIndexColbert, w as stopGateEnabledForRepo, wt as toolbeltPathOverride, x as isSubagentContext, xt as shouldUseInsecureTls, y as fileLastPromptStore, yt as extractTarGzMember, z as toolbeltEnabled, zt as cacheCopilotVersion } from "./peer-mcp-personas-D_HyWhUb.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-Dtu1TDpQ.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.150";
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
  };
@@ -5740,6 +5880,7 @@ const claude = defineCommand({
5740
5880
  if (standInToolEnabled()) enabledGroups.push("decide");
5741
5881
  if (browserToolsEnabled()) enabledGroups.push("browser");
5742
5882
  if (fleetToolsEnabled()) enabledGroups.push("fleet");
5883
+ if (agentToolsEnabled()) enabledGroups.push("first-mate");
5743
5884
  const { keys: groupKeys, skipped: skippedGroups } = await resolveGroupKeysFromMirror(enabledGroups);
5744
5885
  const runtime = await writePeerMcpRuntimeFiles(serverUrl, {
5745
5886
  codexCli: backend === "cli",
@@ -5769,15 +5910,18 @@ const claude = defineCommand({
5769
5910
  process$1.stderr.write(`Peer MCP wired (backend=${backend}, personas=[${personaNames}], subagent .md files=${runtime.agentMdPaths.length}, ${subagentVisibility}).${skippedNote}\n`);
5770
5911
  const sessionCwd = process$1.cwd();
5771
5912
  if (workerToolsEnabled()) {
5913
+ const skillsToWrite = INJECTED_SKILLS.filter((s) => s.name !== "gh-first-mate" || agentToolsEnabled());
5772
5914
  let skillsWritten = 0;
5773
- for (const s of INJECTED_SKILLS) if ((await writeInjectedSkill(s.name, s.md).catch(() => ({ written: false }))).written) skillsWritten++;
5915
+ for (const s of skillsToWrite) if ((await writeInjectedSkill(s.name, s.md).catch(() => ({ written: false }))).written) skillsWritten++;
5774
5916
  try {
5775
5917
  await injectStopHookIntoSettingsFile(nodePath.join(PATHS.CLAUDE_CONFIG_DIR, "settings.json"), buildPromptSubmitHookCommand(process$1.execPath, process$1.argv[1]), "UserPromptSubmit", 45);
5776
5918
  } catch (err) {
5777
5919
  consola.warn(`Could not register the UserPromptSubmit hook: ${String(err)}`);
5778
5920
  }
5779
- if (skillsWritten > 0) process$1.stderr.write(`Floor-raising skills injected (${skillsWritten}/${INJECTED_SKILLS.length}): /gh-research, /gh-orchestrate, /gh-floor-keeper.
5780
- `);
5921
+ if (skillsWritten > 0) {
5922
+ const skillNames = skillsToWrite.map((s) => `/${s.name}`).join(", ");
5923
+ process$1.stderr.write(`Injected skills (${skillsWritten}/${skillsToWrite.length}): ${skillNames}.\n`);
5924
+ }
5781
5925
  }
5782
5926
  const aiordieSidecar = (process$1.env.AIORDIE_CLAUDE_BIND ?? "").trim();
5783
5927
  if (aiordieSidecar.length > 0 && !aiordieSidecar.includes("\"")) try {
@@ -5910,6 +6054,7 @@ const claude = defineCommand({
5910
6054
  standInAvailable: standInToolEnabled(),
5911
6055
  browseAvailable: state.browseEnabled,
5912
6056
  powerBrowseAvailable: state.powerBrowseEnabled,
6057
+ agentToolsAvailable: agentToolsEnabled(),
5913
6058
  groupKeys
5914
6059
  });
5915
6060
  extraArgs.push("--append-system-prompt", peerSnippet);