@ikarmic/forge-core 5.1.1 → 5.3.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 (81) hide show
  1. package/dist/agent/agent.js +208 -57
  2. package/dist/agent/enhance-prompt.js +2 -1
  3. package/dist/agent/goal.d.ts +5 -8
  4. package/dist/agent/prompts.d.ts +15 -0
  5. package/dist/agent/prompts.js +34 -0
  6. package/dist/agent/race-abort.d.ts +8 -0
  7. package/dist/agent/race-abort.js +24 -0
  8. package/dist/agent/retry.d.ts +50 -0
  9. package/dist/agent/retry.js +192 -0
  10. package/dist/agent/shell-command.d.ts +23 -0
  11. package/dist/agent/shell-command.js +93 -0
  12. package/dist/agent/stack-facts.d.ts +23 -0
  13. package/dist/agent/stack-facts.js +150 -0
  14. package/dist/catalog/models-dev-snapshot.d.ts +1 -0
  15. package/dist/catalog/models-dev-snapshot.js +3 -0
  16. package/dist/catalog/models-dev.d.ts +35 -0
  17. package/dist/catalog/models-dev.js +143 -0
  18. package/dist/code-index/parser.js +48 -3
  19. package/dist/context/compaction.js +8 -2
  20. package/dist/git/auto-commit.d.ts +4 -2
  21. package/dist/git/auto-commit.js +16 -5
  22. package/dist/github/github-tools.d.ts +2 -18
  23. package/dist/index.d.ts +11 -3
  24. package/dist/index.js +9 -2
  25. package/dist/journey/answers-block.js +14 -1
  26. package/dist/journey/offer.js +2 -1
  27. package/dist/mcp/json-schema-to-zod.js +12 -1
  28. package/dist/memory/session-digest.js +2 -1
  29. package/dist/orchestrator/index.d.ts +1 -1
  30. package/dist/orchestrator/index.js +1 -1
  31. package/dist/orchestrator/orchestrator.d.ts +45 -6
  32. package/dist/orchestrator/orchestrator.js +62 -12
  33. package/dist/orchestrator/router.d.ts +1 -1
  34. package/dist/orchestrator/router.js +4 -1
  35. package/dist/orchestrator/specialists.d.ts +6 -1
  36. package/dist/orchestrator/specialists.js +165 -68
  37. package/dist/orchestrator/types.d.ts +1 -1
  38. package/dist/policy/policy.d.ts +6 -59
  39. package/dist/pricing.d.ts +2 -0
  40. package/dist/pricing.js +47 -16
  41. package/dist/structured/schema.js +9 -12
  42. package/dist/tools/apply-patch.d.ts +1 -5
  43. package/dist/tools/ask-user.d.ts +2 -10
  44. package/dist/tools/ask-user.js +12 -4
  45. package/dist/tools/browser-tools.d.ts +15 -31
  46. package/dist/tools/codebase-search.d.ts +1 -7
  47. package/dist/tools/command-sandbox.d.ts +24 -0
  48. package/dist/tools/command-sandbox.js +73 -0
  49. package/dist/tools/dependency-audit.d.ts +30 -0
  50. package/dist/tools/dependency-audit.js +197 -0
  51. package/dist/tools/edit-file.d.ts +9 -15
  52. package/dist/tools/edit-file.js +64 -16
  53. package/dist/tools/fetch-url.d.ts +1 -18
  54. package/dist/tools/find-references.d.ts +1 -5
  55. package/dist/tools/find-symbol.d.ts +10 -8
  56. package/dist/tools/git-diff.d.ts +13 -0
  57. package/dist/tools/git-diff.js +85 -0
  58. package/dist/tools/index.d.ts +3 -1
  59. package/dist/tools/index.js +5 -1
  60. package/dist/tools/list-files.d.ts +1 -19
  61. package/dist/tools/list-symbols.d.ts +1 -5
  62. package/dist/tools/memory.d.ts +23 -43
  63. package/dist/tools/notebook.d.ts +11 -17
  64. package/dist/tools/read-file.d.ts +1 -11
  65. package/dist/tools/read-image.d.ts +1 -12
  66. package/dist/tools/read-only.d.ts +1 -1
  67. package/dist/tools/read-only.js +2 -0
  68. package/dist/tools/run-command.d.ts +1 -17
  69. package/dist/tools/run-command.js +12 -2
  70. package/dist/tools/search-files.d.ts +1 -17
  71. package/dist/tools/search-files.js +8 -49
  72. package/dist/tools/search-worker.d.ts +23 -0
  73. package/dist/tools/search-worker.js +77 -0
  74. package/dist/tools/sub-agent-wait.d.ts +2 -8
  75. package/dist/tools/sub-agent.d.ts +2 -70
  76. package/dist/tools/sub-agent.js +1 -0
  77. package/dist/tools/todo.d.ts +8 -20
  78. package/dist/tools/web-search.d.ts +1 -7
  79. package/dist/tools/write-file.d.ts +1 -7
  80. package/dist/types.d.ts +60 -1
  81. package/package.json +3 -3
