@theokit/sdk-tools 0.1.0 → 0.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.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CustomTool } from '@theokit/sdk';
1
+ import { CustomTool, ConfigurationError } from '@theokit/sdk';
2
2
 
3
3
  /**
4
4
  * `apply_patch` — built-in tool for coding agents.
@@ -18,6 +18,60 @@ interface CreateApplyPatchToolOptions {
18
18
  }
19
19
  declare function createApplyPatchTool(opts: CreateApplyPatchToolOptions): CustomTool;
20
20
 
21
+ /**
22
+ * Options for {@link createSessionArtifactStore}.
23
+ *
24
+ * @public
25
+ */
26
+ interface SessionArtifactStoreOptions {
27
+ /** Directory holding one file per artifact (`<dir>/<idStrategy(id)><extension>`). */
28
+ dir: string;
29
+ /**
30
+ * Map an opaque artifact id to a filesystem-safe filename stem.
31
+ * Default: `safeFilenameForId` (accepts ANY id; deterministically hashes
32
+ * non-conforming input). The result is additionally passed through
33
+ * `safePathJoin`, so a traversal id can never escape `dir`.
34
+ *
35
+ * NOTE — the default `safeFilenameForId` is CASE-FOLDING: ids differing only
36
+ * in case (`"Run-1"` vs `"run-1"`) map to the SAME file. If your ids are
37
+ * case-sensitive (e.g. base64), supply a case-preserving `idStrategy`.
38
+ */
39
+ idStrategy?: (id: string) => string;
40
+ /** File extension (with leading dot). Default `".md"`. */
41
+ extension?: string;
42
+ }
43
+ /**
44
+ * A generic, id-keyed, atomic artifact store. Generalizes the per-run
45
+ * session-summary writer pattern: persist an opaque text artifact under a
46
+ * stable id, read it back, and enumerate what's stored.
47
+ *
48
+ * @public
49
+ */
50
+ interface SessionArtifactStore {
51
+ /**
52
+ * Write (overwrite) the artifact atomically; returns the resolved path.
53
+ * Content is persisted byte-for-byte. The id is mapped via `idStrategy`
54
+ * (default case-folding — see {@link SessionArtifactStoreOptions.idStrategy}).
55
+ */
56
+ write(id: string, content: string): Promise<string>;
57
+ /** Read the artifact, or `undefined` if absent/unreadable (never throws). */
58
+ read(id: string): Promise<string | undefined>;
59
+ /** Whether an artifact exists for `id` (never throws). */
60
+ has(id: string): Promise<boolean>;
61
+ /** The filename stems of all stored artifacts (never throws; `[]` if dir absent). */
62
+ list(): Promise<string[]>;
63
+ /** The resolved, traversal-safe path for `id`. */
64
+ path(id: string): string;
65
+ }
66
+ /**
67
+ * Create a generic artifact store rooted at `dir`. Composes the shipped
68
+ * `safeFilenameForId`/`safePathJoin` path guard + the atomic `replaceFileAtomic`
69
+ * writer — zero new dependencies. Reads never throw; writes fail loud.
70
+ *
71
+ * @public
72
+ */
73
+ declare function createSessionArtifactStore(options: SessionArtifactStoreOptions): SessionArtifactStore;
74
+
21
75
  /**
22
76
  * `edit_file` — built-in tool for coding agents.
23
77
  *
@@ -88,8 +142,8 @@ declare function createGitDiffTool(opts: CreateGitDiffToolOptions): CustomTool;
88
142
  * .git, and dist by default. Returns relative paths.
89
143
  *
90
144
  * Return shape (always a JSON string):
91
- * - `{ ok: true, files: string[] }`
92
- * - `{ ok: false, error: 'path_traversal' | 'no_matches' }`
145
+ * - `{ ok: true, files: string[], count }` (an empty match is `ok: true` with `files: []`)
146
+ * - `{ ok: false, error: 'path_traversal' }`
93
147
  */
94
148
 
