@heretyc/subagent-mcp 2.8.8 → 2.9.0
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 +7 -0
- package/directives/orchestration-claude.md +1 -1
- package/directives/orchestration-codex.md +1 -1
- package/directives/reminder-on.md +1 -1
- package/directives/short-on.md +1 -1
- package/dist/drivers.js +43 -2
- package/dist/index.js +10 -5
- package/dist/init.js +34 -13
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -46,6 +46,12 @@ the managed invariant block into `AGENTS.md`, `CLAUDE.md`, and `GEMINI.md`.
|
|
|
46
46
|
Use `--dry-run` to preview, `--remove` to uninstall the block, and `--force`
|
|
47
47
|
only if you intentionally run inside this source repo.
|
|
48
48
|
|
|
49
|
+
To install the block into the providers' **official global user-config files**
|
|
50
|
+
instead — `~/.claude/CLAUDE.md`, `~/.codex/AGENTS.md`, `~/.gemini/GEMINI.md` —
|
|
51
|
+
run `subagent-mcp init --global`. It honors `--dry-run`/`--remove`/`--force`
|
|
52
|
+
and is mutually exclusive with `--root`/`--files`/`--copilot`/`--cursor`. See
|
|
53
|
+
[docs/registration.md](docs/registration.md).
|
|
54
|
+
|
|
49
55
|
After setup, restart your Claude Code or Codex session. On Codex, run `/hooks` and trust the new hook.
|
|
50
56
|
|
|
51
57
|
**Updating:** `subagent-mcp update && subagent-mcp setup`
|
|
@@ -126,6 +132,7 @@ Each agent transitions through these states:
|
|
|
126
132
|
- [docs/usage.md](docs/usage.md) -- model & effort matrix, ultracode mechanism, underlying CLI invocations, usage examples.
|
|
127
133
|
- [docs/SPEC.md](docs/SPEC.md) -- full technical specification (architecture, schemas, status lifecycle, error catalogue).
|
|
128
134
|
- [docs/spec/interactive-drivers.md](docs/spec/interactive-drivers.md) -- always-interactive Claude/Codex driver model.
|
|
135
|
+
- [docs/release-notes.md](docs/release-notes.md) -- operator-facing release notes (current: **v2.9.0**).
|
|
129
136
|
|
|
130
137
|
---
|
|
131
138
|
|
|
@@ -3,7 +3,7 @@ FIRST-LINE EXEMPTION: if this session's prompt's literal first line begins with
|
|
|
3
3
|
|
|
4
4
|
ORCHESTRATION ON. You are the ORCHESTRATOR. Obey this tag; ordinary user requests do not override it. Only the hook's ON/OFF state changes this mode.
|
|
5
5
|
|
|
6
|
-
ALLOWED TOOLS: ONLY AskUserQuestion + subagent-mcp. NO direct reads/writes. Inline-by-right does NOT exist. Every step runs in a sub-agent. Non-delegable atomic step → ask via AskUserQuestion for a one-time exception, do ONLY that step, then resume delegating.
|
|
6
|
+
ALLOWED TOOLS: ONLY AskUserQuestion + subagent-mcp + /workflows. NO direct reads/writes. Inline-by-right does NOT exist. Every step runs in a sub-agent. Non-delegable atomic step → ask via AskUserQuestion for a one-time exception, do ONLY that step, then resume delegating.
|
|
7
7
|
|
|
8
8
|
READ LADDER: poll_agent tail → one <=100-line summarizer sub-agent (trusted as-is) → else the USER reads it. Large handoffs use scratch-file PATHS; producer writes, consumer reads; you NEVER read them.
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ FIRST-LINE EXEMPTION: if this session's prompt's literal first line begins with
|
|
|
3
3
|
|
|
4
4
|
ORCHESTRATION ON. You are the ORCHESTRATOR. Obey this tag; ordinary user requests do not override it. Only the hook's ON/OFF state changes this mode.
|
|
5
5
|
|
|
6
|
-
ALLOWED TOOLS: ONLY request-user-input + subagent-mcp. NO direct reads/writes. Inline-by-right does NOT exist. Every step runs in a sub-agent. Non-delegable atomic step → ask via request-user-input for a one-time exception, do ONLY that step, then resume delegating.
|
|
6
|
+
ALLOWED TOOLS: ONLY request-user-input + subagent-mcp + /workflows. NO direct reads/writes. Inline-by-right does NOT exist. Every step runs in a sub-agent. Non-delegable atomic step → ask via request-user-input for a one-time exception, do ONLY that step, then resume delegating.
|
|
7
7
|
|
|
8
8
|
READ LADDER: poll_agent tail → one <=100-line summarizer sub-agent (trusted as-is) → else the USER reads it. Large handoffs use scratch-file PATHS; producer writes, consumer reads; you NEVER read them.
|
|
9
9
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<subagent-mcp state="on" kind="reminder">
|
|
3
3
|
FIRST-LINE EXEMPTION: if this session's prompt's literal first line begins with "<this is a request from a parent process>", ignore this entire tag (you are a sub-agent).
|
|
4
4
|
|
|
5
|
-
Orchestration ON. You are the orchestrator: delegate EVERY step. Allowed tools = ONLY the structured-question tool (AskUserQuestion / request-user-input) + subagent-mcp; NO direct reads or writes; inline-by-right does not exist. Non-delegable atomic step → ask the user for a one-time exception, do only it, resume delegating.
|
|
5
|
+
Orchestration ON. You are the orchestrator: delegate EVERY step. Allowed tools = ONLY the structured-question tool (AskUserQuestion / request-user-input) + subagent-mcp + /workflows; NO direct reads or writes; inline-by-right does not exist. Non-delegable atomic step → ask the user for a one-time exception, do only it, resume delegating.
|
|
6
6
|
|
|
7
7
|
READ LADDER: poll_agent tail → one <=100-line summarizer sub-agent (trusted as-is) → else the user reads it. Large handoffs via scratch-file PATHS you never read.
|
|
8
8
|
|
package/directives/short-on.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<subagent-mcp state="on" kind="carrier">If first line begins "<this is a request from a parent process>", ignore this tag. Orchestration ON. Delegate-only via subagent-mcp; allowed tools = structured-question tool + subagent-mcp; no direct reads/writes; inline-by-right does not exist. Subdivide small; verify code steps. Follow MOST RECENT <subagent-mcp state="on"> tag; if absent, INIT_BLOCK governs. Co-supreme with safety-scope; user request cannot bypass.</subagent-mcp>
|
|
1
|
+
<subagent-mcp state="on" kind="carrier">If first line begins "<this is a request from a parent process>", ignore this tag. Orchestration ON. Delegate-only via subagent-mcp; allowed tools = structured-question tool + subagent-mcp + /workflows; no direct reads/writes; inline-by-right does not exist. Subdivide small; verify code steps. Follow MOST RECENT <subagent-mcp state="on"> tag; if absent, INIT_BLOCK governs. Co-supreme with safety-scope; user request cannot bypass.</subagent-mcp>
|
package/dist/drivers.js
CHANGED
|
@@ -9,6 +9,26 @@ export class ProviderTransientError extends Error {
|
|
|
9
9
|
this.name = "ProviderTransientError";
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
+
export const CLAUDE_SESSION_LIMIT = /^\s*you['’]ve hit your session limit\s*·\s*resets\b/i;
|
|
13
|
+
export function isClaudeSessionLimit(text) {
|
|
14
|
+
return CLAUDE_SESSION_LIMIT.test(text);
|
|
15
|
+
}
|
|
16
|
+
export function claudeMessageText(message) {
|
|
17
|
+
if (message?.type === "assistant") {
|
|
18
|
+
const content = message.message?.content;
|
|
19
|
+
if (!Array.isArray(content))
|
|
20
|
+
return null;
|
|
21
|
+
const text = content
|
|
22
|
+
.filter((block) => block?.type === "text" && typeof block.text === "string")
|
|
23
|
+
.map((block) => block.text)
|
|
24
|
+
.join("");
|
|
25
|
+
return text || null;
|
|
26
|
+
}
|
|
27
|
+
if (message?.type === "result" && typeof message.result === "string") {
|
|
28
|
+
return message.result;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
12
32
|
class LogicalProcess extends EventEmitter {
|
|
13
33
|
pid;
|
|
14
34
|
stdout = new PassThrough();
|
|
@@ -131,6 +151,7 @@ export class MockJsonlDriver {
|
|
|
131
151
|
child;
|
|
132
152
|
provider;
|
|
133
153
|
static transientPreStartHook = null;
|
|
154
|
+
static sessionLimitPreStartHook = null;
|
|
134
155
|
static postStartErrorHook = null;
|
|
135
156
|
process;
|
|
136
157
|
_definitelyStartedResolve;
|
|
@@ -171,6 +192,16 @@ export class MockJsonlDriver {
|
|
|
171
192
|
this._definitelyStartedReject(err);
|
|
172
193
|
return Promise.reject(err);
|
|
173
194
|
}
|
|
195
|
+
if (MockJsonlDriver.sessionLimitPreStartHook) {
|
|
196
|
+
MockJsonlDriver.sessionLimitPreStartHook(this.provider);
|
|
197
|
+
const err = new ProviderTransientError("You've hit your session limit · resets 7:10pm (America/Los_Angeles)");
|
|
198
|
+
setTimeout(() => {
|
|
199
|
+
this._definitelyStartedReject(err);
|
|
200
|
+
this.process.stderr.write(err.message);
|
|
201
|
+
this.process.close(1);
|
|
202
|
+
}, 0);
|
|
203
|
+
return Promise.resolve();
|
|
204
|
+
}
|
|
174
205
|
if (MockJsonlDriver.postStartErrorHook) {
|
|
175
206
|
this._definitelyStartedResolve();
|
|
176
207
|
MockJsonlDriver.postStartErrorHook(this.provider);
|
|
@@ -472,11 +503,21 @@ export class ClaudeSdkDriver {
|
|
|
472
503
|
let started = false;
|
|
473
504
|
try {
|
|
474
505
|
for await (const message of query) {
|
|
475
|
-
|
|
506
|
+
const text = claudeMessageText(message);
|
|
507
|
+
if (!started && text && isClaudeSessionLimit(text)) {
|
|
508
|
+
// Launch-time failover only applies before startup resolves/spawn grace ends;
|
|
509
|
+
// post-registration session-limit rerouting is intentionally out of scope.
|
|
510
|
+
this._definitelyStartedReject(new ProviderTransientError(text));
|
|
511
|
+
this.closedFlag = true;
|
|
512
|
+
this.process.stderr.write(text);
|
|
513
|
+
this.process.close(1);
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
this.process.stdout.write(`${JSON.stringify(message)}\n`);
|
|
517
|
+
if (!started && message?.type !== "system") {
|
|
476
518
|
started = true;
|
|
477
519
|
this._definitelyStartedResolve();
|
|
478
520
|
}
|
|
479
|
-
this.process.stdout.write(`${JSON.stringify(message)}\n`);
|
|
480
521
|
}
|
|
481
522
|
this.closedFlag = true;
|
|
482
523
|
this.process.close(0);
|
package/dist/index.js
CHANGED
|
@@ -139,11 +139,11 @@ reconcileInterval.unref();
|
|
|
139
139
|
// test/mirror-fragments.test.mjs while ORCHESTRATION_INSTRUCTIONS below stays
|
|
140
140
|
// compressed under MCP metadata limits:
|
|
141
141
|
// READ-ESCALATION LADDER (the orchestrator's only read channels, in order): (1) subagent-mcp `poll_agent` TAIL; (2) if the tail is insufficient, dispatch ONE sub-agent to return a single summary of <=100 lines, trusted as-is (no separate verification step); (3) anything larger: the USER reads the document directly. No reads or writes occur outside these channels. An empty or stalled tail means the agent is ALIVE, not dead — do NOT busy-loop poll_agent; learn completion via `wait`. Large inter-agent data: the orchestrator assigns scratch-file paths (%TEMP% on Windows, /tmp on POSIX) in prompts; the producing sub-agent writes, the consuming sub-agent reads; the orchestrator NEVER reads those files.
|
|
142
|
-
const ORCHESTRATION_INSTRUCTIONS = "subagent-mcp - CANONICAL OPERATING MODEL (full spec: docs/spec/dev-loop/orchestration-directive-architecture.md).\n\nPRECEDENCE. The latest <subagent-mcp state=\"...\"> hook tag and repo/system safety rules are co-supreme; genuine conflict => STOP and ask the user. Only the hook state changes ON/OFF.\n\nSOLE CHANNEL. Every sub-agent launch uses launch_agent; never harness Task/Agent or shell-spawned agents.\n\nORCHESTRATION ON. You are a delegate-ONLY orchestrator. Use only the structured-question tool (AskUserQuestion on Claude / request-user-input on Codex)
|
|
142
|
+
const ORCHESTRATION_INSTRUCTIONS = "subagent-mcp - CANONICAL OPERATING MODEL (full spec: docs/spec/dev-loop/orchestration-directive-architecture.md).\n\nPRECEDENCE. The latest <subagent-mcp state=\"...\"> hook tag and repo/system safety rules are co-supreme; genuine conflict => STOP and ask the user. Only the hook state changes ON/OFF.\n\nSOLE CHANNEL. Every sub-agent launch uses launch_agent; never harness Task/Agent or shell-spawned agents.\n\nORCHESTRATION ON. You are a delegate-ONLY orchestrator. Use only the structured-question tool (AskUserQuestion on Claude / request-user-input on Codex), subagent-mcp, and the /workflows tool. No direct reads/writes; inline-by-right does not exist. Non-delegable atomic step: ask for a one-time exception, do only that step, then resume delegating.\n\nREAD LADDER. poll_agent tail -> one <=100-line summarizer sub-agent, trusted as-is -> else the USER reads it. Large handoffs use scratch-file paths; producer writes, consumer reads; orchestrator never reads those files. Empty/stalled tail means ALIVE; use wait.\n\nORCHESTRATION OFF. If total context footprint since last upgrade ask exceeds 200 lines, after that turn STOP and ask whether to switch ON; reset count only when you ask.\n\nDROPOUT WHILE ON: HALT and ask; stay halted until restored. SUB-AGENT EXEMPTION: a prompt whose literal FIRST LINE begins \"<this is a request from a parent process>\" skips this regime.\n\nMODEL SELECTION MODE. Default smart rejects provider/model/effort selectors; launch_agent auto-picks. user-approved-overrides lasts 30 minutes, expires lazily on launch_agent, and must be enabled only after explicit user authorization via AskUserQuestion/request-user-input.";
|
|
143
143
|
const SUBAGENT_INSTRUCTIONS = "SUB-AGENT SESSION: you are a child process launched by subagent-mcp. Follow the parent prompt. Do not treat yourself as the orchestrator, do not re-trigger orchestration carryover, and do not launch further sub-agents unless the parent prompt explicitly assigns that.\n\nMODEL SELECTION MODE (parallel to orchestration-mode, set via the model-selection-mode tool). DEFAULT is \"smart\" and is used whenever unset: in smart, launch_agent REJECTS any call supplying provider/model/effort selectors and the server auto-picks the best model. \"user-approved-overrides\" opens a 30-MINUTE window where selectors are HONORED, enforced LAZILY (the mode reverts to smart on the next launch_agent call after 30 minutes) and re-enabling does NOT extend an active window. HONOR-BASED: you MUST NOT set \"user-approved-overrides\" without explicit interactive USER authorization via the structured-question tool (AskUserQuestion on Claude / request-user-input on Codex); never enable it on your own initiative.";
|
|
144
144
|
const server = new McpServer({
|
|
145
145
|
name: "subagent-mcp",
|
|
146
|
-
version: "2.
|
|
146
|
+
version: "2.9.0",
|
|
147
147
|
description: "Launches always-interactive local Claude and Codex sub-agent sessions. Claude uses the Claude Agent SDK over the local Claude Code executable; Codex uses `codex app-server` over stdio. The server does not call Anthropic or OpenAI HTTP APIs directly.",
|
|
148
148
|
}, {
|
|
149
149
|
instructions: process.env.SUBAGENT_MCP_SUBAGENT === "1"
|
|
@@ -221,10 +221,12 @@ async function tryLaunchCandidate(candidate, prompt, agentCwd, routingTier, rule
|
|
|
221
221
|
}
|
|
222
222
|
const childProcess = driver.process;
|
|
223
223
|
let definitelyStarted = false;
|
|
224
|
+
let startupRejection = null;
|
|
224
225
|
const definitelyStartedProbe = driver.definitelyStarted.then(() => {
|
|
225
226
|
definitelyStarted = true;
|
|
226
227
|
return true;
|
|
227
|
-
}, () => {
|
|
228
|
+
}, (e) => {
|
|
229
|
+
startupRejection = e instanceof Error ? e : new Error(String(e));
|
|
228
230
|
return false;
|
|
229
231
|
});
|
|
230
232
|
const readStartedBoundary = async () => {
|
|
@@ -452,7 +454,9 @@ async function tryLaunchCandidate(candidate, prompt, agentCwd, routingTier, rule
|
|
|
452
454
|
const reason = `process exited (code ${earlyExit.code ?? earlyExit.signal}) within ${SPAWN_GRACE_MS}ms of spawn${tail ? `: ${tail}` : ""}`;
|
|
453
455
|
return {
|
|
454
456
|
reason,
|
|
455
|
-
failure_type:
|
|
457
|
+
failure_type: startupRejection
|
|
458
|
+
? failureTypeForError(startupRejection, agentState.stderr)
|
|
459
|
+
: classifyFailureReason(reason, agentState.stderr),
|
|
456
460
|
};
|
|
457
461
|
}
|
|
458
462
|
}
|
|
@@ -1000,7 +1004,7 @@ server.tool("wait", "Blocks until one or more sub-agents reach a reportable stat
|
|
|
1000
1004
|
};
|
|
1001
1005
|
});
|
|
1002
1006
|
// Tool 7: orchestration-mode
|
|
1003
|
-
server.tool("orchestration-mode", "Toggle or query per-project ORCHESTRATION MODE. `enabled`: true = ON, false = OFF, omit = query current state. SOLE CHANNEL: the subagent MCP is the ONLY sanctioned channel for launching sub-agents whether this mode is ON or OFF — toggling OFF does not lift that obligation. When OFF, run the per-turn upgrade check: a long-horizon task = any whose TOTAL context footprint (input read + output produced) exceeds 200 lines, measured CUMULATIVELY since your last upgrade ask; after EVERY user turn, if it qualifies, STOP and ask the user whether to switch ON (ask every qualifying turn; a decline does not latch; reset the count only when you actually ask). The FULL operating model + governance is carried in this server's MCP `instructions` (read once at initialize) — this is the operational summary only; do not act on the mode without that detail. WHAT: a per-project toggle for LONG-HORIZON work that would fill the context window if run to completion inline; when ON, act as
|
|
1007
|
+
server.tool("orchestration-mode", "Toggle or query per-project ORCHESTRATION MODE. `enabled`: true = ON, false = OFF, omit = query current state. SOLE CHANNEL: the subagent MCP is the ONLY sanctioned channel for launching sub-agents whether this mode is ON or OFF — toggling OFF does not lift that obligation. When OFF, run the per-turn upgrade check: a long-horizon task = any whose TOTAL context footprint (input read + output produced) exceeds 200 lines, measured CUMULATIVELY since your last upgrade ask; after EVERY user turn, if it qualifies, STOP and ask the user whether to switch ON (ask every qualifying turn; a decline does not latch; reset the count only when you actually ask). The FULL operating model + governance is carried in this server's MCP `instructions` (read once at initialize) — this is the operational summary only; do not act on the mode without that detail. WHAT: a per-project toggle for LONG-HORIZON work that would fill the context window if run to completion inline; when ON, act as a delegate-ONLY orchestrator: delegate every step; inline-by-right does not exist; a non-delegable atomic step requires a one-time user-approved exception via the structured-question tool (state which + why). PERSISTENCE: a per-project marker keyed by cwd; absence of the marker = OFF = no injection; once ON it persists across restarts/sessions until a permitted disable (it does NOT reset on a new session). CARRYOVER: if ON was inherited from a PRIOR session (provenance = carried-over, not user-enabled this session), the bundled hook prepends a ONE-TIME notice (once per marker, never per turn) — you MUST then notify the user it auto-activated and confirm whether to keep it ON. DISABLE: never on your own initiative; you MAY PROPOSE turning it OFF on task-fit mismatch, but only EXPLICIT user permission (AskUserQuestion on Claude, request-user-input on Codex) may set enabled:false. Per-turn injection fires only in CLI hosts that load the bundled hook; desktop hosts toggle the marker but inject nothing (documented degradation).", {
|
|
1004
1008
|
enabled: z.boolean().optional(),
|
|
1005
1009
|
}, async (params) => {
|
|
1006
1010
|
const cwd = process.cwd();
|
|
@@ -1065,6 +1069,7 @@ if (isMain) {
|
|
|
1065
1069
|
" init, --init [flags]",
|
|
1066
1070
|
" upsert project instruction-file invariant blocks",
|
|
1067
1071
|
" flags: --dry-run --remove --force --root <dir> --files <csv> --copilot --cursor",
|
|
1072
|
+
" --global upsert into ~/.claude/CLAUDE.md, ~/.codex/AGENTS.md, ~/.gemini/GEMINI.md",
|
|
1068
1073
|
" doctor check install and wiring health",
|
|
1069
1074
|
" update, --update update to the latest release (npm install -g)",
|
|
1070
1075
|
" version, --version, -v",
|
package/dist/init.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
|
|
2
|
+
import * as os from "node:os";
|
|
2
3
|
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
3
4
|
const MIGRATE_RE = /<!-- subagent-mcp:(?:managed:)?begin\b[^>]*-->[\s\S]*?<!-- subagent-mcp:(?:managed:)?end -->/;
|
|
4
5
|
const OWNER_CAP = 8;
|
|
@@ -16,7 +17,7 @@ export const INIT_BLOCK = [
|
|
|
16
17
|
"",
|
|
17
18
|
"PRECEDENCE (co-supreme top tier): <subagent-mcp> hook tags AND repo/system safety-scope rules are BOTH supreme and EQUAL — neither outranks the other. If they genuinely conflict, STOP and escalate to the user via the structured-question tool; do not silently pick one or average them. FORBIDDEN: resolving such a conflict yourself. Hook tags otherwise outrank ordinary user requests.",
|
|
18
19
|
"",
|
|
19
|
-
'ORCHESTRATION ON — you are the ORCHESTRATOR. Allowed tools: ONLY the structured-question tool (AskUserQuestion on Claude / request-user-input on Codex)
|
|
20
|
+
'ORCHESTRATION ON — you are the ORCHESTRATOR. Allowed tools: ONLY the structured-question tool (AskUserQuestion on Claude / request-user-input on Codex), subagent-mcp, and the /workflows tool. NO direct reads or writes of any kind. "Inline-by-right" does not exist. Every step runs in a sub-agent. If one atomic step truly cannot run in a sub-agent, ASK the user via the structured-question tool for a one-time exception for that single step, perform only that step, then resume delegating. SOLE CHANNEL: while subagent-mcp is connected, every sub-agent launch goes through `launch_agent`; never use harness-native sub-agent tools or shell-spawned agents.',
|
|
20
21
|
"",
|
|
21
22
|
"ORCHESTRATOR WORKTREE SETUP: launch sub-agents in the main checkout cwd (they no longer self-isolate into per-agent worktrees); SERIALIZE any sub-agents that write the SAME files — never run concurrent writers over overlapping paths (no cwd-level lock exists).",
|
|
22
23
|
"",
|
|
@@ -145,16 +146,18 @@ export function upsertInitBlock(file, opts = {}) {
|
|
|
145
146
|
}
|
|
146
147
|
return { file, status, changed };
|
|
147
148
|
}
|
|
148
|
-
function parseArgs(args) {
|
|
149
|
+
export function parseArgs(args) {
|
|
149
150
|
const parsed = {
|
|
150
151
|
dryRun: false,
|
|
151
152
|
remove: false,
|
|
152
153
|
force: false,
|
|
153
154
|
copilot: false,
|
|
154
155
|
cursor: false,
|
|
156
|
+
global: false,
|
|
155
157
|
root: process.cwd(),
|
|
156
158
|
files: null,
|
|
157
159
|
};
|
|
160
|
+
let rootProvided = false;
|
|
158
161
|
const readValue = (args, i, flag) => {
|
|
159
162
|
const value = args[i + 1];
|
|
160
163
|
if (value === undefined || value === "" || value.startsWith("--")) {
|
|
@@ -174,8 +177,11 @@ function parseArgs(args) {
|
|
|
174
177
|
parsed.copilot = true;
|
|
175
178
|
else if (a === "--cursor")
|
|
176
179
|
parsed.cursor = true;
|
|
180
|
+
else if (a === "--global")
|
|
181
|
+
parsed.global = true;
|
|
177
182
|
else if (a === "--root") {
|
|
178
183
|
parsed.root = readValue(args, i, a);
|
|
184
|
+
rootProvided = true;
|
|
179
185
|
i++;
|
|
180
186
|
}
|
|
181
187
|
else if (a === "--files") {
|
|
@@ -187,6 +193,9 @@ function parseArgs(args) {
|
|
|
187
193
|
}
|
|
188
194
|
if (!parsed.root)
|
|
189
195
|
throw new Error("--root requires a directory");
|
|
196
|
+
if (parsed.global && (rootProvided || parsed.files || parsed.copilot || parsed.cursor)) {
|
|
197
|
+
throw new Error("--global cannot be combined with --root/--files/--copilot/--cursor");
|
|
198
|
+
}
|
|
190
199
|
return parsed;
|
|
191
200
|
}
|
|
192
201
|
function isSelfRepo(root) {
|
|
@@ -198,6 +207,13 @@ function isSelfRepo(root) {
|
|
|
198
207
|
return false;
|
|
199
208
|
}
|
|
200
209
|
}
|
|
210
|
+
export function globalTargetFiles(home = os.homedir()) {
|
|
211
|
+
return [
|
|
212
|
+
join(home, ".claude", "CLAUDE.md"),
|
|
213
|
+
join(home, ".codex", "AGENTS.md"),
|
|
214
|
+
join(home, ".gemini", "GEMINI.md"),
|
|
215
|
+
];
|
|
216
|
+
}
|
|
201
217
|
function targetFiles(root, opts) {
|
|
202
218
|
const resolveTarget = (f) => {
|
|
203
219
|
const target = isAbsolute(f) ? resolve(f) : resolve(root, f);
|
|
@@ -225,19 +241,24 @@ export async function runInit(args = process.argv.slice(3)) {
|
|
|
225
241
|
console.error(e instanceof Error ? e.message : String(e));
|
|
226
242
|
return 1;
|
|
227
243
|
}
|
|
228
|
-
const root = resolve(opts.root);
|
|
229
|
-
if (isSelfRepo(root) && !opts.force) {
|
|
230
|
-
console.error("Refusing to run init inside the subagent-mcp source repo without --force.");
|
|
231
|
-
console.error("This repo keeps CLAUDE.md/GEMINI.md as thin redirects; use --root for a consumer repo.");
|
|
232
|
-
return 1;
|
|
233
|
-
}
|
|
234
244
|
let files;
|
|
235
|
-
|
|
236
|
-
files =
|
|
245
|
+
if (opts.global) {
|
|
246
|
+
files = globalTargetFiles();
|
|
237
247
|
}
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
248
|
+
else {
|
|
249
|
+
const root = resolve(opts.root);
|
|
250
|
+
if (isSelfRepo(root) && !opts.force) {
|
|
251
|
+
console.error("Refusing to run init inside the subagent-mcp source repo without --force.");
|
|
252
|
+
console.error("This repo keeps CLAUDE.md/GEMINI.md as thin redirects; use --root for a consumer repo.");
|
|
253
|
+
return 1;
|
|
254
|
+
}
|
|
255
|
+
try {
|
|
256
|
+
files = targetFiles(root, opts);
|
|
257
|
+
}
|
|
258
|
+
catch (e) {
|
|
259
|
+
console.error(e instanceof Error ? e.message : String(e));
|
|
260
|
+
return 1;
|
|
261
|
+
}
|
|
241
262
|
}
|
|
242
263
|
const issues = [];
|
|
243
264
|
const results = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heretyc/subagent-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"description": "MCP server that launches and manages always-interactive Claude Code and Codex sub-agent sessions (no direct Anthropic/OpenAI API).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"postinstall": "node scripts/postinstall.mjs",
|
|
23
23
|
"prepare": "npm run build",
|
|
24
24
|
"prepublishOnly": "npm test",
|
|
25
|
-
"test": "npm run check:versions && node test/effort.test.mjs && node test/drivers.test.mjs && node test/platform.test.mjs && node test/wait.test.mjs && node test/status.test.mjs && node test/output.test.mjs && node test/stream.test.mjs && node test/routing.test.mjs && node test/deadlock.test.mjs && node test/handler-validation.test.mjs && node test/index-handler.test.mjs && node test/ruleset.test.mjs && node test/ruleset-exec.test.mjs && node test/ruleset-handler.test.mjs && node test/failover.test.mjs && node test/orchestration-marker.test.mjs && node test/orchestration-hook-core.test.mjs && node test/orchestration-adapters.test.mjs && node test/orchestration-pretool.test.mjs && node test/orchestration-directives.test.mjs && node test/no-five-call.test.mjs && node test/check-worktree-subagent.test.mjs && node test/launch-agent-upsert.test.mjs && node test/init-migration.test.mjs && node test/mirror-fragments.test.mjs && node test/performance-tier-effort.test.mjs && node test/setup-repair.test.mjs && node test/setup-quoting.test.mjs && node test/setup-wire.test.mjs && node test/setup-cli-integration.test.mjs && node test/init.test.mjs && node test/model-selection-mode.test.mjs && node test/cli-args.test.mjs && node scripts/validate_provider.mjs && node scripts/validate_seed_sites.mjs && node scripts/validate_routing_audit.mjs && node test/seed-sites.test.mjs && node test/mcp-compliance.test.mjs"
|
|
25
|
+
"test": "npm run check:versions && node test/effort.test.mjs && node test/drivers.test.mjs && node test/platform.test.mjs && node test/wait.test.mjs && node test/status.test.mjs && node test/output.test.mjs && node test/stream.test.mjs && node test/routing.test.mjs && node test/deadlock.test.mjs && node test/handler-validation.test.mjs && node test/index-handler.test.mjs && node test/ruleset.test.mjs && node test/ruleset-exec.test.mjs && node test/ruleset-handler.test.mjs && node test/failover.test.mjs && node test/orchestration-marker.test.mjs && node test/orchestration-hook-core.test.mjs && node test/orchestration-adapters.test.mjs && node test/orchestration-pretool.test.mjs && node test/orchestration-directives.test.mjs && node test/no-five-call.test.mjs && node test/check-worktree-subagent.test.mjs && node test/launch-agent-upsert.test.mjs && node test/claude-session-limit.test.mjs && node test/init-migration.test.mjs && node test/init-global.test.mjs && node test/mirror-fragments.test.mjs && node test/performance-tier-effort.test.mjs && node test/setup-repair.test.mjs && node test/setup-quoting.test.mjs && node test/setup-wire.test.mjs && node test/setup-cli-integration.test.mjs && node test/init.test.mjs && node test/model-selection-mode.test.mjs && node test/cli-args.test.mjs && node scripts/validate_provider.mjs && node scripts/validate_seed_sites.mjs && node scripts/validate_routing_audit.mjs && node test/seed-sites.test.mjs && node test/mcp-compliance.test.mjs"
|
|
26
26
|
},
|
|
27
27
|
"author": "Lexi Blackburn",
|
|
28
28
|
"license": "Apache-2.0",
|