@@ -0,0 +1,77 @@
1
+ /**
2
+ * search_files' matching, run in a worker thread with a time limit. JavaScript cannot interrupt a running regex, so a
3
+ * pattern that backtracks badly on the main thread froze the process (in VS Code, the extension host): in a worker it
4
+ * is terminated after `timeoutMs`. The worker source is a plain string, not a function's text, so a bundler cannot
5
+ * rename or wrap anything in it; the same string runs in-process when a worker cannot start.
6
+ */
7
+ import { readFileSync } from 'node:fs';
8
+ import { Worker } from 'node:worker_threads';
9
+ export const DEFAULT_SEARCH_TIMEOUT_MS = 20_000;
10
+ /** Body of `function (job, readFile)`: read each file, skip binaries, match line by line, keep context. */
11
+ const MATCH_BODY = String.raw `
12
+ var regex = new RegExp(job.source, job.flags);
13
+ var matches = [];
14
+ var truncated = false;
15
+ var filesScanned = 0;
16
+ function truncateByLines(text, maxLines) {
17
+ var lines = text.split(/\r?\n/);
18
+ if (lines.length <= maxLines) return text;
19
+ var dropped = lines.length - maxLines;
20
+ return lines.slice(0, maxLines).join('\n') + '\n\n... (' + dropped + ' more line' + (dropped === 1 ? '' : 's') + ' truncated; re-read with a smaller offset to see more)';
21
+ }
22
+ for (var f = 0; f < job.files.length; f++) {
23
+ if (matches.length >= job.maxResults) { truncated = true; break; }
24
+ var file = job.files[f];
25
+ filesScanned++;
26
+ var buf;
27
+ try { buf = readFile(file.abs); } catch (e) { continue; }
28
+ if (buf.includes(0)) continue;
29
+ var lines = buf.toString('utf8').split(/\r?\n/);
30
+ for (var i = 0; i < lines.length; i++) {
31
+ if (matches.length >= job.maxResults) { truncated = true; break; }
32
+ regex.lastIndex = 0;
33
+ if (regex.test(lines[i])) {
34
+ var start = Math.max(0, i - job.contextLines);
35
+ var end = Math.min(lines.length - 1, i + job.contextLines);
36
+ var block = [];
37
+ for (var j = start; j <= end; j++) block.push((j === i ? '>' : ' ') + ' ' + String(j + 1).padStart(6) + '\t' + lines[j]);
38
+ matches.push({ path: file.rel, line: i + 1, text: truncateByLines(block.join('\n'), 10) });
39
+ }
40
+ }
41
+ }
42
+ return { matches: matches, truncated: truncated, filesScanned: filesScanned };
43
+ `;
44
+ const WORKER_SOURCE = `
45
+ const { parentPort, workerData } = require('node:worker_threads');
46
+ const fs = require('node:fs');
47
+ const match = new Function('job', 'readFile', ${JSON.stringify(MATCH_BODY)});
48
+ parentPort.postMessage(match(workerData, (p) => fs.readFileSync(p)));
49
+ `;
50
+ function matchInProcess(job) {
51
+ return new Function('job', 'readFile', MATCH_BODY)(job, (p) => readFileSync(p));
52
+ }
53
+ /** Match `job` in a worker; throws when it runs longer than `timeoutMs`. Falls back to in-process if no worker starts. */
54
+ export function matchInWorker(job, opts) {
55
+ let worker;
56
+ try {
57
+ worker = (opts.startWorker ?? ((source, data) => new Worker(source, { eval: true, workerData: data })))(WORKER_SOURCE, job);
58
+ }
59
+ catch {
60
+ return Promise.resolve(matchInProcess(job));
61
+ }
62
+ return new Promise((resolve, reject) => {
63
+ const timer = setTimeout(() => {
64
+ void worker.terminate();
65
+ reject(new Error(`The search pattern took longer than ${Math.round(opts.timeoutMs / 1000)} s and was stopped. Simplify it (avoid repeated groups that can match the same text in several ways) or search fewer files.`));
66
+ }, opts.timeoutMs);
67
+ worker.once('message', (result) => {
68
+ clearTimeout(timer);
69
+ void worker.terminate();
70
+ resolve(result);
71
+ });
72
+ worker.once('error', (err) => {
73
+ clearTimeout(timer);
74
+ reject(err);
75
+ });
76
+ });
77
+ }
@@ -1,15 +1,9 @@
1
1
  import { z } from 'zod';