95
149
  interface CreateGlobToolOptions {
@@ -98,6 +152,205 @@ interface CreateGlobToolOptions {
98
152
  }
99
153
  declare function createGlobTool(opts: CreateGlobToolOptions): CustomTool;
100
154
 
155
+ /**
156
+ * Composable command-permission policy layer (M3-6).
157
+ *
158
+ * A `CommandPolicy` is a pure predicate returning a deny REASON (or `null` to
159
+ * allow). `denyCatastrophicCommands()` COMPOSES the M3-2 `catastrophicShellReason`
160
+ * guardrail (it does not duplicate the deny-list). `commandDenialReason` combines
161
+ * a policy array with deny-wins semantics (the first policy returning a reason
162
+ * denies); an empty array denies nothing. `isCommandAllowed` is the boolean view.
163
+ *
164
+ * Framework-agnostic: a consumer wires it at their permission layer — e.g. inside
165
+ * an ACP `pre_tool_call` hook — `@theokit/agents` is not required. Inherits the
166
+ * M3-2 honesty: a heuristic gate, not a sandbox. Design: blueprint m3-command-policy.
167
+ */
168
+ /**
169
+ * A pure command-permission predicate: returns a non-empty deny reason, or `null`
170
+ * to allow. NOTE: return `null` to allow — NOT `""`. An empty string is treated
171
+ * as a deny with a blank reason (`"" !== null`), which is almost never intended.
172
+ */
173
+ type CommandPolicy = (command: string) => string | null;
174
+ /** A policy that denies catastrophic commands by composing the M3-2 guardrail. */
175
+ declare function denyCatastrophicCommands(): CommandPolicy;
176
+ /**
177
+ * The first deny reason across `policies` (deny-wins), or `null` if every policy
178
+ * allows. An empty `policies` array denies nothing (returns `null`).
179
+ */
180
+ declare function commandDenialReason(command: string, policies: CommandPolicy[]): string | null;
181
+ /** `true` when no policy denies `command` (an empty policy array allows everything). */
182
+ declare function isCommandAllowed(command: string, policies: CommandPolicy[]): boolean;
183
+
184
+ /**
185
+ * SSRF guard for network tools (M3-1).
186
+ *
187
+ * `isBlockedIp` is a pure block-list of the canonical private/loopback/link-local/
188
+ * CGNAT/metadata/reserved ranges (IPv4 + IPv6, with IPv4-mapped unwrap).
189
+ * `resolveAndScreen` resolves ALL of a host's addresses and rejects if any is
190
+ * blocked. `screenedFetch` fetches with `redirect:"manual"` and re-screens every
191
+ * hop. `lookup`/`fetchImpl` are injectable so the DNS + redirect paths are
192
+ * deterministically testable without real network access.
193
+ *
194
+ * Design: blueprint m3-ssrf-guard ADRs D1-D6. Node builtins only (zero new deps).
195
+ */
196
+
197
+ /** Thrown when a host/redirect resolves to a blocked (private/reserved) address. */
198
+ declare class SsrfBlockedError extends ConfigurationError {
199
+ readonly name = "SsrfBlockedError";
200
+ constructor(host: string, detail?: string);
201
+ }
202
+ /**
203
+ * True if `ip` is a blocked address (private/loopback/link-local/CGNAT/metadata/
204
+ * reserved). A non-IP literal returns `true` (fail closed — callers resolve names
205
+ * to IPs first via {@link resolveAndScreen}).
206
+ */
207
+ declare function isBlockedIp(ip: string): boolean;
208
+ type LookupFn = (host: string, opts: {
209
+ all: true;
210
+ }) => Promise<Array<{
211
+ address: string;
212
+ }>>;
213
+ /** Options for {@link resolveAndScreen}. */
214
+ interface ResolveAndScreenOptions {
215
+ /** DNS resolver (injectable for tests); defaults to `node:dns/promises` lookup. */
216
+ lookup?: LookupFn;
217
+ }
218
+ /**
219
+ * Resolve `host` to ALL its addresses and screen each. Throws {@link SsrfBlockedError}
220
+ * if any resolved address is blocked (or if `host` is a blocked IP literal, or if
221
+ * resolution yields no address). Returns the resolved IPs otherwise.
222
+ */
223
+ declare function resolveAndScreen(rawHost: string, options?: ResolveAndScreenOptions): Promise<string[]>;
224
+ type FetchFn = (url: string, init?: RequestInit) => Promise<Response>;
225
+ /** Options for {@link screenedFetch}. */
226
+ interface ScreenedFetchOptions {
227
+ /** Fetch implementation (injectable for tests); defaults to global `fetch`. */
228
+ fetchImpl?: FetchFn;
229
+ /** DNS resolver (injectable for tests). */
230
+ lookup?: LookupFn;
231
+ /** Max redirect hops to follow (default 5). */
232
+ maxRedirects?: number;
233
+ /** Skip SSRF screening entirely (opt-out for local-dev tools). Default false. */
234
+ allowPrivateHosts?: boolean;
235
+ /** Abort signal forwarded to fetch. */
236
+ signal?: AbortSignal;
237
+ }
238
+ /**
239
+ * Fetch `url` with SSRF screening: screens the host (unless `allowPrivateHosts`),
240
+ * sets `redirect:"manual"`, and re-screens every redirect hop (rejecting a hop to a
241
+ * blocked host or a non-http(s) target). Throws {@link SsrfBlockedError} on a block
242
+ * or on exceeding `maxRedirects`.
243
+ */
244
+ declare function screenedFetch(url: string, options?: ScreenedFetchOptions): Promise<Response>;
245
+
246
+ /**
247
+ * Repo-map / env-context builders for orienting an LLM coding agent (M3-3).
248
+ *
249
+ * `buildEnvContext(cwd)` renders a short `<env>` block (cwd, platform, node,
250
+ * is-git, date, project docs, manifests). `buildRepoMap(cwd, opts)` renders a
251
+ * char-bounded, depth-limited directory tree. Both are node:fs-only and NEVER
252
+ * throw — a missing/unreadable path yields a best-effort partial string or an
253
+ * `(unavailable)` marker (distinct from the M3-1/M3-2 guards, which throw).
254
+ *
255
+ * Design: blueprint m3-repo-map. Zero new dependencies. A best-effort
256
+ * orientation aid, not a complete or secure listing (bounded + skips on error).
257
+ */
258
+ interface RepoMapOptions {
259
+ /** Max characters of tree output before truncation. Default 8000. */
260
+ budget?: number;
261
+ /** Directory/file names to skip (merged with the built-in ignore set). */
262
+ ignore?: string[];
263
+ /** Max directory depth to descend. Default 4. */
264
+ maxDepth?: number;
265
+ }
266
+ /** Render a portable `<env>` orientation block. Never throws. */
267
+ declare function buildEnvContext(cwd: string): string;
268
+ /** Render a char-bounded, depth-limited directory tree. Never throws. */
269
+ declare function buildRepoMap(cwd: string, opts?: RepoMapOptions): string;
270
+
271
+ /**
272
+ * Catastrophic-command guardrail for `shell_exec` (M3-2).
273
+ *
274
+ * `catastrophicShellReason` is a pure, segment-aware deny-list: it splits a
275
+ * command on top-level connectors (`;`, `&&`, `||`, pipe), strips `sudo`/`env`
276
+ * prefixes, and matches at COMMAND POSITION (the executable, not an arbitrary
277
+ * substring) so a mention like `echo "rm -rf /"` is not over-blocked. It returns
278
+ * a human reason for the first catastrophic segment, else `null`.
279
+ *
280
+ * This is a heuristic GUARDRAIL, NOT a sandbox: it is bypassable by obfuscation
281
+ * (eval/base64) and is best-effort. POSIX `/bin/sh` only; Windows PowerShell is
282
+ * out of scope. Design: blueprint m3-catastrophic-shell. Zero new deps.
283
+ */
284
+
285
+ /** Thrown / reported when a command matches the catastrophic deny-list. */
286
+ declare class CatastrophicCommandError extends ConfigurationError {
287
+ readonly name = "CatastrophicCommandError";
288
+ constructor(reason: string);
289
+ }
290
+ /**
291
+ * Returns a human reason if `cmd` contains a catastrophic command (in any
292
+ * segment, across chains/sudo/pipes), else `null`.
293
+ */
294
+ declare function catastrophicShellReason(cmd: string): string | null;
295
+
296
+ /**
297
+ * ACI (Agent-Computer Interface) helpers for tools (M3-5).
298
+ *
299
+ * `withDescription(tool, description)` immutably overrides a tool's LLM-facing
300
+ * description (the wording that drives tool-selection accuracy) — returning a
301
+ * NEW `CustomTool` and leaving the original untouched. `renderToolList(tools)`
302
+ * renders a `<tools>` block FROM THE SAME `CustomTool[]` the agent runs, so the
303
+ * rendered list cannot drift from the real tools (single source of truth).
304
+ *
305
+ * Both are pure, zero-dependency, and never throw. The `<tools>` block is a
306
+ * system-prompt orientation aid — NOT the provider tool-call schema (that stays
307
+ * each tool's `inputSchema`). Design: blueprint m3-aci-tools.
308
+ */
309
+
310
+ /**
311
+ * Return a new `CustomTool` with `description` replaced. Preserves
312
+ * name/inputSchema/handler; does NOT mutate the original tool.
313
+ */
314
+ declare function withDescription(tool: CustomTool, description: string): CustomTool;
315
+ /**
316
+ * Render a `<tools>` block (name + description per tool) from the agent's actual
317
+ * `CustomTool[]` — single source of truth, so an overridden/added/removed tool
318
+ * is reflected automatically. An empty array yields `<tools></tools>`. Never throws.
319
+ */
320
+ declare function renderToolList(tools: CustomTool[]): string;
321
+
322
+ /**
323
+ * Rich-error guidance for tool failures (M3-4).
324
+ *
325
+ * `withToolResultGuidance(tool, guidance)` wraps a `CustomTool` so a failing
326
+ * `{ ok: false, error }` JSON result gains an LLM-actionable `guidance` string
327
+ * telling the model how to self-correct. The injection is ADDITIVE (only on
328
+ * `ok:false`), IDEMPOTENT (never overwrites an existing `guidance`), and
329
+ * NEVER-THROW (a non-JSON / non-object / `ok:true` / unknown-code result is
330
+ * returned unchanged). Composes over the existing built-in tools (and custom
331
+ * tools) — no factory edits required.
332
+ *
333
+ * Design: blueprint m3-rich-errors. Zero new dependencies (JSON transform).
334
+ */
335
+
336
+ /** Maps a tool error code to a short, LLM-actionable self-correction hint. */
337
+ type ToolGuidanceMap = Record<string, string>;
338
+ /** Curated hints for the common cross-tool error codes. Consumers may extend. */
339
+ declare const DEFAULT_TOOL_GUIDANCE: ToolGuidanceMap;
340
+ /**
341
+ * Pure: parse a tool handler's JSON output and ADD a `guidance` hint when the
342
+ * result is an `{ ok: false, error }` object whose code has a hint and that does
343
+ * not already carry guidance. Any other input is returned UNCHANGED (never throws).
344
+ */
345
+ declare function injectGuidance(handlerOutput: string, guidance: ToolGuidanceMap): string;
346
+ /**
347
+ * Wrap a `CustomTool` so its failed results gain a `guidance` hint from `guidance`.
348
+ * Preserves name/description/inputSchema; only the handler output is augmented.
349
+ */
350
+ declare function withToolResultGuidance(tool: CustomTool, guidance: ToolGuidanceMap): CustomTool;
351
+ /** `withToolResultGuidance` pre-bound to {@link DEFAULT_TOOL_GUIDANCE}. */
352
+ declare function withDefaultGuidance(tool: CustomTool): CustomTool;
353
+
101
354
  /**
102
355
  * `list_dir` — built-in tool for coding agents.
103
356
  *
@@ -133,7 +386,11 @@ declare function createListDirTool(opts: CreateListDirToolOptions): CustomTool;
133
386
  * Return shape (always a JSON string):
134
387
  * - `{ ok: true, mode: string, message: string }`
135
388
  * - `{ ok: false, error: "invalid_action" }`
389
+ *
390
+ * Opt-in persistence (M4-4): `createPlanModeTool({ artifactStore })` returns a
391
+ * variant whose async handler persists the submitted `plan` on `exit`.
136
392
  */
393
+
137
394
  type Mode = "normal" | "plan";
138
395
  interface PlanModeTool {
139
396
  name: string;
@@ -145,7 +402,36 @@ interface PlanModeTool {
145
402
  /** Expose current mode for testing. */
146
403
  currentMode: () => Mode;
147
404
  }
405
+ /**
406
+ * Plan-mode tool with opt-in artifact persistence (M4-4). Same surface as
407
+ * {@link PlanModeTool} but the handler is ASYNC (it may write to the store) and
408
+ * accepts an optional `plan` to persist on `exit`.
409
+ *
410
+ * @public
411
+ */
412
+ interface PlanModeToolWithStore {
413
+ name: string;
414
+ description: string;
415
+ inputSchema: unknown;
416
+ handler: (input: {
417
+ action: string;
418
+ plan?: string;
419
+ }) => Promise<string>;
420
+ currentMode: () => Mode;
421
+ }
422
+ /**
423
+ * Options for the persistence-enabled {@link createPlanModeTool} overload.
424
+ *
425
+ * @public
426
+ */
427
+ interface PlanModeToolOptions {
428
+ /** Store the submitted `plan` is persisted to on `exit`. */
429
+ artifactStore: SessionArtifactStore;
430
+ /** Artifact id under which the plan is stored. Default `"plan"`. */
431
+ artifactId?: string;
432
+ }
148
433
  declare function createPlanModeTool(): PlanModeTool;
434
+ declare function createPlanModeTool(options: PlanModeToolOptions): PlanModeToolWithStore;
149
435
 
150
436
  /**
151
437
  * `question` — interactive tool that asks the user a question and waits for a response.
@@ -289,6 +575,13 @@ interface CreateShellToolOptions {
289
575
  projectRoot: string;
290
576
  /** Default timeout in ms. Capped at 300s. */
291
577
  defaultTimeoutMs?: number;
578
+ /**
579
+ * Opt out of the catastrophic-command guardrail. Default `false` (the
580
+ * guardrail screens every command before spawn). Set `true` only when the
581
+ * agent legitimately needs destructive power flows — it is a heuristic
582
+ * guardrail, not a sandbox.
583
+ */
584
+ allowCatastrophic?: boolean;
292
585
  }
293
586
  declare function createShellTool(opts: CreateShellToolOptions): CustomTool;
294
587
 
@@ -339,6 +632,27 @@ type TodoInput = {
339
632
  };
340
633
  declare function createTodolistTool(): TodolistTool;
341
634
 
635
+ /**
636
+ * A flat plan-render node — the stable shape a UI/plan layer consumes. Mirrors
637
+ * the `TodoItem` status union; `label` is the item title.
638
+ *
639
+ * @public
640
+ */
641
+ interface PlanNode {
642
+ id: string;
643
+ label: string;
644
+ status: "pending" | "in_progress" | "done";
645
+ }
646
+ /**
647
+ * Convert structured todo items (from a `todolist` tool result's `items`, M4-5)
648
+ * into versioned `PlanNode`s for rendering. Pure: projects EXACTLY
649
+ * `{ id, label, status }` (timestamps are intentionally dropped), preserving
650
+ * input order. Replaces consumer-side hand-rolled mappers.
651
+ *
652
+ * @public
653
+ */
654
+ declare function todoItemsToPlanNodes(items: readonly TodoItem[]): PlanNode[];
655
+
342
656
  /**
343
657
  * `truncateOutput` — utility for truncating large tool output.
344
658
  *
@@ -380,6 +694,12 @@ declare function truncateOutput(output: string, opts?: TruncationOptions): Trunc
380
694
  interface CreateWebFetchToolOptions {
381
695
  /** Default timeout in ms. */
382
696
  defaultTimeoutMs?: number;
697
+ /**
698
+ * Opt out of the SSRF guard (default `false`). When `true`, requests to
699
+ * private/loopback/link-local/metadata addresses are NOT blocked — use only for
700
+ * trusted local-dev tooling.
701
+ */
702
+ allowPrivateHosts?: boolean;
383
703
  }
