@juspay/neurolink 12.1.0 → 12.2.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.
Files changed (35) hide show
  1. package/CHANGELOG.md +2 -2
  2. package/dist/agent/agentToolRegistrar.d.ts +30 -0
  3. package/dist/agent/agentToolRegistrar.js +72 -18
  4. package/dist/agent/backgroundCommands.d.ts +110 -0
  5. package/dist/agent/backgroundCommands.js +914 -0
  6. package/dist/agent/backgroundDelegation.d.ts +87 -0
  7. package/dist/agent/backgroundDelegation.js +753 -0
  8. package/dist/agent/gitTools.d.ts +43 -0
  9. package/dist/agent/gitTools.js +618 -0
  10. package/dist/agent/taskChecklist.d.ts +58 -0
  11. package/dist/agent/taskChecklist.js +322 -0
  12. package/dist/artifacts/artifactBanking.d.ts +57 -0
  13. package/dist/artifacts/artifactBanking.js +123 -0
  14. package/dist/artifacts/artifactStore.d.ts +36 -8
  15. package/dist/artifacts/artifactStore.js +164 -13
  16. package/dist/browser/neurolink.min.js +442 -414
  17. package/dist/neurolink.d.ts +294 -3
  18. package/dist/neurolink.js +447 -4
  19. package/dist/types/artifact.d.ts +54 -0
  20. package/dist/types/backgroundCommand.d.ts +174 -0
  21. package/dist/types/backgroundCommand.js +22 -0
  22. package/dist/types/delegation.d.ts +178 -0
  23. package/dist/types/delegation.js +18 -0
  24. package/dist/types/gitTools.d.ts +69 -0
  25. package/dist/types/gitTools.js +22 -0
  26. package/dist/types/index.d.ts +5 -0
  27. package/dist/types/index.js +8 -0
  28. package/dist/types/pathSandbox.d.ts +23 -0
  29. package/dist/types/pathSandbox.js +12 -0
  30. package/dist/types/tasks.d.ts +85 -0
  31. package/dist/types/tasks.js +14 -0
  32. package/dist/types/tools.d.ts +11 -0
  33. package/dist/utils/pathSandbox.d.ts +49 -0
  34. package/dist/utils/pathSandbox.js +127 -0
  35. package/package.json +5 -1
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Background commands (N4) — run a command detached, bank its output, monitor
3
+ * it — types.
4
+ *
5
+ * A long-running agent has to run real commands: a build, a test suite, a
6
+ * linter whose output is the evidence for a review finding. Two things make
7
+ * that safe and useful, and both are in these types.
8
+ *
9
+ * 1. **Nothing is discarded.** Both streams go straight to files and the FULL
10
+ * files are banked as artifacts when the command settles. What reaches the
11
+ * conversation is a bounded `tailPreview` plus a {@link BankedArtifactRef}
12
+ * per stream — a pointer, never a replacement. `maxOutputBytes` is the one
13
+ * bound, and hitting it is a loud state (`output-limit`), not a silent cut.
14
+ * 2. **Execution is a contract, not advice.** `argv` arrays only, no shell
15
+ * ever; an executable allowlist; a cwd that must resolve, through symlinks,
16
+ * inside a declared root; a timeout that actually kills.
17
+ *
18
+ * Naming: `cli.ts` already owns `CommandResult` / `CommandDefinition` and
19
+ * `action.ts` owns `ActionCommand`, so everything here carries the
20
+ * `BackgroundCommand` prefix (Critical Rule 9).
21
+ */
22
+ import type { BankedArtifactRef } from "./artifact.js";
23
+ /** Which of a command's two output streams a page or artifact refers to. */
24
+ export type BackgroundCommandStreamName = "stdout" | "stderr";
25
+ /**
26
+ * Lifecycle of one background command.
27
+ *
28
+ * `queued` is the window between the handle being returned and the OS
29
+ * confirming the child started. The four settled states are deliberately
30
+ * distinct: "the command failed" and "we killed it because it printed 4 GB"
31
+ * are different facts about a run, and collapsing them loses the one a
32
+ * reviewer needs.
33
+ */
34
+ export type BackgroundCommandState = "queued" | "running" | "exited" | "killed" | "timeout" | "output-limit";
35
+ /** `true` to allow, or a string giving the reason the command was refused. */
36
+ export type BackgroundCommandAllowDecision = true | string;
37
+ /**
38
+ * What a host permits. There is no default policy: without one every start is
39
+ * refused, because "run whatever the model asks" is not a defensible default
40
+ * for a primitive that executes processes.
41
+ */
42
+ export type BackgroundCommandPolicy = {
43
+ /**
44
+ * Executables that may be started, matched EXACTLY against `argv[0]` — no
45
+ * basename fallback, so allowlisting `git` never permits `/tmp/evil/git`.
46
+ * Required, and an empty list refuses everything.
47
+ */
48
+ allowedExecutables: string[];
49
+ /**
50
+ * Final say after the allowlist and the sandbox have passed. Return `true`
51
+ * to allow, or a string that is handed to the caller as the refusal reason
52
+ * (so put the recovery step in it).
53
+ */
54
+ allowlist?: (argv: string[], cwd: string) => BackgroundCommandAllowDecision;
55
+ /**
56
+ * Sandbox root. The resolved REAL cwd (symlinks followed) must be this
57
+ * directory or inside it.
58
+ */
59
+ cwdRoot: string;
60
+ /** Wall-clock budget when the caller names none. Default 120_000. */
61
+ defaultTimeoutMs?: number;
62
+ /** Per-stream byte cap when the caller names none. Default 10_485_760. */
63
+ maxOutputBytes?: number;
64
+ };
65
+ /**
66
+ * Per-start options. Only `timeoutMs` and `maxOutputBytes` fall back to the
67
+ * policy's defaults. The rest have their own omission behaviour: `env`
68
+ * inherits the parent environment, `label` defaults to `argv[0]`, `sessionId`
69
+ * resolves from the host's tool context, and `abortSignal` simply has no
70
+ * fallback.
71
+ */
72
+ export type BackgroundCommandOptions = {
73
+ /** Working directory. Must resolve inside `BackgroundCommandPolicy.cwdRoot`. */
74
+ cwd: string;
75
+ /** Wall-clock budget in ms; SIGTERM then SIGKILL. */
76
+ timeoutMs?: number;
77
+ /** Per-stream byte cap; hitting it kills the command with `output-limit`. */
78
+ maxOutputBytes?: number;
79
+ /**
80
+ * Environment for the child. When given it REPLACES the parent environment
81
+ * rather than extending it — the command gets exactly these variables and
82
+ * nothing else. Omit it to inherit the parent environment, which is what a
83
+ * repository's own checks normally need.
84
+ */
85
+ env?: Record<string, string>;
86
+ /** Short human label for logs and the banked artifacts. Defaults to argv[0]. */
87
+ label?: string;
88
+ /** Session the command belongs to; scopes the outstanding counters. */
89
+ sessionId?: string;
90
+ /** Parent cancellation — an aborted parent kills the command. */
91
+ abortSignal?: AbortSignal;
92
+ };
93
+ /** Returned the moment a command is accepted — before it has produced output. */
94
+ export type BackgroundCommandHandle = {
95
+ taskId: string;
96
+ argv: string[];
97
+ startedAt: number;
98
+ };
99
+ /**
100
+ * Everything known about one command right now.
101
+ *
102
+ * `stdout` / `stderr` appear once the command has settled and its streams have
103
+ * been banked; `tailPreview` is available throughout and is always bounded.
104
+ * The preview is for orientation — the banked artifacts are the evidence.
105
+ */
106
+ export type BackgroundCommandStatus = {
107
+ taskId: string;
108
+ /** Short human label, e.g. "git log" — which command this is. */
109
+ label: string;
110
+ state: BackgroundCommandState;
111
+ /** Process exit code, once it exited on its own. */
112
+ exitCode?: number;
113
+ /** Signal that ended the process, when one did. */
114
+ signal?: string;
115
+ durationMs: number;
116
+ /** Bytes written to each stream's log file so far. */
117
+ stdoutBytes: number;
118
+ stderrBytes: number;
119
+ /** The FULL stdout, banked (N3). Present once settled. */
120
+ stdout?: BankedArtifactRef;
121
+ /** The FULL stderr, banked (N3). Present once settled. */
122
+ stderr?: BankedArtifactRef;
123
+ /** Tail of the output so far, ≤ 2000 chars. Never a substitute for the files. */
124
+ tailPreview: string;
125
+ /** Why the command could not run, or how it was cut short. */
126
+ error?: string;
127
+ };
128
+ /** One character window of a command's output, read straight from the log file. */
129
+ export type BackgroundCommandOutputPage = {
130
+ taskId: string;
131
+ stream: BackgroundCommandStreamName;
132
+ content: string;
133
+ offset: number;
134
+ limit: number;
135
+ /** Characters in the whole stream, including what this page did not return. */
136
+ totalSize: number;
137
+ hasMore: boolean;
138
+ };
139
+ /** Character window for a paginated output read. */
140
+ export type BackgroundCommandPageRequest = {
141
+ stream: BackgroundCommandStreamName;
142
+ /** Character offset to start at. Default 0. */
143
+ offset?: number;
144
+ /** Maximum characters to return. Default 50_000, hard cap 200_000. */
145
+ limit?: number;
146
+ };
147
+ /**
148
+ * Outstanding commands for a session: `running` have not settled yet, and
149
+ * `finished` have settled without anyone having looked at them since.
150
+ *
151
+ * "Not looked at" rather than "ever finished" is what makes the number
152
+ * actionable — reading a settled command's status or output clears it, so a
153
+ * non-zero `finished` always means there is something new to read. Nothing is
154
+ * discarded when it clears: the job, its logs and its artifacts stay exactly
155
+ * where they were.
156
+ *
157
+ * Carried on every command tool result and — via the checklist — on every
158
+ * `tasks_list`, so the model learns a build finished without polling.
159
+ */
160
+ export type BackgroundCommandCounts = {
161
+ running: number;
162
+ finished: number;
163
+ };
164
+ /** Supplies {@link BackgroundCommandCounts} to the task checklist. */
165
+ export type BackgroundCommandCountsSource = (sessionId: string) => BackgroundCommandCounts;
166
+ /** What `run_command_bg` returns: the handle plus the outstanding counters. */
167
+ export type BackgroundCommandStartToolResult = BackgroundCommandHandle & BackgroundCommandCounts;
168
+ /** What the monitor tools return: a status plus the outstanding counters. */
169
+ export type BackgroundCommandStatusToolResult = BackgroundCommandStatus & BackgroundCommandCounts;
170
+ /** Refusal shape shared with the agent tool registrar: recovery text included. */
171
+ export type BackgroundCommandRefusal = {
172
+ isError: true;
173
+ error: string;
174
+ };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Background commands (N4) — run a command detached, bank its output, monitor
3
+ * it — types.
4
+ *
5
+ * A long-running agent has to run real commands: a build, a test suite, a
6
+ * linter whose output is the evidence for a review finding. Two things make
7
+ * that safe and useful, and both are in these types.
8
+ *
9
+ * 1. **Nothing is discarded.** Both streams go straight to files and the FULL
10
+ * files are banked as artifacts when the command settles. What reaches the
11
+ * conversation is a bounded `tailPreview` plus a {@link BankedArtifactRef}
12
+ * per stream — a pointer, never a replacement. `maxOutputBytes` is the one
13
+ * bound, and hitting it is a loud state (`output-limit`), not a silent cut.
14
+ * 2. **Execution is a contract, not advice.** `argv` arrays only, no shell
15
+ * ever; an executable allowlist; a cwd that must resolve, through symlinks,
16
+ * inside a declared root; a timeout that actually kills.
17
+ *
18
+ * Naming: `cli.ts` already owns `CommandResult` / `CommandDefinition` and
19
+ * `action.ts` owns `ActionCommand`, so everything here carries the
20
+ * `BackgroundCommand` prefix (Critical Rule 9).
21
+ */
22
+ export {};
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Async delegation (N2) — spawn a background worker, collect it later, in any
3
+ * order — types.
4
+ *
5
+ * Delegation today is a synchronous tool call: the supervising agent blocks
6
+ * until the worker is done, so four investigations take four times as long as
7
+ * one and the supervisor cannot do anything useful while it waits. These types
8
+ * describe the background form — `spawn` hands back a `DelegateHandle`
9
+ * immediately, `collect` returns whichever worker finished FIRST regardless of
10
+ * which was started first, and each outcome carries a bounded summary plus a
11
+ * {@link BankedArtifactRef} to the worker's full report, which is banked to a
12
+ * file rather than pushed into the conversation.
13
+ *
14
+ * Naming: `agentNetwork.ts` already owns `DelegationRule` / `DelegationCondition`
15
+ * and `isolatedAgent.ts` owns `AgentDelegationTurnState`, so everything here
16
+ * carries the `Delegate` prefix (Critical Rule 9).
17
+ */
18
+ import type { BankedArtifactRef } from "./artifact.js";
19
+ import type { AgentRunStatus } from "./isolatedAgent.js";
20
+ /** What a supervisor hands down when it spawns a background worker. */
21
+ export type DelegateSpawnOptions = {
22
+ /** The task, in the supervisor's own words. Required and non-empty. */
23
+ task: string;
24
+ /** What the worker may look at — files, directories, systems. */
25
+ scope?: string;
26
+ /** Brief slice of context handed down (never the whole rulebook). */
27
+ context?: string;
28
+ /** Model override for this worker. */
29
+ model?: string;
30
+ /** Provider override for this worker. */
31
+ provider?: string;
32
+ /** Read-only tool allowlist for the worker (tool names). */
33
+ tools?: string[];
34
+ /**
35
+ * Caller's session. Collection is scoped to it, and it is the key the task
36
+ * checklist's `delegatesPending` / `delegatesReady` counters are read by.
37
+ * Defaults to the session the host's tool context declares.
38
+ */
39
+ sessionId?: string;
40
+ /** Caller's delegation depth; the worker runs one level deeper. */
41
+ depth?: number;
42
+ /** Short human label used in logs and in the banked report's name. */
43
+ label?: string;
44
+ /** Parent cancellation — an aborted parent cancels this worker. */
45
+ abortSignal?: AbortSignal;
46
+ /** Max agentic steps for the worker's research pass. */
47
+ maxSteps?: number;
48
+ /** Wall-clock budget for the worker's research pass (ms). */
49
+ budgetMs?: number;
50
+ };
51
+ /**
52
+ * Returned the moment a worker is spawned — before it has run anything.
53
+ * `queued` is true when the process-wide delegation pool was full and the
54
+ * worker is waiting for a slot.
55
+ */
56
+ export type DelegateHandle = {
57
+ workerId: string;
58
+ spawnedAt: number;
59
+ queued: boolean;
60
+ };
61
+ /**
62
+ * A settled worker, claimed exactly once.
63
+ *
64
+ * `summary` is bounded; `report` points at the COMPLETE report on disk. The
65
+ * two are not alternatives — the summary is what the conversation carries, the
66
+ * report is what the evidence lives in.
67
+ */
68
+ export type DelegateOutcome = {
69
+ workerId: string;
70
+ /** Human label the spawn was given (defaults to the worker id). */
71
+ label: string;
72
+ /** Reused from the isolated-agent runner — no parallel taxonomy. */
73
+ status: AgentRunStatus;
74
+ /** True for `completed` and `partial`: the worker produced usable evidence. */
75
+ ok: boolean;
76
+ /** Bounded narrative for the conversation. Never the whole report. */
77
+ summary: string;
78
+ /** The FULL report, always banked to a file. */
79
+ report: BankedArtifactRef;
80
+ durationMs: number;
81
+ toolCallsUsed: number;
82
+ /** Mechanical waste signatures the runner tripped, if any. */
83
+ wasteSignals?: string[];
84
+ /** `continueAgent()` handle when the worker was cut short mid-investigation. */
85
+ handle?: string;
86
+ /** Why the worker failed, when it did. */
87
+ error?: string;
88
+ };
89
+ /** `any` returns the first worker to finish; `all` waits for every one. */
90
+ export type DelegateCollectMode = "any" | "all";
91
+ /**
92
+ * What to collect. `waitMs` of 0 polls (return what is ready right now);
93
+ * omitting it uses the runtime default.
94
+ */
95
+ export type DelegateCollectRequest = {
96
+ mode: DelegateCollectMode;
97
+ waitMs?: number;
98
+ sessionId?: string;
99
+ } | {
100
+ workerId: string;
101
+ waitMs?: number;
102
+ sessionId?: string;
103
+ };
104
+ /**
105
+ * Outcomes claimed by one collect call, in COMPLETION order — the order
106
+ * workers finished in, which has nothing to do with the order they were
107
+ * spawned in.
108
+ */
109
+ export type DelegateCollectResult = {
110
+ /** Claimed exactly once: these outcomes are gone from the registry. */
111
+ completed: DelegateOutcome[];
112
+ /** Still running or waiting for a pool slot. */
113
+ pending: number;
114
+ /** Finished but not yet claimed. */
115
+ ready: number;
116
+ /**
117
+ * True when the wait expired before this call claimed what it asked for:
118
+ * for a named worker, that worker's outcome; for `any`, any outcome while
119
+ * work was still pending; for `all`, pending work remained when the wait
120
+ * ran out. A collect that claimed something reports `false` even if other
121
+ * work is still outstanding — `pending`/`ready` carry that.
122
+ */
123
+ timedOut: boolean;
124
+ };
125
+ /** Lifecycle of one background job. `claimed` jobs are dropped immediately. */
126
+ export type DelegateJobPhase = "queued" | "running" | "ready" | "claimed";
127
+ /**
128
+ * Provider/model a model-invoked `delegate_task` spawn falls back to. The spawn
129
+ * schema deliberately exposes no `provider` — a model cannot name a provider it
130
+ * cannot see — so without a default the worker instance falls back to provider
131
+ * auto-selection, which on a host with stray credentials puts a worker on a
132
+ * provider nobody configured — observed live as workers walking several
133
+ * unconfigured providers before reaching the configured one. The model's own
134
+ * `model` argument still wins over `model` here.
135
+ */
136
+ export type DelegateSpawnDefaults = {
137
+ provider?: string;
138
+ model?: string;
139
+ };
140
+ /** Per-host delegation policy, resolved from registration options. */
141
+ export type DelegateRuntimeSettings = {
142
+ /** Caller depth at which `delegate_task` refuses rather than spawning. */
143
+ maxDepth: number;
144
+ /** How long a spawned worker waits for a pool slot before giving up (ms). */
145
+ poolQueueTimeoutMs: number;
146
+ /** Default `waitMs` for a collect that does not name one (ms). */
147
+ defaultCollectWaitMs: number;
148
+ /** Defaults merged under every model-invoked `delegate_task` spawn. */
149
+ spawnDefaults?: DelegateSpawnDefaults;
150
+ };
151
+ /** Options for `NeuroLink.registerDelegationTools()`. */
152
+ export type DelegateRegistrationOptions = {
153
+ /**
154
+ * Caller depth at which further delegation is refused. Default 1: a
155
+ * background worker does not spawn background workers, because nothing
156
+ * would ever collect them.
157
+ */
158
+ maxDepth?: number;
159
+ /**
160
+ * Raise the process-wide delegation pool to at least this many concurrent
161
+ * workers. The pool is shared with `registerAgentTool` and only ever rises.
162
+ */
163
+ maxConcurrent?: number;
164
+ /** Queue wait before a spawned worker gives up on a pool slot (ms). */
165
+ poolQueueTimeoutMs?: number;
166
+ /** Provider/model for model-invoked spawns — see {@link DelegateSpawnDefaults}. */
167
+ spawnDefaults?: DelegateSpawnDefaults;
168
+ };
169
+ /** What `delegate_task` returns: the handle plus the outstanding counters. */
170
+ export type DelegateSpawnToolResult = DelegateHandle & {
171
+ pending: number;
172
+ ready: number;
173
+ };
174
+ /** Refusal shape shared with the agent tool registrar: recovery text included. */
175
+ export type DelegateRefusal = {
176
+ isError: true;
177
+ error: string;
178
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Async delegation (N2) — spawn a background worker, collect it later, in any
3
+ * order — types.
4
+ *
5
+ * Delegation today is a synchronous tool call: the supervising agent blocks
6
+ * until the worker is done, so four investigations take four times as long as
7
+ * one and the supervisor cannot do anything useful while it waits. These types
8
+ * describe the background form — `spawn` hands back a `DelegateHandle`
9
+ * immediately, `collect` returns whichever worker finished FIRST regardless of
10
+ * which was started first, and each outcome carries a bounded summary plus a
11
+ * {@link BankedArtifactRef} to the worker's full report, which is banked to a
12
+ * file rather than pushed into the conversation.
13
+ *
14
+ * Naming: `agentNetwork.ts` already owns `DelegationRule` / `DelegationCondition`
15
+ * and `isolatedAgent.ts` owns `AgentDelegationTurnState`, so everything here
16
+ * carries the `Delegate` prefix (Critical Rule 9).
17
+ */
18
+ export {};
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Read-only git toolset (N4.4) — types.
3
+ *
4
+ * A reviewing agent needs git constantly: what changed, who wrote it, what the
5
+ * merge base was. Handing it a shell to run `git` in is the wrong shape twice
6
+ * over — it can then run anything, and git itself has write-capable options
7
+ * (`--output=<file>`, `diff.external`) that a free-form argument string would
8
+ * carry straight through.
9
+ *
10
+ * So these tools are BOUNDED: the model supplies validated values (a ref, a
11
+ * path, a line range), never flags, and each tool assembles a fixed argv from
12
+ * them. The whole surface is six read-only subcommands. Execution goes through
13
+ * the same hardened runner as {@link BackgroundCommandPolicy} — argv arrays,
14
+ * no shell, a cwd sandboxed to the repository, a timeout, a byte cap — and the
15
+ * full output is banked, so a 40 MB diff costs a bounded preview plus a
16
+ * pointer.
17
+ *
18
+ * Naming: nothing else in the types folder claims `Git`, and `tools.ts` owns
19
+ * the unprefixed `Tool*` names, so these carry the `GitTool` prefix
20
+ * (Critical Rule 9).
21
+ */
22
+ import type { BankedArtifactRef } from "./artifact.js";
23
+ import type { BackgroundCommandState } from "./backgroundCommand.js";
24
+ /** How `git log` should render each commit. Presets only — never a raw format. */
25
+ export type GitToolLogFormat = "oneline" | "full" | "stat" | "name-only";
26
+ /** Options for `NeuroLink.registerGitTools()`. */
27
+ export type GitToolsetOptions = {
28
+ /**
29
+ * Repository root. Every git tool runs here, and every path argument must
30
+ * resolve inside it.
31
+ */
32
+ repoRoot: string;
33
+ /** Wall-clock budget per git invocation (ms). Default 60_000. */
34
+ timeoutMs?: number;
35
+ /** Byte cap per stream. Default 33_554_432 (a big diff is still a diff). */
36
+ maxOutputBytes?: number;
37
+ /** Characters of output returned inline. Default 2000, hard cap 4000. */
38
+ previewChars?: number;
39
+ /** Executable to run. Default "git"; name an absolute path to pin it. */
40
+ gitExecutable?: string;
41
+ };
42
+ /**
43
+ * What every git tool returns.
44
+ *
45
+ * `preview` is a bounded head slice for the conversation; `output` points at
46
+ * the COMPLETE stdout on disk. They are not alternatives — a `git diff` whose
47
+ * preview looks empty may still have banked megabytes.
48
+ */
49
+ export type GitToolResult = {
50
+ /** The exact argv that ran, so the result is reproducible by hand. */
51
+ command: string[];
52
+ /** True when git exited 0. */
53
+ ok: boolean;
54
+ exitCode?: number;
55
+ state: BackgroundCommandState;
56
+ /** Bounded head slice of stdout. */
57
+ preview: string;
58
+ /** The FULL stdout, banked (N3). */
59
+ output: BankedArtifactRef;
60
+ /** Literal `retrieve_context` call that reads the rest of stdout. */
61
+ readBackHint: string;
62
+ /** Bounded head slice of stderr, present only when git wrote something there. */
63
+ stderrPreview?: string;
64
+ };
65
+ /** Refusal shape shared with the agent tool registrar: recovery text included. */
66
+ export type GitToolRefusal = {
67
+ isError: true;
68
+ error: string;
69
+ };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Read-only git toolset (N4.4) — types.
3
+ *
4
+ * A reviewing agent needs git constantly: what changed, who wrote it, what the
5
+ * merge base was. Handing it a shell to run `git` in is the wrong shape twice
6
+ * over — it can then run anything, and git itself has write-capable options
7
+ * (`--output=<file>`, `diff.external`) that a free-form argument string would
8
+ * carry straight through.
9
+ *
10
+ * So these tools are BOUNDED: the model supplies validated values (a ref, a
11
+ * path, a line range), never flags, and each tool assembles a fixed argv from
12
+ * them. The whole surface is six read-only subcommands. Execution goes through
13
+ * the same hardened runner as {@link BackgroundCommandPolicy} — argv arrays,
14
+ * no shell, a cwd sandboxed to the repository, a timeout, a byte cap — and the
15
+ * full output is banked, so a 40 MB diff costs a bounded preview plus a
16
+ * pointer.
17
+ *
18
+ * Naming: nothing else in the types folder claims `Git`, and `tools.ts` owns
19
+ * the unprefixed `Tool*` names, so these carry the `GitTool` prefix
20
+ * (Critical Rule 9).
21
+ */
22
+ export {};
@@ -18,6 +18,10 @@ export * from "./config.js";
18
18
  export * from "./context.js";
19
19
  export * from "./conversation.js";
20
20
  export * from "./conversationMemoryInterface.js";
21
+ export * from "./delegation.js";
22
+ export * from "./backgroundCommand.js";
23
+ export * from "./gitTools.js";
24
+ export * from "./pathSandbox.js";
21
25
  export * from "./domain.js";
22
26
  export * from "./errors.js";
23
27
  export * from "./evaluation.js";
@@ -58,6 +62,7 @@ export * from "./streaming.js";
58
62
  export * from "./subscription.js";
59
63
  export * from "./task.js";
60
64
  export * from "./taskClassification.js";
65
+ export * from "./tasks.js";
61
66
  export * from "./toolDedup.js";
62
67
  export * from "./toolResolution.js";
63
68
  export * from "./toolRouting.js";
@@ -19,6 +19,13 @@ export * from "./config.js";
19
19
  export * from "./context.js";
20
20
  export * from "./conversation.js";
21
21
  export * from "./conversationMemoryInterface.js";
22
+ export * from "./delegation.js";
23
+ // Background commands (N4) — detached execution, banked output, monitors
24
+ export * from "./backgroundCommand.js";
25
+ // Read-only git toolset (N4.4) built on the background-command runner
26
+ export * from "./gitTools.js";
27
+ // Path containment guard shared by the sandboxed execution paths
28
+ export * from "./pathSandbox.js";
22
29
  export * from "./domain.js";
23
30
  export * from "./errors.js";
24
31
  export * from "./evaluation.js";
@@ -59,6 +66,7 @@ export * from "./streaming.js";
59
66
  export * from "./subscription.js";
60
67
  export * from "./task.js";
61
68
  export * from "./taskClassification.js";
69
+ export * from "./tasks.js";
62
70
  export * from "./toolDedup.js";
63
71
  export * from "./toolResolution.js";
64
72
  export * from "./toolRouting.js";
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Path sandboxing — types.
3
+ *
4
+ * One shape, used by every guard that has to answer "may this path be
5
+ * touched?": the resolved real path, or the reason it was refused. A
6
+ * discriminated result rather than a thrown error, because a refusal is an
7
+ * ordinary answer a tool turns into recovery text, not an exceptional one.
8
+ *
9
+ * Naming: `file.ts` already owns `FilePath*`, so this carries the
10
+ * `PathSandbox` prefix (Critical Rule 9).
11
+ */
12
+ /**
13
+ * Outcome of a containment check. Exactly one branch is present, so a caller
14
+ * that forgets to check `error` cannot accidentally read a path that was
15
+ * refused.
16
+ */
17
+ export type PathSandboxResult = {
18
+ path: string;
19
+ error?: undefined;
20
+ } | {
21
+ path?: undefined;
22
+ error: string;
23
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Path sandboxing — types.
3
+ *
4
+ * One shape, used by every guard that has to answer "may this path be
5
+ * touched?": the resolved real path, or the reason it was refused. A
6
+ * discriminated result rather than a thrown error, because a refusal is an
7
+ * ordinary answer a tool turns into recovery text, not an exceptional one.
8
+ *
9
+ * Naming: `file.ts` already owns `FilePath*`, so this carries the
10
+ * `PathSandbox` prefix (Critical Rule 9).
11
+ */
12
+ export {};
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Task-checklist primitive (TodoWrite-style) — types.
3
+ *
4
+ * A long-running agent needs a durable, model-visible list of what this run
5
+ * must finish. The checklist lives on the SESSION, outside the message list,
6
+ * so summarization/compaction can rewrite the conversation without touching
7
+ * it, and every tool call returns the whole list so the model re-anchors for
8
+ * free after a compaction.
9
+ *
10
+ * Naming: the scheduler in `task.ts` already owns `Task`, `TaskStatus`,
11
+ * `TaskDefinition`, `TaskStore`, `TaskRunResult` and `TasksFile`, so every
12
+ * type here carries the `Checklist` prefix (Critical Rule 9).
13
+ */
14
+ /** Lifecycle of one checklist item. `closed` means "not done, and here is why". */
15
+ export type ChecklistItemStatus = "pending" | "in_progress" | "done" | "closed";
16
+ export type ChecklistItem = {
17
+ /** "t1", "t2", … — assigned by the engine, never by the model. */
18
+ id: string;
19
+ title: string;
20
+ status: ChecklistItemStatus;
21
+ /** Result note, or the REASON an item was closed unfinished. */
22
+ note?: string;
23
+ createdAt: number;
24
+ updatedAt: number;
25
+ };
26
+ /** Everything one session's checklist holds. Never stored in messages. */
27
+ export type ChecklistState = {
28
+ sessionId: string;
29
+ items: ChecklistItem[];
30
+ updatedAt: number;
31
+ };
32
+ export type ChecklistCreateInput = {
33
+ titles: string[];
34
+ };
35
+ export type ChecklistUpdateInput = {
36
+ id: string;
37
+ status: ChecklistItemStatus;
38
+ note?: string;
39
+ };
40
+ /**
41
+ * Background delegates outstanding for a session. Populated by the async
42
+ * delegation primitive; zero while that primitive is unused.
43
+ */
44
+ export type ChecklistDelegateCounts = {
45
+ pending: number;
46
+ ready: number;
47
+ };
48
+ /** Supplies {@link ChecklistDelegateCounts} to every checklist tool result. */
49
+ export type ChecklistDelegateCountsSource = (sessionId: string) => ChecklistDelegateCounts;
50
+ /**
51
+ * Background commands outstanding for a session. Populated by the
52
+ * background-command primitive; zero while that primitive is unused.
53
+ */
54
+ export type ChecklistCommandCounts = {
55
+ running: number;
56
+ finished: number;
57
+ };
58
+ /** Supplies {@link ChecklistCommandCounts} to every checklist tool result. */
59
+ export type ChecklistCommandCountsSource = (sessionId: string) => ChecklistCommandCounts;
60
+ /**
61
+ * Every `tasks_*` tool returns this — the model re-anchors on the full list
62
+ * on each call, which is what makes the checklist survive compaction with no
63
+ * re-injection machinery.
64
+ */
65
+ export type ChecklistToolResult = {
66
+ items: ChecklistItem[];
67
+ counts: Record<ChecklistItemStatus, number>;
68
+ /** Background delegates not yet collected (0 when delegation is unused). */
69
+ delegatesPending: number;
70
+ delegatesReady: number;
71
+ /**
72
+ * Background commands still running (0 when the command primitive is
73
+ * unused). Carried here for the same reason the delegate counters are: the
74
+ * model learns "the build finished" from any `tasks_list`, with no polling
75
+ * and no change to the core loop.
76
+ */
77
+ commandsRunning: number;
78
+ /** Background commands that have settled and can be read. */
79
+ commandsFinished: number;
80
+ };
81
+ /** Refusal shape shared with the agent tool registrar: recovery text included. */
82
+ export type ChecklistRefusal = {
83
+ isError: true;
84
+ error: string;
85
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Task-checklist primitive (TodoWrite-style) — types.
3
+ *
4
+ * A long-running agent needs a durable, model-visible list of what this run
5
+ * must finish. The checklist lives on the SESSION, outside the message list,
6
+ * so summarization/compaction can rewrite the conversation without touching
7
+ * it, and every tool call returns the whole list so the model re-anchors for
8
+ * free after a compaction.
9
+ *
10
+ * Naming: the scheduler in `task.ts` already owns `Task`, `TaskStatus`,
11
+ * `TaskDefinition`, `TaskStore`, `TaskRunResult` and `TasksFile`, so every
12
+ * type here carries the `Checklist` prefix (Critical Rule 9).
13
+ */
14
+ export {};