2
2
  import type { ToolDefinition } from '../types.js';
3
3
  declare const params: z.ZodObject<{
4
- ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
4
+ ids: z.ZodOptional<z.ZodArray<z.ZodString>>;
5
5
  timeout_seconds: z.ZodOptional<z.ZodNumber>;
6
- }, "strip", z.ZodTypeAny, {
7
- ids?: string[] | undefined;
8
- timeout_seconds?: number | undefined;
9
- }, {
10
- ids?: string[] | undefined;
11
- timeout_seconds?: number | undefined;
12
- }>;
6
+ }, z.core.$strip>;
13
7
  export interface SubAgentWaitResult {
14
8
  agents: Array<{
15
9
  id: string;
@@ -2,84 +2,16 @@ import { z } from 'zod';
2
2
  import { type AgentDef } from '../agents/agent-files.js';
3
3
  import type { AgentConfig, ModelConfig, ToolContext, ToolDefinition } from '../types.js';
4
4
  declare const params: z.ZodObject<{
5
- /** The task for the sub-agent to perform. Free-form text. */
6
5
  task: z.ZodString;
7
- /** Name of an agent file (`.forge/agents/<name>.md`) to run as: its prompt, tools, model and step cap. */
8
6
  agent: z.ZodOptional<z.ZodString>;
9
- /** Hard cap on iterations for the sub-agent. Default 10. */
10
7
  max_iterations: z.ZodOptional<z.ZodNumber>;
11
- /**
12
- * Run the sub-agent without approval prompts (autonomous). Defaults to
13
- * `false` even when the parent is in `--auto` mode: the sub-agent is
14
- * expected to be focused and short-lived, so the explicit opt-in is
15
- * deliberate to avoid runaway destructive work.
16
- */
17
8
  auto: z.ZodOptional<z.ZodBoolean>;
18
- /**
19
- * Working directory for the sub-agent. Defaults to the parent's cwd.
20
- * Useful when the sub-task should operate on a subdirectory without
21
- * dragging the parent through the navigation.
22
- */
23
9
  cwd: z.ZodOptional<z.ZodString>;
24
- /**
25
- * Run the sub-agent in an isolated git worktree. The worktree is
26
- * created at `<repoRoot>/.forge/worktrees/<label>/`, the child runs
27
- * there, and the worktree is removed on completion (success or
28
- * error). Falls back to plain `cwd` mode (with a stderr warning)
29
- * when the parent's cwd is not inside a git repo.
30
- *
31
- * Pair this with `orchestrator run` parallel dispatch (v2.3) to
32
- * safely run multiple specialists concurrently without them
33
- * clobbering each other's files.
34
- */
35
10
  use_worktree: z.ZodOptional<z.ZodBoolean>;
36
- /**
37
- * Human-readable label for the worktree (used in the branch name and
38
- * directory). Defaults to a random short hash. Ignored when
39
- * `use_worktree` is false.
40
- */
41
11
  worktree_label: z.ZodOptional<z.ZodString>;
42
- /**
43
- * v2.14: when `use_worktree: true`, also delete the auto-created
44
- * `forge/<label>-<short-sha>` branch once the worktree's working
45
- * tree is gone. Default `true` because sub-agents are short-lived
46
- * and orphan branches are pure clutter.
47
- *
48
- * Set to `false` when you want to inspect the diff afterwards (e.g.
49
- * `git diff main..forge/<label>-<sha>`) or hand the branch to a
50
- * human reviewer.
51
- *
52
- * The branch is only deleted when no other worktree currently
53
- * references it, so two Forge sessions working on the same branch
54
- * won't collide.
55
- */
56
12
  cleanup_branch: z.ZodOptional<z.ZodBoolean>;
57
- /**
58
- * Start the child and return at once. The child keeps working while the parent continues; collect its answer with
59
- * `sub_agent_wait`. Only where the surface can show background runs; elsewhere the child runs to completion as usual.
60
- */
61
13
  background: z.ZodOptional<z.ZodBoolean>;
62
- }, "strip", z.ZodTypeAny, {
63
- task: string;
64
- agent?: string | undefined;
65
- cwd?: string | undefined;
66
- auto?: boolean | undefined;
67
- background?: boolean | undefined;
68
- max_iterations?: number | undefined;
69
- use_worktree?: boolean | undefined;
70
- worktree_label?: string | undefined;
71
- cleanup_branch?: boolean | undefined;
72
- }, {
73
- task: string;
74
- agent?: string | undefined;
75
- cwd?: string | undefined;
76
- auto?: boolean | undefined;
77
- background?: boolean | undefined;
78
- max_iterations?: number | undefined;
79
- use_worktree?: boolean | undefined;
80
- worktree_label?: string | undefined;
81
- cleanup_branch?: boolean | undefined;
82
- }>;
14
+ }, z.core.$strip>;
83
15
  /** What `sub_agent { background: true }` returns instead of a result. */
84
16
  export interface SubAgentStarted {
85
17
  started: true;
@@ -145,7 +77,7 @@ export declare function childAgentConfig(setup: {
145
77
  model: ModelConfig;
146
78
  maxIterations: number;
147
79
  systemPrompt?: string;
148
- }, ctx: Pick<ToolContext, 'autoApproveTools' | 'permissionRules' | 'toolSandbox' | 'askBudget'>, cwd: string, auto: boolean): AgentConfig;
80
+ }, ctx: Pick<ToolContext, 'autoApproveTools' | 'permissionRules' | 'toolSandbox' | 'askBudget' | 'commandSandbox'>, cwd: string, auto: boolean): AgentConfig;
149
81
  /** What a child runs without asking: what the parent does, else the read-only tools. Destructive tools still never run unasked. */
