@nexrall/code-core 1.4.25 → 1.4.26

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.
@@ -0,0 +1,45 @@
1
+ import type { Message } from '../types';
2
+ export interface StoredAgent {
3
+ id: string;
4
+ /**
5
+ * The agent type this ran as, or null for an unnamed (general-purpose) run.
6
+ *
7
+ * Stored so resumption can be re-authorised against the CURRENT permission
8
+ * rules. Without it, an id would be a permanent bypass of any deny rule added
9
+ * after the agent first ran.
10
+ */
11
+ agentName: string | null;
12
+ /** Full conversation: the sub-agent's own user/assistant/tool messages. */
13
+ messages: Message[];
14
+ /** The description shown in the UI, for `/agents --resumable` style listings. */
15
+ description: string;
16
+ createdAt: number;
17
+ updatedAt: number;
18
+ /**
19
+ * Monotonic touch counter, used for ordering instead of `updatedAt`.
20
+ *
21
+ * Date.now() has millisecond resolution and these operations take
22
+ * microseconds, so two agents touched in the same tick compare EQUAL and a
23
+ * stable sort silently falls back to insertion order — i.e. "most recent"
24
+ * would have been wrong exactly when several things happen at once, which is
25
+ * the normal case for parallel sub-tasks. The timestamps are kept because
26
+ * they are meaningful to humans; the ordering does not depend on them.
27
+ */
28
+ seq: number;
29
+ /** Rough JSON size, cached so the byte cap doesn't re-serialise on every write. */
30
+ bytes: number;
31
+ }
32
+ /** Store a finished sub-agent's transcript. Returns its resumable id. */
33
+ export declare function rememberAgent(agentName: string | null, description: string, messages: Message[]): string;
34
+ /** Append a resumed run's new messages to an existing agent. */
35
+ export declare function updateAgent(id: string, messages: Message[]): void;
36
+ export declare function getAgent(id: string): StoredAgent | undefined;
37
+ /** Newest first — the order a "which agents can I resume?" list wants. */
38
+ export declare function listAgents(): StoredAgent[];
39
+ /** Test seam. Not exported through index.ts's public surface by intent. */
40
+ export declare function _resetAgentRegistry(): void;
41
+ export declare const _limits: {
42
+ MAX_AGENTS: number;
43
+ MAX_TOTAL_BYTES: number;
44
+ };
45
+ //# sourceMappingURL=agentRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentRegistry.d.ts","sourceRoot":"","sources":["../../src/agent/agentRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AA8CxC,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,2EAA2E;IAC3E,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;;;OASG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,mFAAmF;IACnF,KAAK,EAAE,MAAM,CAAC;CACf;AA4CD,yEAAyE;AACzE,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,OAAO,EAAE,GAClB,MAAM,CAeR;AAED,gEAAgE;AAChE,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,CAYjE;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAE5D;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,IAAI,WAAW,EAAE,CAE1C;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,IAAI,IAAI,CAI1C;AAED,eAAO,MAAM,OAAO;;;CAAkC,CAAC"}
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports._limits = void 0;
4
+ exports.rememberAgent = rememberAgent;
5
+ exports.updateAgent = updateAgent;
6
+ exports.getAgent = getAgent;
7
+ exports.listAgents = listAgents;
8
+ exports._resetAgentRegistry = _resetAgentRegistry;
9
+ // ─── Resumable sub-agents ────────────────────────────────────────────────────
10
+ //
11
+ // A sub-agent normally starts with a blank slate: fresh context, no memory of a
12
+ // previous run. That is the whole point for one-shot research — but it makes
13
+ // follow-up work absurdly expensive. "Now also check the auth path" re-reads
14
+ // every file the last run already read, because the only way to add to a
15
+ // finished sub-task is to describe the whole job again from scratch.
16
+ //
17
+ // This registry keeps a completed sub-agent's transcript in memory so a later
18
+ // `task` call can continue it instead of restarting it. Claude Code does the
19
+ // same thing; the design decisions worth writing down are the ones about what
20
+ // NOT to do:
21
+ //
22
+ // • IN-MEMORY, process-lifetime only. Deliberately not written to disk. A
23
+ // transcript is unredacted tool output — file contents, command output,
24
+ // whatever a repo happens to contain. Persisting it would create a new
25
+ // durable copy of material the user never asked us to store, in a new place
26
+ // they would have to know to clean up. Losing resumability when the process
27
+ // exits is a much smaller cost than that.
28
+ //
29
+ // • BOUNDED, by entries and by bytes. A transcript is the largest object this
30
+ // process handles, and an agent loop that spawns sub-agents in a cycle would
31
+ // otherwise grow the heap until the CLI dies — a leak that shows up only in
32
+ // the longest sessions, i.e. the ones where losing work hurts most.
33
+ //
34
+ // • Resumption re-checks permission at the CALL SITE, not here. An id is a
35
+ // capability: if a rule denies `task(explorer)` after an explorer agent has
36
+ // already run, resuming by id must not hand that agent back. This module
37
+ // therefore stores the agent's NAME alongside its history, so the caller can
38
+ // re-evaluate the current rules against it. See runSubTask.
39
+ /** Max resumable agents kept alive. Oldest is evicted first. */
40
+ const MAX_AGENTS = 20;
41
+ /**
42
+ * Max total transcript bytes across all stored agents (~8 MB of JSON).
43
+ *
44
+ * Sized to comfortably hold a handful of long research runs while staying far
45
+ * below the point where it competes with the model context for memory. Eviction
46
+ * is by age, not by size, so one enormous transcript cannot pin out many small
47
+ * useful ones.
48
+ */
49
+ const MAX_TOTAL_BYTES = 8 * 1024 * 1024;
50
+ /**
51
+ * Insertion-ordered store. A Map is enough: Maps iterate in insertion order, so
52
+ * "oldest" is simply the first key, and re-inserting on update moves an entry to
53
+ * the back — giving LRU-by-touch for free without a second data structure.
54
+ */
55
+ const _agents = new Map();
56
+ let _counter = 0;
57
+ let _seq = 0;
58
+ function totalBytes() {
59
+ let n = 0;
60
+ for (const a of _agents.values())
61
+ n += a.bytes;
62
+ return n;
63
+ }
64
+ function evictUntilWithinLimits() {
65
+ while (_agents.size > MAX_AGENTS) {
66
+ const oldest = _agents.keys().next().value;
67
+ if (oldest === undefined)
68
+ break;
69
+ _agents.delete(oldest);
70
+ }
71
+ // Byte cap is checked second: an entry that is individually enormous should
72
+ // still be storable (it is the most expensive thing to recompute), but it
73
+ // must not drag the total past the cap alongside its neighbours.
74
+ while (totalBytes() > MAX_TOTAL_BYTES && _agents.size > 1) {
75
+ const oldest = _agents.keys().next().value;
76
+ if (oldest === undefined)
77
+ break;
78
+ _agents.delete(oldest);
79
+ }
80
+ }
81
+ function sizeOf(messages) {
82
+ try {
83
+ return JSON.stringify(messages).length;
84
+ }
85
+ catch {
86
+ // A transcript that cannot be serialised (cycles shouldn't happen, but a
87
+ // crash here would take down a completed sub-task's result) is treated as
88
+ // large so it gets evicted early rather than silently counted as free.
89
+ return MAX_TOTAL_BYTES;
90
+ }
91
+ }
92
+ /** Store a finished sub-agent's transcript. Returns its resumable id. */
93
+ function rememberAgent(agentName, description, messages) {
94
+ const id = `agent_${++_counter}`;
95
+ const now = Date.now();
96
+ _agents.set(id, {
97
+ id,
98
+ agentName,
99
+ description,
100
+ messages,
101
+ createdAt: now,
102
+ updatedAt: now,
103
+ seq: ++_seq,
104
+ bytes: sizeOf(messages),
105
+ });
106
+ evictUntilWithinLimits();
107
+ return id;
108
+ }
109
+ /** Append a resumed run's new messages to an existing agent. */
110
+ function updateAgent(id, messages) {
111
+ const existing = _agents.get(id);
112
+ if (!existing)
113
+ return;
114
+ existing.messages = messages;
115
+ existing.updatedAt = Date.now();
116
+ existing.seq = ++_seq;
117
+ existing.bytes = sizeOf(messages);
118
+ // Re-insert so this becomes the most recently used entry, protecting an
119
+ // actively-continued agent from being evicted by a burst of new one-shots.
120
+ _agents.delete(id);
121
+ _agents.set(id, existing);
122
+ evictUntilWithinLimits();
123
+ }
124
+ function getAgent(id) {
125
+ return _agents.get(id);
126
+ }
127
+ /** Newest first — the order a "which agents can I resume?" list wants. */
128
+ function listAgents() {
129
+ return [..._agents.values()].sort((a, b) => b.seq - a.seq);
130
+ }
131
+ /** Test seam. Not exported through index.ts's public surface by intent. */
132
+ function _resetAgentRegistry() {
133
+ _agents.clear();
134
+ _counter = 0;
135
+ _seq = 0;
136
+ }
137
+ exports._limits = { MAX_AGENTS, MAX_TOTAL_BYTES };
138
+ //# sourceMappingURL=agentRegistry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"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"}
@@ -59,6 +59,8 @@ const executor_1 = require("../tools/executor");
59
59
  const agentTypes_1 = require("./agentTypes");