384
704
  declare function createWebFetchTool(opts?: CreateWebFetchToolOptions): CustomTool;
385
705
 
@@ -408,6 +728,33 @@ interface CreateWebSearchToolOptions {
408
728
  }
409
729
  declare function createWebSearchTool(opts: CreateWebSearchToolOptions): CustomTool;
410
730
 
731
+ /**
732
+ * Brave Search adapter for `createWebSearchTool` (M3-7).
733
+ *
734
+ * `createBraveWebSearchAdapter()` returns a `WebSearchCallback` that queries the
735
+ * Brave Search API using an env-driven key (`BRAVE_API_KEY`). It plugs into the
736
+ * provider-agnostic `createWebSearchTool` via its callback seam — the tool is NOT
737
+ * modified. The `fetch` impl is injectable (default `globalThis.fetch`) so the
738
+ * adapter is offline-testable; a plain fetch (not `screenedFetch`) is used because
739
+ * the endpoint host is fixed (no SSRF surface) and `screenedFetch` cannot carry
740
+ * the required auth header. Zero new dependencies. Design: blueprint m3-websearch-adapter.
741
+ */
742
+
743
+ type FetchLike = (url: string, init?: RequestInit) => Promise<Response>;
744
+ interface CreateBraveWebSearchAdapterOptions {
745
+ /** Brave API key. Defaults to `process.env.BRAVE_API_KEY`. */
746
+ apiKey?: string;
747
+ /** Injectable fetch (default `globalThis.fetch`) — set in tests for offline runs. */
748
+ fetchImpl?: FetchLike;
749
+ /** Override the Brave endpoint (self-host / test). */
750
+ endpoint?: string;
751
+ }
752
+ /**
753
+ * Build a `WebSearchCallback` backed by the Brave Search API. Throws a typed
754
+ * `ConfigurationError` ("no_api_key") at creation when no key is available.
755
+ */
756
+ declare function createBraveWebSearchAdapter(opts?: CreateBraveWebSearchAdapterOptions): WebSearchCallback;
757
+
411
758
  /**
412
759
  * `write_file` — built-in tool for coding agents.
413
760
  *
@@ -427,4 +774,4 @@ interface CreateWriteFileToolOptions {
427
774
  }
428
775
  declare function createWriteFileTool(opts: CreateWriteFileToolOptions): CustomTool;
429
776
 
430
- export { type CreateApplyPatchToolOptions, type CreateEditFileToolOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, type PlanModeTool, type QuestionTool, type QuestionToolOptions, type TodoItem, type TodolistTool, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, createApplyPatchTool, createEditFileTool, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, formatCode, formatDiff, formatError, formatFileList, truncateOutput };
777
+ export { CatastrophicCommandError, type CommandPolicy, type CreateApplyPatchToolOptions, type CreateBraveWebSearchAdapterOptions, type CreateEditFileToolOptions, type CreateGitDiffToolOptions, type CreateGlobToolOptions, type CreateListDirToolOptions, type CreateReadFileToolOptions, type CreateRunVitestToolOptions, type CreateSearchTextToolOptions, type CreateShellToolOptions, type CreateWebFetchToolOptions, type CreateWebSearchToolOptions, type CreateWriteFileToolOptions, DEFAULT_TOOL_GUIDANCE, type PlanModeTool, type PlanModeToolOptions, type PlanModeToolWithStore, type PlanNode, type QuestionTool, type QuestionToolOptions, type RepoMapOptions, type ResolveAndScreenOptions, type ScreenedFetchOptions, type SessionArtifactStore, type SessionArtifactStoreOptions, SsrfBlockedError, type TodoItem, type TodolistTool, type ToolGuidanceMap, type TruncationOptions, type TruncationResult, type VitestSummary, type WebSearchCallback, type WebSearchResult, buildEnvContext, buildRepoMap, catastrophicShellReason, commandDenialReason, createApplyPatchTool, createBraveWebSearchAdapter, createEditFileTool, createGitDiffTool, createGlobTool, createListDirTool, createPlanModeTool, createQuestionTool, createReadFileTool, createRunVitestTool, createSearchTextTool, createSessionArtifactStore, createShellTool, createTodolistTool, createWebFetchTool, createWebSearchTool, createWriteFileTool, denyCatastrophicCommands, formatCode, formatDiff, formatError, formatFileList, injectGuidance, isBlockedIp, isCommandAllowed, renderToolList, resolveAndScreen, screenedFetch, todoItemsToPlanNodes, truncateOutput, withDefaultGuidance, withDescription, withToolResultGuidance };