150
82
  export declare function childAutoApprove(ctx: Pick<ToolContext, 'autoApproveTools'>): string[];
151
83
  /** The configured sub-agent model, else the parent's, else a last-resort default. */
@@ -328,6 +328,7 @@ export function childAgentConfig(setup, ctx, cwd, auto) {
328
328
  autoApproveTools: childAutoApprove(ctx),
329
329
  ...(ctx.permissionRules ? { permissionRules: ctx.permissionRules } : {}),
330
330
  ...(ctx.toolSandbox ? { toolSandbox: ctx.toolSandbox } : {}),
331
+ ...(ctx.commandSandbox ? { commandSandbox: ctx.commandSandbox } : {}),
331
332
  // The same budget object, not a copy: a child that started its own four
332
333
  // would be a way around the limit the parent is under (RB-14).
333
334
  ...(ctx.askBudget ? { askBudget: ctx.askBudget } : {}),
@@ -7,26 +7,14 @@ import type { TodoItem, ToolDefinition } from '../types.js';
7
7
  declare const writeParams: z.ZodObject<{
8
8
  todos: z.ZodArray<z.ZodObject<{
9
9
  content: z.ZodString;
10
- status: z.ZodEnum<["pending", "in_progress", "completed"]>;
11
- }, "strip", z.ZodTypeAny, {
12
- status: "pending" | "in_progress" | "completed";
13
- content: string;
14
- }, {
15
- status: "pending" | "in_progress" | "completed";
16
- content: string;
17
- }>, "many">;
18
- }, "strip", z.ZodTypeAny, {
19
- todos: {
20
- status: "pending" | "in_progress" | "completed";
21
- content: string;
22
- }[];
23
- }, {
24
- todos: {
25
- status: "pending" | "in_progress" | "completed";
26
- content: string;
27
- }[];
28
- }>;
29
- declare const readParams: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
10
+ status: z.ZodEnum<{
11
+ pending: "pending";
12
+ in_progress: "in_progress";
13
+ completed: "completed";
14
+ }>;
15
+ }, z.core.$strip>>;
16
+ }, z.core.$strip>;
17
+ declare const readParams: z.ZodObject<{}, z.core.$strip>;
30
18
  export declare const todoWriteTool: ToolDefinition<z.infer<typeof writeParams>, {
31
19
  todos: TodoItem[];
32
20
  }>;