60
60
  const skills_1 = require("./skills");
61
61
  const rules_1 = require("../permissions/rules");
62
+ const planMode_1 = require("./planMode");
63
+ const agentRegistry_1 = require("./agentRegistry");
62
64
  const sandbox_1 = require("../tools/sandbox");
63
65
  const index_1 = require("../plugins/index");
64
66
  const testIntegrity_1 = require("./testIntegrity");
@@ -541,7 +543,49 @@ async function runSubTask(input, options, agentTypes) {
541
543
  // ENOENT stats — against a sub-agent that is about to run for seconds to
542
544
  // minutes. Note runAgentLoop re-reads for the sub-agent anyway, so the old
543
545
  // behaviour was already inconsistent: fresh for the child, stale for the lookup.
544
- const requestedType = typeof input.subagent_type === 'string' ? input.subagent_type : '';
546
+ // ── Resolve a resume target ─────────────────────────────────────────────────
547
+ //
548
+ // `resume_agent_id` continues a previous sub-agent. The stored transcript
549
+ // carries the agent's NAME, and that name — not the one the model passed — is
550
+ // what gets authorised below.
551
+ //
552
+ // This matters because an id would otherwise be a permanent capability: deny
553
+ // `task(explorer)` today and a model holding yesterday's explorer id could
554
+ // still resume it, with the deny rule looking like it was applied. Re-deriving
555
+ // the name from storage also stops a mismatched `subagent_type` from being
556
+ // used to launder a denied agent under an allowed name.
557
+ const resumeId = typeof input.resume_agent_id === 'string' ? input.resume_agent_id.trim() : '';
558
+ const resumed = resumeId ? (0, agentRegistry_1.getAgent)(resumeId) : undefined;
559
+ if (resumeId && !resumed) {
560
+ return {
561
+ error: `No resumable sub-agent with id "${resumeId}". Ids live only for the current session and the ` +
562
+ 'oldest are dropped when too many accumulate, so this one has expired or never existed. ' +
563
+ 'Start a fresh sub-task with a self-contained prompt instead.',
564
+ };
565
+ }
566
+ const requestedType = resumed
567
+ ? (resumed.agentName ?? '')
568
+ : (typeof input.subagent_type === 'string' ? input.subagent_type : '');
569
+ // ── Enforce `deny: ["task(<name>)"]` ─────────────────────────────────────────
570
+ //
571
+ // This is the load-bearing check; filtering the catalogue in runAgentLoop only
572
+ // stops the agent being SUGGESTED. It must run BEFORE resolution, because the
573
+ // reload-on-miss path below deliberately re-reads from disk UNFILTERED — a
574
+ // denied agent is absent from the snapshot, would therefore "miss", and would
575
+ // then be found by that reload and run. Denying by omission is not denying.
576
+ //
577
+ // Phrased as a policy refusal, not "unknown type": the model must not respond
578
+ // by trying to create the agent file it thinks is missing.
579
+ if (requestedType) {
580
+ const decision = (0, rules_1.evaluatePermission)((0, rules_1.loadSettings)(options.workDir).permissions, 'task', { subagent_type: requestedType }, options.workDir);
581
+ if (decision === 'deny') {
582
+ return {
583
+ error: `The sub-agent "${requestedType}" is disabled by a permission rule in this project ` +
584
+ `(permissions.deny in settings.json). This is a deliberate policy choice, not a missing file — ` +
585
+ 'do not create it and do not retry. Do the work yourself, or use a different sub-agent.',
586
+ };
587
+ }
588
+ }
545
589
  let agent = (0, agentTypes_1.findAgentType)(agentTypes, requestedType);
546
590
  let knownTypes = agentTypes;
547
591
  if (requestedType && !agent) {
@@ -584,9 +628,16 @@ async function runSubTask(input, options, agentTypes) {
584
628
  }
585
629
  return options.requestPermission(req);
586
630
  };
587
- const subMessages = [
588
- { role: 'user', content: [{ type: 'text', text: prompt }] },
589
- ];
631
+ // ── Resume: continue a previous sub-agent instead of starting cold ──────────
632
+ //
633
+ // The new prompt is appended as another user turn to the stored transcript, so
634
+ // the agent keeps every file it read and every conclusion it reached. Without
635
+ // this, "now also check the auth path" means re-describing the entire job and
636
+ // re-reading everything — the most common and most expensive kind of waste in
637
+ // a delegated workflow.
638
+ const subMessages = resumed
639
+ ? [...resumed.messages, { role: 'user', content: [{ type: 'text', text: prompt }] }]
640
+ : [{ role: 'user', content: [{ type: 'text', text: prompt }] }];
590
641
  // A dedicated abort signal for this sub-agent, distinct from the parent's own
591
642
  // options.abortSignal (user hit Ctrl+C). Set to true either when the parent
592
643
  // aborts OR when the stall timeout below fires, whichever happens first —
@@ -609,6 +660,9 @@ async function runSubTask(input, options, agentTypes) {
609
660
  _agentScope: `sub_${++_subTaskCounter}`, // isolated todo store per sub-agent
610
661
  editorContext: null, // fresh isolated context for sub-agent
611
662
  model: agent?.model ?? options.model,
663
+ // Plan mode is inherited, never relaxed. If the main agent could spawn a
664
+ // sub-agent that writes, the lock would be one `task` call from useless.
665
+ planMode: options.planMode,
612
666
  nexrallMd: subNexrallMd,
613
667
  abortSignal: subAbort,
614
668
  requestPermission: gatedPermission,
@@ -671,7 +725,23 @@ async function runSubTask(input, options, agentTypes) {
671
725
  }
672
726
  // Normal completion: the final assistant message is the sub-agent's answer.
673
727
  const text = capSubTaskText(extractSubTaskText(result, true));
674
- return { output: text || '(sub-task completed with no text output)' };
728
+ // Store the transcript so a follow-up can continue this agent rather than
729
+ // re-running it from scratch, and tell the parent the id.
730
+ //
731
+ // Only on NORMAL completion. A timed-out or failed run is deliberately not
732
+ // resumable: its transcript ends mid-thought, often mid-tool-call, and
733
+ // resuming from that state invites the model to build on work whose status
734
+ // it cannot determine. Those paths already salvage their partial output as
735
+ // TEXT, which is the safe way to carry that information forward.
736
+ const agentId = resumed
737
+ ? ((0, agentRegistry_1.updateAgent)(resumed.id, result), resumed.id)
738
+ : (0, agentRegistry_1.rememberAgent)(agent?.name ?? null, (typeof input.description === 'string' && input.description.trim()) || prompt.slice(0, 80), result);
739
+ const body = text || '(sub-task completed with no text output)';
740
+ return {
741
+ output: `${body}\n\n[resumable: this sub-agent is "${agentId}". To ask IT a follow-up — keeping ` +
742
+ 'everything it already read and concluded — call task again with resume_agent_id="' + agentId +
743
+ '" instead of writing a new prompt from scratch.]',
744
+ };
675
745
  }
676
746
  catch (err) {
677
747
  // Same salvage rule as the timeout path above, for the other way a sub-agent
@@ -1342,17 +1412,36 @@ async function runAgentLoop(initialMessages, options) {
1342
1412
  const hooks = loadHooks(options.workDir);
1343
1413
  const depth = options._depth ?? 0;
1344
1414
  const agentScope = options._agentScope ?? 'root';
1415
+ // Settings are read before the agent catalogue because a `deny` rule can
1416
+ // switch a sub-agent off, and an agent that may not run must not be
1417
+ // advertised (see below).
1418
+ const settings = (0, rules_1.loadSettings)(options.workDir);
1345
1419
  // Discover custom sub-agent types. Only the top-level agent is told the
1346
1420
  // catalogue (sub-agents can't spawn further), but every level resolves types.
1347
- const agentTypes = (0, agentTypes_1.loadAgentTypes)(options.workDir);
1421
+ //
1422
+ // Denied agents are filtered OUT of the catalogue rather than left in it to be
1423
+ // refused on dispatch. Listing an agent you have forbidden trains the model to
1424
+ // spend a tool call discovering the refusal, and "available types: …" on the
1425
+ // error path would name it again. Enforcement still happens at dispatch
1426
+ // (runSubTask) — this is the cosmetic half; that is the load-bearing half.
1427
+ const agentTypes = (0, agentTypes_1.loadAgentTypes)(options.workDir).filter((t) => (0, rules_1.evaluatePermission)(settings.permissions, 'task', { subagent_type: t.name }, options.workDir) !== 'deny');
1348
1428
  const agentsCatalogue = depth === 0 ? (0, agentTypes_1.summariseAgents)(agentTypes) : '';
1349
1429
  // Skills catalogue — unlike agentsCatalogue, available at every depth: a skill is
1350
1430
  // just a reusable prompt template (via use_skill), not another spawn point, so
1351
1431
  // sub-agents benefit from the same playbooks without the recursion concerns that
1352
1432
  // gate agentsCatalogue to the top level.
1353
1433
  const skillsCatalogue = (0, skills_1.summariseSkills)((0, skills_1.loadSkills)(options.workDir));
1434
+ // Plan mode instructions ride the project-instructions channel, which is
1435
+ // authoritative in the system prompt. Prepended rather than appended: the
1436
+ // lock has to be read before the project conventions it overrides.
1437
+ //
1438
+ // Telling the model is not the enforcement (checkPlanMode at the call site is)
1439
+ // — it exists so the model spends the turn planning instead of discovering the
1440
+ // lock one refused tool call at a time.
1441
+ const planAwareNexrallMd = options.planMode
1442
+ ? planMode_1.PLAN_MODE_INSTRUCTIONS + (options.nexrallMd ? `\n\n---\n\n${options.nexrallMd}` : '')
1443
+ : options.nexrallMd;
1354
1444
  // Optional OS-level bash sandbox (opt-in via settings.json "sandbox").
1355
- const settings = (0, rules_1.loadSettings)(options.workDir);
1356
1445
  const sandboxCfg = (0, sandbox_1.parseSandboxConfig)(settings.raw.sandbox) ?? undefined;
1357
1446
  // Soft iteration budget + optional auto-continue past it (see resolvers above).
1358
1447
  const maxIterations = resolveMaxIterations(options.maxIterations, settings.raw);
@@ -1569,7 +1658,7 @@ async function runAgentLoop(initialMessages, options) {
1569
1658
  effort: options.effort,
1570
1659
  env: options.env,
1571
1660
  editorContext: options.editorContext,
1572
- nexrallMd: options.nexrallMd,
1661
+ nexrallMd: planAwareNexrallMd,
1573
1662
  clientType: options.clientType,
1574
1663
  abortSignal: options.abortSignal,
1575
1664
  extraTools: options.mcpManager?.getAnthropicTools(),
@@ -1794,6 +1883,21 @@ async function runAgentLoop(initialMessages, options) {
1794
1883
  options.onToolResult(name, result);
1795
1884
  return { block: { ...block, id }, result };
1796
1885
  }
1886
+ // ── Plan mode: a session-wide read-only lock ────────────────────────
1887
+ //
1888
+ // Checked BEFORE requestPermission on purpose. Routing it through the
1889
+ // permission prompt would ask the user to approve something that is
1890
+ // not theirs to approve in that moment, and a model told "denied by
1891
+ // user" reliably re-asks. This refusal instead says plainly that no
1892
+ // answer here can unlock it.
1893
+ if (options.planMode) {
1894
+ const refusal = (0, planMode_1.checkPlanMode)(name, input);
1895
+ if (refusal) {
1896
+ result = { error: refusal.message };
1897
+ options.onToolResult(name, result);
1898
+ return { block: { ...block, id }, result };
1899
+ }
1900
+ }
1797
1901
  // Request permission
1798
1902
  const description = humanDescription(name, input);
1799
1903
  let permitted;
@@ -0,0 +1,20 @@
1
+ export interface PlanModeRefusal {
2
+ /** Machine-readable reason, for tests and telemetry. */
3
+ reason: 'mutating-tool' | 'bash-not-read-only';
4
+ /** Message shown to the MODEL. Must stop it retrying or asking for approval. */
5
+ message: string;
6
+ }
7
+ /**
8
+ * Is this bash command provably read-only?
9
+ *
10
+ * "Provably" is doing real work: unknown verbs are refused, not guessed at.
11
+ */
12
+ export declare function isReadOnlyCommand(command: string): boolean;
13
+ /**
14
+ * Should this tool call be refused because the session is in plan mode?
15
+ * Returns null when the call is allowed.
16
+ */
17
+ export declare function checkPlanMode(tool: string, input: Record<string, unknown>): PlanModeRefusal | null;
18
+ /** Text appended to the system prompt while plan mode is active. */
19
+ export declare const PLAN_MODE_INSTRUCTIONS: string;
20
+ //# sourceMappingURL=planMode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planMode.d.ts","sourceRoot":"","sources":["../../src/agent/planMode.ts"],"names":[],"mappings":"AAwHA,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,MAAM,EAAE,eAAe,GAAG,oBAAoB,CAAC;IAC/C,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAgE1D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,eAAe,GAAG,IAAI,CAoCxB;AAED,oEAAoE;AACpE,eAAO,MAAM,sBAAsB,QAqBvB,CAAC"}
@@ -0,0 +1,252 @@
1
+ "use strict";
2
+ // ─── Plan mode ───────────────────────────────────────────────────────────────
3
+ //
4
+ // A session-wide read-only lock. The model may research as deeply as it likes
5
+ // and must finish by PROPOSING a plan; it cannot change anything until a human
6
+ // leaves plan mode. Claude Code ships the same idea, and the reason to copy it
7
+ // is that "read the codebase, then tell me what you'd do" is otherwise
8
+ // unenforceable — you are relying on the model choosing not to edit, which is a
9
+ // promise, not a guarantee.
10
+ //
11
+ // The design rule here is FAIL CLOSED. Everything that is not provably
12
+ // side-effect-free is refused. A false refusal costs the user one message
13
+ // ("this needs plan mode off"); a false permit silently mutates a repo the user
14
+ // believed was frozen. Those are not symmetric, so ambiguity always loses.
15
+ //
16
+ // Note this is a DIFFERENT axis from the sub-agent tool allowlist in
17
+ // agentTypes.ts. That restricts one delegated worker; this restricts the whole
18
+ // session including the main agent and every sub-agent it spawns.
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.PLAN_MODE_INSTRUCTIONS = void 0;
21
+ exports.isReadOnlyCommand = isReadOnlyCommand;
22
+ exports.checkPlanMode = checkPlanMode;
23
+ /**
24
+ * Tools that cannot alter anything outside the conversation.
25
+ *
26
+ * Deliberately an ALLOWLIST. A denylist would mean every tool added later is
27
+ * writable-by-default in plan mode, and the person adding it has no reason to
28
+ * think about plan mode at all — the failure would ship silently. With an
29
+ * allowlist, a new tool is refused until someone deliberately classifies it,
30
+ * and the refusal is visible the first time anybody tries it.
31
+ */
32
+ const READ_ONLY_TOOLS = new Set([
33
+ 'read_file', 'search_files', 'glob', 'list_directory', 'notebook_read',
34
+ // Planning bookkeeping. todo_write persists only to the session's own todo
35
+ // list, not the repo, so it stays available — a plan mode that cannot draft
36
+ // a checklist is missing the point of plan mode.
37
+ 'todo_write', 'todo_read',
38
+ // Reading memory is fine; memory_write is NOT here on purpose. Memory is
39
+ // durable state that survives the session, so writing it is a real mutation
40
+ // even though no file in the repo changes.
41
+ 'memory_read',
42
+ 'use_skill',
43
+ 'fetch_url', 'web_search',
44
+ // Delegating research is ALLOWED, and this is safe rather than a hole:
45
+ // runSubTask passes planMode down, so the sub-agent is under the same lock and
46
+ // its own write tools are refused by this very function one level deeper.
47
+ //
48
+ // Worth allowing rather than blanket-refusing, because plan mode exists to
49
+ // support deep research and the explorer agent is the cheapest way to do bulk
50
+ // searching without flooding the main context. Blocking `task` would have made
51
+ // the mode's headline use case worse, for no security gain.
52
+ 'task',
53
+ // VS Code language server — all pure queries.
54
+ 'get_symbols', 'get_workspace_symbols', 'find_references', 'go_to_definition',
55
+ 'get_hover', 'get_diagnostics',
56
+ // Reading output from an ALREADY-running background shell. Starting one is
57
+ // gated with the rest of bash below; draining a buffer is not a new effect.
58
+ 'bash_output',
59
+ ]);
60
+ /**
61
+ * Commands allowed through `bash` in plan mode.
62
+ *
63
+ * bash is the hard case: it is one tool that spans `git log` and `rm -rf /`,
64
+ * so plan mode is only as strong as this list. Hence a strict allowlist of
65
+ * verbs known to be read-only, plus the argument screening in
66
+ * `isReadOnlyCommand` for the several that are read-only ONLY in some forms.
67
+ */
68
+ const READ_ONLY_BASH = new Set([
69
+ 'ls', 'cat', 'head', 'tail', 'wc', 'file', 'stat', 'du', 'df', 'pwd', 'which',
70
+ 'type', 'echo', 'printf', 'basename', 'dirname', 'realpath', 'readlink',
71
+ 'grep', 'egrep', 'fgrep', 'rg', 'ag', 'ack', 'find', 'fd', 'locate',
72
+ 'diff', 'comm', 'cmp', 'sort', 'uniq', 'cut', 'tr', 'column', 'jq', 'yq',
73
+ 'date', 'whoami', 'hostname', 'uname', 'env', 'printenv', 'id', 'groups',
74
+ 'ps', 'top', 'uptime', 'free', 'node', 'python', 'python3',
75
+ 'tree', 'less', 'more', 'nl', 'tac', 'strings', 'md5sum', 'sha256sum',
76
+ 'true', 'false', 'test', 'sleep', 'seq', 'expr',
77
+ ]);
78
+ /**
79
+ * Subcommands that are read-only for tools whose safety depends on the verb.
80
+ *
81
+ * `git` is the reason this exists: `git log` and `git push --force` share one
82
+ * binary, so classifying by executable name alone is useless here.
83
+ */
84
+ const READ_ONLY_SUBCOMMANDS = {
85
+ git: new Set([
86
+ 'log', 'show', 'diff', 'status', 'blame', 'branch', 'tag', 'remote',
87
+ 'describe', 'rev-parse', 'rev-list', 'ls-files', 'ls-tree', 'ls-remote',
88
+ 'cat-file', 'shortlog', 'reflog', 'whatchanged', 'grep', 'config',
89
+ 'check-ignore', 'merge-base', 'name-rev', 'count-objects', 'verify-commit',
90
+ ]),
91
+ // Package managers: only their query verbs.
92
+ npm: new Set(['ls', 'list', 'view', 'info', 'outdated', 'why', 'config', 'ping', 'search']),
93
+ pnpm: new Set(['ls', 'list', 'view', 'info', 'outdated', 'why', 'config']),
94
+ yarn: new Set(['list', 'info', 'why', 'config']),
95
+ cargo: new Set(['tree', 'metadata', 'search']),
96
+ go: new Set(['list', 'version', 'env', 'vet', 'doc']),
97
+ docker: new Set(['ps', 'images', 'logs', 'inspect', 'version', 'info', 'top', 'port', 'diff', 'stats']),
98
+ kubectl: new Set(['get', 'describe', 'logs', 'explain', 'top', 'version', 'api-resources', 'api-versions']),
99
+ // gh: read verbs only. `gh run rerun`, `gh pr merge` etc. are excluded, and
100
+ // the nested-verb check in isReadOnlyCommand handles `gh pr view` vs `gh pr merge`.
101
+ gh: new Set(['browse']),
102
+ };
103
+ /** Second-level read verbs for CLIs shaped as `<tool> <noun> <verb>`. */
104
+ const READ_ONLY_NESTED = {
105
+ gh: new Set(['view', 'list', 'status', 'diff', 'checks']),
106
+ };
107
+ /**
108
+ * Shell metacharacters that can smuggle a second command past verb inspection.
109
+ *
110
+ * We could parse the chain and check each segment — `destructive.ts` does
111
+ * something like that — but plan mode is a deliberate, temporary restriction:
112
+ * the honest answer to "can I run this compound pipeline while frozen?" is
113
+ * "no, and it costs you nothing to wait". Rejecting the whole shape is far
114
+ * easier to get right than parsing shell grammar, and being wrong here means
115
+ * writing to a repo the user thinks is locked.
116
+ *
117
+ * `|` is included: `cat x | tee y` writes, and so does `... | sh`.
118
+ */
119
+ const SHELL_CONTROL = /[\n\r;&|`]|\$\(|>>|>|<\(/;
120
+ function firstWords(command) {
121
+ return command.trim().split(/\s+/).filter(Boolean);
122
+ }
123
+ /**
124
+ * Is this bash command provably read-only?
125
+ *
126
+ * "Provably" is doing real work: unknown verbs are refused, not guessed at.
127
+ */
128
+ function isReadOnlyCommand(command) {
129
+ const cmd = command.trim();
130
+ if (!cmd)
131
+ return false;
132
+ // Any chaining/redirection/substitution — refuse the whole thing.
133
+ if (SHELL_CONTROL.test(cmd))
134
+ return false;
135
+ const words = firstWords(cmd);
136
+ if (!words.length)
137
+ return false;
138
+ // `VAR=x cmd` — skip leading environment assignments to find the real verb.
139
+ let i = 0;
140
+ while (i < words.length && /^[A-Za-z_][A-Za-z0-9_]*=/.test(words[i]))
141
+ i++;
142
+ if (i >= words.length)
143
+ return false;
144
+ let verb = words[i];
145
+ // Strip a path prefix: /usr/bin/git → git
146
+ const slash = verb.lastIndexOf('/');
147
+ if (slash >= 0)
148
+ verb = verb.slice(slash + 1);
149
+ // `sudo anything` is refused outright regardless of the verb behind it: plan
150
+ // mode is a promise about this machine, and privilege escalation is exactly
151
+ // where a mistaken allow is least recoverable.
152
+ if (verb === 'sudo' || verb === 'doas' || verb === 'su')
153
+ return false;
154
+ const rest = words.slice(i + 1).filter((w) => !w.startsWith('-'));
155
+ const subs = READ_ONLY_SUBCOMMANDS[verb];
156
+ if (subs) {
157
+ const sub = rest[0];
158
+ if (!sub) {
159
+ // Bare `git` / `npm` just prints help — harmless.
160
+ return true;
161
+ }
162
+ if (subs.has(sub)) {
163
+ // `git config --global x y` WRITES. Only the read form (no value) passes.
164
+ if (verb === 'git' && sub === 'config') {
165
+ const args = words.slice(i + 2).filter((w) => !w.startsWith('-'));
166
+ return args.length <= 1;
167
+ }
168
+ return true;
169
+ }
170
+ const nested = READ_ONLY_NESTED[verb];
171
+ if (nested && rest[1] && nested.has(rest[1]))
172
+ return true;
173
+ return false;
174
+ }
175
+ if (!READ_ONLY_TOOLS.has(verb) && !READ_ONLY_BASH.has(verb))
176
+ return false;
177
+ // Interpreters can execute arbitrary code inline; only allow the trivial
178
+ // read-only forms (`node --version`). `node -e "fs.rmSync(...)"` must not pass.
179
+ if (verb === 'node' || verb === 'python' || verb === 'python3') {
180
+ return words.slice(i + 1).every((w) => w === '--version' || w === '-V' || w === '-v');
181
+ }
182
+ // `find` can execute and delete.
183
+ if (verb === 'find' && words.some((w) => w === '-exec' || w === '-execdir' || w === '-delete')) {
184
+ return false;
185
+ }
186
+ // Reading a file with `test`/`stat` is fine, but `tee` is not in the list at
187
+ // all, and `echo`/`printf` are only safe because redirection is already
188
+ // rejected by SHELL_CONTROL above.
189
+ return true;
190
+ }
191
+ /**
192
+ * Should this tool call be refused because the session is in plan mode?
193
+ * Returns null when the call is allowed.
194
+ */
195
+ function checkPlanMode(tool, input) {
196
+ if (tool === 'bash') {
197
+ const command = typeof input.command === 'string' ? input.command : '';
198
+ // Starting a background process in a "frozen" session is a side effect that
199
+ // outlives the refusal, so it is refused even for an otherwise-safe verb.
200
+ if (input.run_in_background === true) {
201
+ return {
202
+ reason: 'bash-not-read-only',
203
+ message: 'Plan mode is ON: background processes cannot be started. Finish researching and propose ' +
204
+ 'your plan; the user will leave plan mode if they want it carried out.',
205
+ };
206
+ }
207
+ if (isReadOnlyCommand(command))
208
+ return null;
209
+ return {
210
+ reason: 'bash-not-read-only',
211
+ message: `Plan mode is ON, so \`bash\` is limited to provably read-only commands and this one was not ` +
212
+ 'recognised as such (chained commands, redirection and command substitution are always refused). ' +
213
+ 'Do NOT ask the user to approve it and do NOT try a variation to get around this — it is a ' +
214
+ 'session-wide lock, not a per-call prompt. Use read-only inspection instead, and put the command ' +
215
+ 'in your plan as a step to run once plan mode is off.',
216
+ };
217
+ }
218
+ if (READ_ONLY_TOOLS.has(tool))
219
+ return null;
220
+ return {
221
+ reason: 'mutating-tool',
222
+ message: `Plan mode is ON, so \`${tool}\` is unavailable — this session may not modify anything yet. ` +
223
+ 'Do NOT ask for approval: no answer the user gives at this prompt can unlock it, because it is a ' +
224
+ 'session-wide lock they control directly. Research with read-only tools and finish by proposing ' +
225
+ 'a concrete plan (files to change, in order, and how to verify). The user will exit plan mode to ' +
226
+ 'let you carry it out.',
227
+ };
228
+ }
229
+ /** Text appended to the system prompt while plan mode is active. */
230
+ exports.PLAN_MODE_INSTRUCTIONS = [
231
+ '# PLAN MODE IS ACTIVE',
232
+ '',
233
+ 'This session is READ-ONLY. You cannot edit files, write files, run mutating commands, or start',
234
+ 'background processes. This is enforced outside your control — it is not a permission prompt, and',
235
+ 'the user cannot approve an exception from inside this turn.',
236
+ '',
237
+ 'Therefore:',
238
+ '- NEVER ask "shall I go ahead and make this change?" — you cannot, whatever the answer.',
239
+ '- NEVER attempt a mutating tool "just to see" — it will be refused and wastes the turn.',
240
+ '- NEVER try to reach a blocked command another way (a different flag, a script, an interpreter).',
241
+ '',
242
+ 'Your job is to research thoroughly, then deliver a plan:',
243
+ '1. What you found — the specific files, functions and line numbers that matter.',
244
+ '2. What you propose to change — file by file, in dependency order.',
245
+ '3. Risks and unknowns — what could break, what you could not verify, what you assumed.',
246
+ '4. How it will be verified — the exact build/test/lint command that proves it works.',
247
+ '',
248
+ 'Be concrete. "Update the auth logic" is not a plan; "add a `refreshToken` field to AuthConfig in',
249
+ 'auth/index.ts:42, then thread it through client.ts:118" is. The user will review the plan and',
250
+ 'leave plan mode to have it carried out.',
251
+ ].join('\n');
252
+ //# sourceMappingURL=planMode.js.map
package/dist/index.d.ts CHANGED
@@ -17,6 +17,8 @@ export * from './mcp/manager';
17
17
  export * from './checkpoint/manager';
18
18
  export * from './commands/loader';
19
19
  export * from './agent/agentTypes';
20
+ export * from './agent/planMode';
21
+ export * from './agent/agentRegistry';
20
22
  export * from './permissions/rules';
21
23
  export * from './permissions/destructive';
22
24
  export * from './plugins/index';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -33,6 +33,8 @@ __exportStar(require("./mcp/manager"), exports);
33
33
  __exportStar(require("./checkpoint/manager"), exports);
34
34
  __exportStar(require("./commands/loader"), exports);
35
35
  __exportStar(require("./agent/agentTypes"), exports);
36
+ __exportStar(require("./agent/planMode"), exports);
37
+ __exportStar(require("./agent/agentRegistry"), exports);
36
38
  __exportStar(require("./permissions/rules"), exports);
37
39
  __exportStar(require("./permissions/destructive"), exports);
38
40
  __exportStar(require("./plugins/index"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/permissions/rules.ts"],"names":[],"mappings":"AAwBA,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,eAAe,CAAC;IAC7B,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9B;AAsBD,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAoB5D;AAgID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,MAAM,GACd,kBAAkB,GAAG,IAAI,CAK3B"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/permissions/rules.ts"],"names":[],"mappings":"AAwBA,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,eAAe,CAAC;IAC7B,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9B;AAsBD,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAoB5D;AA8ID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,MAAM,GACd,kBAAkB,GAAG,IAAI,CAK3B"}
@@ -174,6 +174,20 @@ function matchValues(tool, input, workDir) {
174
174
  case 'stock_photo':
175
175
  vals.push(str(input.path));
176
176
  break;
177
+ // Sub-agent dispatch. Matching on the agent NAME is what makes
178
+ // `deny: ["task(explorer)"]` mean "this repo may not use the explorer
179
+ // agent" — the Claude-Code way of switching off a built-in you don't want.
180
+ //
181
+ // Without this case, `task` fell through to `default`, which reads
182
+ // `input.path` — a key the task tool does not have. Every patterned task
183
+ // rule therefore matched nothing and silently did nothing, which is the
184
+ // worst failure mode for a deny rule: it looks configured and isn't.
185
+ //
186
+ // A bare `task` rule (no pattern) still matches any dispatch, so
187
+ // `deny: ["task"]` disables sub-agents wholesale.
188
+ case 'task':
189
+ vals.push(str(input.subagent_type));
190
+ break;
177
191
  default:
178
192
  pushPath(str(input.path));
179
193
  break;
package/dist/types.d.ts CHANGED
@@ -321,6 +321,15 @@ export interface AgentLoopOptions {
321
321
  env?: EnvContext;
322
322
  editorContext?: EditorContext | null;
323
323
  nexrallMd?: string;
324
+ /**
325
+ * Session-wide read-only lock ("plan mode"). When true the loop refuses every
326
+ * mutating tool BEFORE requestPermission is consulted, so no user answer at a
327
+ * permission prompt can unlock it — only leaving plan mode can.
328
+ *
329
+ * Inherited by every sub-agent: a lock the main agent can delegate its way
330
+ * out of is not a lock.
331
+ */
332
+ planMode?: boolean;
324
333
  /** Client type — controls which tools Claude is told about. */
325
334
  clientType?: string;
326
335
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexrall/code-core",
3
- "version": "1.4.25",
3
+ "version": "1.4.26",
4
4
  "description": "Core agent loop, tools, and extension primitives for Nexrall Code — embed an AI coding agent in any Node.js application.",
5
5
  "license": "MIT",
6
6
  "author": "Nexrall <support@nexrall.com> (https://nexrall.com)",