@@ -39,13 +39,7 @@ export declare function searchWeb(cfg: WebSearchConfig, query: string, count: nu
39
39
  declare const params: z.ZodObject<{
40
40
  query: z.ZodString;
41
41
  max_results: z.ZodOptional<z.ZodNumber>;
42
- }, "strip", z.ZodTypeAny, {
43
- query: string;
44
- max_results?: number | undefined;
45
- }, {
46
- query: string;
47
- max_results?: number | undefined;
48
- }>;
42
+ }, z.core.$strip>;
49
43
  export interface WebSearchToolResult {
50
44
  provider: WebSearchProvider;
51
45
  query: string;
@@ -3,13 +3,7 @@ import type { ToolDefinition } from '../types.js';
3
3
  declare const params: z.ZodObject<{
4
4
  path: z.ZodString;
5
5
  content: z.ZodString;
6
- }, "strip", z.ZodTypeAny, {
7
- path: string;
8
- content: string;
9
- }, {
10
- path: string;
11
- content: string;
12
- }>;
6
+ }, z.core.$strip>;
13
7
  export interface WriteFileResult {
14
8
  path: string;
15
9
  bytes: number;
package/dist/types.d.ts CHANGED
@@ -107,6 +107,10 @@ export interface ToolContext {
107
107
  * the default `child_process` runner.
108
108
  */
109
109
  commandRunner?: CommandRunner;
110
+ /** How long `search_files` may match before its worker is stopped. Default 20 s. */
111
+ searchTimeoutMs?: number;
112
+ /** Run `run_command` inside the OS sandbox (`AgentConfig.commandSandbox`); handed to sub-agents. */
113
+ commandSandbox?: CommandSandbox;
110
114
  /** The model sub-agents use instead of the parent's (`AgentConfig.subAgentModel`). */
111
115
  subAgentModel?: ModelConfig;
112
116
  /** Folder `AGENTS.md` paths already shown in this run; `read_file` adds each folder's file once. */
@@ -176,6 +180,13 @@ export type ModelRouter = (ctx: {
176
180
  /** Tool names the model called on the previous step (empty on the first). */
177
181
  lastToolNames: string[];
178
182
  }) => ModelConfig | undefined;
183
+ /** What `run_command`'s OS sandbox allows besides writing to the workspace and the temp folder. */
184
+ export interface CommandSandbox {
185
+ /** Let commands reach the network. */
186
+ network: boolean;
187
+ /** More folders commands may write to (a package manager's cache, say). */
188
+ extraWritable?: string[];
189
+ }
179
190
  /**
180
191
  * Executes one shell command on behalf of `run_command`. Return `null` to decline
181
192
  * (e.g. no terminal available); the default `child_process` runner then handles it.
@@ -250,6 +261,11 @@ export interface ChildProgressEvent {
250
261
  /** Any event the child emitted. */
251
262
  event: AgentEvent;
252
263
  }
264
+ /**
265
+ * How a tool call was let through: the person approved it, a permission rule allowed it, it is on the
266
+ * auto-approve list, memory writes are allowed, the command is on the "Always allow" list, or the run is Autonomous.
267
+ */
268
+ export type ApprovalSource = 'person' | 'rule' | 'list' | 'memory' | 'always' | 'autonomous';
253
269
  /** Streamed agent event: surfaced to the UI via the AgentRunOptions.onEvent callback. */
254
270
  export type AgentEvent = {
255
271
  type: 'text_delta';
@@ -263,11 +279,14 @@ export type AgentEvent = {
263
279
  } | {
264
280
  type: 'reasoning_done';
265
281
  text: string;
266
- } | {
282
+ }
283
+ /** `approval` says how the call was let through; absent for bookkeeping tools that never ask (the todo list). */
284
+ | {
267
285
  type: 'tool_call';
268
286
  name: string;
269
287
  id: string;
270
288
  args: unknown;
289
+ approval?: ApprovalSource;
271
290
  } | {
272
291
  type: 'tool_result';
273
292
  name: string;
@@ -343,6 +362,22 @@ export type AgentEvent = {
343
362
  } | {
344
363
  type: 'continuation'; /** 1-based count of continuations so far in this run. */
345
364
  count: number;
365
+ }
366
+ /**
367
+ * The step now running failed (a provider error worth retrying, or an empty reply) and is being asked again after
368
+ * `delayMs`. Everything it streamed is discarded: a UI drops the step's partial text.
369
+ */
370
+ /** The model ended a turn with `open` items of its own todo list still open and was reminded once (RB-44). */
371
+ | {
372
+ type: 'todo_nudge';
373
+ open: number;
374
+ } | {
375
+ type: 'retry';
376
+ kind: 'provider_error' | 'empty_reply' | 'offline';
377
+ attempt: number;
378
+ maxRetries: number;
379
+ delayMs: number;
380
+ reason: string;
346
381
  } | {
347
382
  type: 'phase';
348
383
  /** Architect/editor mode: which phase the following events belong to. */
@@ -564,6 +599,8 @@ export interface AgentConfig {
564
599
  * be surprising.
565
600
  */
566
601
  disableMemory?: boolean;
602
+ /** Leave out the `<stack>` block (the versions the workspace's files state). Default: included. */
603
+ disableStackFacts?: boolean;
567
604
  /**
568
605
  * Skip injecting `AGENTS.md` / `CLAUDE.md` / `CONVENTIONS.md` from the
569
606
  * working directory into the system prompt.
@@ -740,6 +777,23 @@ export interface AgentConfig {
740
777
  * Each continuation is a normal iteration (counts toward every cap).
741
778
  */
742
779
  maxContinuations?: number;
780
+ /**
781
+ * Retrying a step whose model call failed with something a retry can fix (429, 5xx, overload, dropped
782
+ * connection). Default 5 retries, back-off from 2 s (doubling, capped at 30 s) unless the provider sends
783
+ * retry-after. An empty or reasoning-only reply is asked for again twice, separately.
784
+ */
785
+ providerRetry?: {
786
+ maxRetries?: number;
787
+ baseDelayMs?: number;
788
+ /**
789
+ * With no network at all (DNS or route gone) the run waits instead of spending retries: it probes every
790
+ * `offlinePollMs` (default 3 s) for up to `maxOfflineMs` in total (default 15 min), then reports the error.
791
+ */
792
+ offlinePollMs?: number;
793
+ maxOfflineMs?: number;
794
+ /** True when the network is reachable; default dials a few public addresses over TCP. */
795
+ networkProbe?: () => Promise<boolean>;
796
+ };
743
797
  /**
744
798
  * Pick the model for each step (cheap for exploration, strong for planning…).
745
799
  * Return `undefined` to keep the current model. Cost is priced per routed model.
@@ -747,6 +801,11 @@ export interface AgentConfig {
747
801
  modelRouter?: ModelRouter;
748
802
  /** Replace how `run_command` executes. See {@link CommandRunner}. */
749
803
  commandRunner?: CommandRunner;
804
+ /**
805
+ * Confine `run_command` with the OS sandbox: bubblewrap on Linux, sandbox-exec on macOS. A command is refused when
806
+ * the tool is missing; Windows has no equivalent, so there commands run as before. Absent = off.
807
+ */
808
+ commandSandbox?: CommandSandbox;
750
809
  /**
751
810
  * Answers `ask_user`. When absent, or when `auto` is on, the model is not offered the tool.
752
811
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ikarmic/forge-core",
3
- "version": "5.1.1",
3
+ "version": "5.3.0",
4
4
  "description": "Agent engine for IKarmic AI Forge. Model loop, tools, MCP, sandbox, memory, compaction, plan mode, skills, hooks.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -56,13 +56,13 @@
56
56
  "tree-sitter-wasms": "^0.1.13",
57
57
  "undici": "^7.30.0",
58
58
  "web-tree-sitter": "0.20.8",
59
- "zod": "^3.23.0"
59
+ "zod": "^4.6.7"
60
60
  },
61
61
  "devDependencies": {
62
62
  "@ai-sdk/provider": "^4.0.0",
63
63
  "@types/node": "^22.7.0",
64
64
  "typescript": "^5.6.3",
65
- "vitest": "^5.0.2"
65
+ "vitest": "^5.0.5"
66
66
  },
67
67
  "scripts": {
68
68
  "build": "tsc -p tsconfig.json",