@arnilo/prism 0.0.8 → 0.0.11

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 (62) hide show
  1. package/CHANGELOG.md +44 -3
  2. package/dist/agent-loops.d.ts +1 -0
  3. package/dist/agent-loops.js +44 -5
  4. package/dist/agents.js +141 -7
  5. package/dist/context-budget.d.ts +63 -0
  6. package/dist/context-budget.js +235 -0
  7. package/dist/contracts.d.ts +107 -0
  8. package/dist/contracts.js +77 -0
  9. package/dist/index.d.ts +7 -5
  10. package/dist/index.js +5 -4
  11. package/dist/input.d.ts +3 -0
  12. package/dist/input.js +71 -28
  13. package/dist/node/session-store-jsonl.js +4 -1
  14. package/dist/provider-events.d.ts +2 -0
  15. package/dist/provider-events.js +21 -13
  16. package/dist/providers/openai-compatible.js +8 -5
  17. package/dist/providers/transport.d.ts +10 -1
  18. package/dist/providers/transport.js +24 -8
  19. package/dist/rpc.js +13 -2
  20. package/dist/session-stores.d.ts +7 -2
  21. package/dist/session-stores.js +174 -4
  22. package/dist/structured-output.d.ts +5 -1
  23. package/dist/structured-output.js +18 -0
  24. package/dist/testing/persistence-schema.d.ts +1 -1
  25. package/dist/testing/persistence-schema.js +8 -2
  26. package/dist/testing/session-store-conformance.d.ts +6 -0
  27. package/dist/testing/session-store-conformance.js +36 -1
  28. package/dist/tools.js +2 -0
  29. package/docs/agent-events.md +3 -2
  30. package/docs/agent-loops.md +10 -3
  31. package/docs/agent-session-runtime.md +5 -1
  32. package/docs/browser-automation.md +124 -0
  33. package/docs/cli-rpc.md +2 -1
  34. package/docs/coding-agent-tools.md +178 -14
  35. package/docs/coding-security.md +84 -11
  36. package/docs/evaluations.md +13 -2
  37. package/docs/guardrails.md +2 -1
  38. package/docs/host-security.md +4 -2
  39. package/docs/index.md +19 -15
  40. package/docs/input-and-prompt-assembly.md +4 -1
  41. package/docs/migration.md +84 -0
  42. package/docs/node-jsonl-session-store.md +1 -1
  43. package/docs/performance.md +46 -0
  44. package/docs/postgres-persistence.md +3 -3
  45. package/docs/provider-conformance.md +1 -1
  46. package/docs/provider-packages.md +1 -1
  47. package/docs/provider-primitives.md +7 -1
  48. package/docs/providers/anthropic.md +92 -0
  49. package/docs/providers/google.md +87 -0
  50. package/docs/public-contracts.md +4 -0
  51. package/docs/release-and-install.md +197 -64
  52. package/docs/review-coverage-2026-07-20-phase-4.md +175 -0
  53. package/docs/review-coverage-2026-07-21-phase-5.md +172 -0
  54. package/docs/review-coverage-2026-07-22-phase-6.md +209 -0
  55. package/docs/session-store-conformance.md +2 -0
  56. package/docs/session-stores.md +40 -1
  57. package/docs/sqlite-persistence.md +3 -3
  58. package/docs/structured-output.md +9 -3
  59. package/docs/tools.md +3 -0
  60. package/docs/web-tools.md +1 -1
  61. package/docs/workflows.md +3 -0
  62. package/package.json +6 -5
@@ -25,6 +25,8 @@ Use this helper when implementing a DB-backed `SessionStore` (for example, the r
25
25
  - session ids remain isolated (`assertSessionStoreConforms` always probes a secondary session)
26
26
  - optional concurrent fork children of the same parent succeed when `exerciseConcurrentParentAppend: true`
27
27
  - optional durable reopen/idempotency survival when `runSessionStoreConformance(..., { exerciseReopen: true })`
28
+ - optional `searchSessions` bounds/ownership/empty-page checks when `exerciseSearchSessions: true` (`assertSessionStoreSearchSessions`)
29
+ - optional `searchSessions` bounds/ownership/empty-page checks when `exerciseSearchSessions: true` (`assertSessionStoreSearchSessions`)
28
30
 
29
31
  ## Inputs / request
30
32
 
@@ -24,13 +24,16 @@ import type { SessionStore, SessionEntry } from "@arnilo/prism";
24
24
  | `list(sessionId)` | Return all entries for one session in stored order. Development fallback for branch reads. |
25
25
  | `get?(id)` | Return one entry by id, if present. Optional. |
26
26
  | `readBranchPath?(query)` | Optional DB-friendly branch read. Return one branch's ancestor chain as a `PersistencePage<SessionEntry>` so the runtime can avoid `list(sessionId)`. |
27
+ | `searchSessions?(query)` | Optional bounded session search (`SessionSearchQuery` → `PersistencePage<SessionSearchHit>`). SQLite/Postgres implement FTS + metadata filters; memory default is linear; JSONL throws `SessionSearchUnsupportedError`. |
27
28
 
28
29
  Public helpers:
29
30
 
30
31
  | Helper | Purpose |
31
32
  | --- | --- |
32
33
  | `createSessionEntry(options)` | Build a `SessionEntry` with generated `id`/`timestamp` when omitted. |
33
- | `createMemorySessionStore(initialEntries?)` | Built-in in-memory `SessionStore`. |
34
+ | `createMemorySessionStore(initialEntries?, options?)` | Built-in in-memory `SessionStore`. `options.sessionSearchMode`: `"linear"` (default) or `"unsupported"` (throws `SessionSearchUnsupportedError`). |
35
+ | `resolveSessionSearchQuery(query)` | Validate/clamp search limits (page, query bytes, snippet, cursor, linear/FTS caps). |
36
+ | `SessionIndex` | Narrow search seam (`search(query)`); adapters may expose this instead of `SessionStore.searchSessions`. |
34
37
  | `getSessionBranchEntries(entries, options)` | Return root-to-leaf entries for a leaf id (sync array path). |
35
38
  | `getSessionBranchEntries(reader, query)` | Async overload for a `BranchReader` / `readBranchPath` implementation. |
36
39
  | `listSessionBranches(entries)` | List every branch handle as `{ leafId, entries }`. Pair with `sessionId` for a durable `(sessionId, leafId)` branch handle. |
@@ -107,6 +110,42 @@ Recognize it with `isSessionAppendConflict(error)`, not message text. Built-in s
107
110
  - Branch semantics are parent links plus a leaf id. External UIs should keep branch handles as `(sessionId, leafId)`; RPC exposes an additional `handleId` for active handles.
108
111
  - Development stores can omit `readBranchPath`; the runtime falls back to `list(sessionId)` and the pure in-memory branch walk. Database-backed stores should implement `readBranchPath` so `entries()`, `clone()`, and context rebuild read only the selected ancestor chain.
109
112
 
113
+ ## Session search (0.0.11)
114
+
115
+ Bounded `SessionIndex` / `searchSessions` lists sessions by optional `workspaceRoot` (`metadata.workspaceRoot`), provider/model, label/summary, time range, ownership, and optional text `query` (FTS on SQLite/Postgres; case-sensitive substring on memory linear). Hits require `sessionId` and may include `leafId` for `checkout`; never credentials or whole transcripts.
116
+
117
+ ```ts
118
+ import { createMemorySessionStore, resolveSessionSearchQuery } from "@arnilo/prism";
119
+
120
+ const store = createMemorySessionStore([], { sessionSearchMode: "linear" });
121
+ const page = await store.searchSessions!({
122
+ workspaceRoot: "/repo",
123
+ query: "flake",
124
+ limit: 20,
125
+ });
126
+ // Opt out: createMemorySessionStore([], { sessionSearchMode: "unsupported" })
127
+ ```
128
+
129
+ Finite caps (defaults / hard): page 20/100; query string 4 KiB/16 KiB; snippet 512 B/4 KiB; cursor 1 KiB/4 KiB; memory linear sessions 1000/5000, entries 10000/50000, bytes 8 MiB/64 MiB; DB FTS candidates 1000/5000. Overflow fails closed via `resolveSessionSearchQuery`. See [Phase 6 evidence](review-coverage-2026-07-22-phase-6.md).
130
+
131
+ ## Session search (0.0.11)
132
+
133
+ Bounded `SessionIndex` / `searchSessions` lists sessions by optional `workspaceRoot` (`metadata.workspaceRoot`), provider/model, label/summary, time range, ownership, and optional text `query` (FTS on SQLite/Postgres; case-sensitive substring on memory linear). Hits require `sessionId` and may include `leafId` for `checkout`; never credentials or whole transcripts.
134
+
135
+ ```ts
136
+ import { createMemorySessionStore, resolveSessionSearchQuery } from "@arnilo/prism";
137
+
138
+ const store = createMemorySessionStore([], { sessionSearchMode: "linear" });
139
+ const page = await store.searchSessions!({
140
+ workspaceRoot: "/repo",
141
+ query: "flake",
142
+ limit: 20,
143
+ });
144
+ // Opt out: createMemorySessionStore([], { sessionSearchMode: "unsupported" })
145
+ ```
146
+
147
+ Finite caps (defaults / hard): page 20/100; query string 4 KiB/16 KiB; snippet 512 B/4 KiB; cursor 1 KiB/4 KiB; memory linear sessions 1000/5000, entries 10000/50000, bytes 8 MiB/64 MiB; DB FTS candidates 1000/5000. Overflow fails closed via `resolveSessionSearchQuery`. See [Phase 6 evidence](review-coverage-2026-07-22-phase-6.md).
148
+
110
149
  ## Security and performance notes
111
150
 
112
151
  - Do not store provider credentials, credential resolvers, provider instances, or unredacted secrets in session entries, append options, idempotency keys, or branch records.
@@ -4,7 +4,7 @@
4
4
 
5
5
  The optional `@arnilo/prism-session-store-sqlite` package ships a production-oriented SQLite adapter that implements:
6
6
 
7
- - `SessionStore` — atomic `append` / `list` / `get` / `readBranchPath`
7
+ - `SessionStore` — atomic `append` / `list` / `get` / `readBranchPath` / bounded `searchSessions` / bounded `searchSessions`
8
8
  - `RunLedger` — durable run, event, tool-call, and usage rows
9
9
  - `ProductionPersistenceStore` — cursor-paginated `query*` reads plus generic `checkpoints` and atomic `leases` capabilities
10
10
 
@@ -56,7 +56,7 @@ import { createSqlitePersistence } from "@arnilo/prism-session-store-sqlite";
56
56
  | `leases` | Atomic `LeaseStore` backed by `prism_leases`; database-clock expiry, opaque renew/release token, monotonic takeover fence. |
57
57
  | `close()` | Closes the underlying database when the adapter opened it. |
58
58
 
59
- Migrations run automatically on open and are idempotent across reopen. Under the SQLite migration transaction, startup checks ordered contract name/version/SHA-256 rows plus full schema-v3 PRAGMA/catalog shape (all required tables, columns/types/nullability/defaults, PK/unique/FK keys, and named indexes) before any runtime write. A complete legacy 0.0.5 history with all `checksum` values `NULL` is shape-verified then backfilled transactionally once. Unknown, duplicate, out-of-order, partial-legacy, checksum, or shape drift rejects open; restore or apply reviewed DDL rather than editing migration rows.
59
+ Migrations run automatically on open and are idempotent across reopen. Under the SQLite migration transaction, startup checks ordered contract name/version/SHA-256 rows plus full schema-v4 PRAGMA/catalog shape (all required tables, columns/types/nullability/defaults, PK/unique/FK keys, and named indexes) before any runtime write. A complete legacy 0.0.5 history with all `checksum` values `NULL` is shape-verified then backfilled transactionally once. Unknown, duplicate, out-of-order, partial-legacy, checksum, or shape drift rejects open; restore or apply reviewed DDL rather than editing migration rows.
60
60
 
61
61
  ## Request/response example
62
62
 
@@ -99,7 +99,7 @@ For resume/timeline flows, use `queryRuns`, `queryEvents`, `queryToolCalls`, and
99
99
  - The package is optional and workspace-local; `@arnilo/prism` core has no SQLite dependency.
100
100
  - Hosts choose the database path and own backup, retention enforcement, and filesystem permissions.
101
101
  - `SessionAppendOptions` idempotency rows are durable in `prism_session_append_idempotency` and survive reopen.
102
- - Schema version **3** applies `001_init`, additive `002_usage_scope`, and `003_run_feedback`. Migration 003 adds immutable `prism_run_feedback` rows with run FK/cascade deletion and owner/run/trace cursor indexes. `persistence.feedback` validates exact run ownership, bounds/redacts through optional `feedbackRedactor`, queries bounded pages, and deletes only exact-owned IDs. PostgreSQL shares the same model with dialect-local DDL.
102
+ - Schema version **4** applies `001_init`, `002_usage_scope`, `003_run_feedback`, and `004_session_search`. Migration 003 adds immutable `prism_run_feedback` rows with run FK/cascade deletion and owner/run/trace cursor indexes. Migration 004 adds session search FTS (FTS5 virtual table `prism_session_search_fts` dual-written on append) plus `prism_sessions(updated_at, id)` cursor index; existing entries are backfilled once. `persistence.feedback` validates exact run ownership, bounds/redacts through optional `feedbackRedactor`, queries bounded pages, and deletes only exact-owned IDs. Search hits never include credentials; ownership filters apply when present. PostgreSQL shares the same model with dialect-local DDL.
103
103
  - Pass an existing `better-sqlite3` `Database` via `database` when your host already manages connections.
104
104
 
105
105
  ## Security and performance notes
@@ -49,8 +49,11 @@ await session.run(input, {
49
49
  parser, // optional; default treats assistant text as the value
50
50
  repairer, // optional; default stringifies validation.errors[].message
51
51
  maxRevisions: 3, // optional; default 3
52
+ toolCalls: "bounded", // optional; default "disabled"
52
53
  structuredOutput: { name: "answer", schema, strict: true }, // optional native mode
53
54
  structuredOutputMode: "native", // or "artifact-loop" to skip provider-native schema
55
+ // Opt-in: schema only on artifact/revision turns (tools free on earlier turns).
56
+ structuredOutputTiming: "final-turn-only", // default "every-turn"
54
57
  },
55
58
  providerOptions: {
56
59
  structuredOutput: { name: "answer", schema, strict: true }, // direct native request
@@ -58,6 +61,8 @@ await session.run(input, {
58
61
  });
59
62
  ```
60
63
 
64
+ `structuredOutputTiming: "final-turn-only"` (with `toolCalls: "bounded"` and native schema) sends tool-eligible turns **without** `response_format` so models can call tools; once the model returns a call-free candidate (or tool rounds are exhausted), the next turn withdraws tools and attaches schema. Revision turns stay schema-on / tools-off. Default `"every-turn"` keeps legacy behavior (schema on every provider request).
65
+
61
66
  ## Outputs / response / events
62
67
 
63
68
  `generateValidateReviseLoop.run(ctx)` returns `Promise<Usage | undefined>`. Observable behavior is emitted through `AgentEvent` artifact variants (zero emitted by `singleShotLoop`):
@@ -230,11 +235,12 @@ Key cross-seam points:
230
235
 
231
236
  - `generate-validate-revise` is selected via `AgentConfig.loop` / `RunOptions.loop` (`RunOptions.loop` wins). See [Agent loops](agent-loops.md). `resolveLoop()` maps the options form to the factory; an unknown `strategy` throws before the first turn; a custom `AgentLoopStrategy` instance bypasses the options form.
232
237
  - Native structured output uses provider-neutral `StructuredOutputOptions` on `ProviderRequestOptions` / loop options. Capable OpenAI-family providers map to JSON-schema wire fields; unsupported models fail before fetch unless the host sets `structuredOutputMode: "artifact-loop"` and relies on parser/validator/repairer only.
238
+ - `structuredOutputTiming: "final-turn-only"` (opt-in; default `"every-turn"`) with `toolCalls: "bounded"` omits native schema on tool-eligible turns and attaches schema only on artifact/revision turns (tools withdrawn). Call-free tool-phase output promotes to one schema turn before parse/validate.
233
239
  - `validateStructuredOutputOptions()` enforces JSON-safe schemas, forbidden prototype-pollution keys, and a 64 KiB schema size cap.
234
- - The default parser treats assistant text as the value (`{ ok: true, value: text }`); supply a host parser whenever `T` is not `string`.
240
+ - The default parser treats non-empty assistant text as the value (`{ ok: true, value: text }`); empty/whitespace-only call-free text is a `parse_error` before the parser. Supply a host parser whenever `T` is not `string`.
235
241
  - The default repairer builds a user message from `validation.errors[].message`; supply a host repairer for schema-specific guidance.
236
- - `maxRevisions` (default 3) bounds revision turns; budget exhaustion ends the loop and emits `artifact_failed` (it does not throw).
237
- - Tools are inert in artifact turns unless `loop.toolCalls: "bounded"` is explicit. Bounded mode uses run-global `maxToolRounds`, dispatches calls sequentially through normal runtime guards, skips parser/validator for tool-calling responses, and permits at most `1 + maxRevisions + maxToolRounds` provider turns. An extra tool response yields terminal `artifact_failed` with `result.metadata.reason === "tool_round_limit"` and executes nothing.
242
+ - `maxRevisions` (default 3) bounds revision turns; budget exhaustion ends the loop and emits `artifact_failed`. Session runs then fail with `AgentRunError` unless `artifact_finished` occurred (direct `loop.run` still returns usage without throwing).
243
+ - Tools are inert in artifact turns unless `loop.toolCalls: "bounded"` is explicit. Bounded mode uses run-global `maxToolRounds`, dispatches calls sequentially through normal runtime guards, skips parser/validator for tool-calling responses, and permits at most `1 + maxRevisions + maxToolRounds` provider turns (plus one extra schema turn under `final-turn-only` when a tool-phase call-free draft promotes). An extra tool response yields terminal `artifact_failed` with `result.metadata.reason === "tool_round_limit"` and executes nothing.
238
244
 
239
245
  ## Security and performance notes
240
246
 
package/docs/tools.md CHANGED
@@ -11,6 +11,7 @@ APIs:
11
11
  - `dispatchToolCall()`
12
12
  - `ToolFilter`, `ToolFilterInput`, `ToolValidator`, `DispatchToolCallOptions`
13
13
  - Optional [Web search, fetch, and extraction](web-tools.md): three narrow host-selected `ToolDefinition`s with untrusted bounded outputs.
14
+ - Optional [Browser automation](browser-automation.md): four exclusive Playwright tools over a host-supplied browser with run-owned contexts and snapshot refs.
14
15
 
15
16
  ## When to use it
16
17
 
@@ -91,6 +92,8 @@ When `options.ledger` is set, `dispatchToolCall()` also appends a `ToolCallRecor
91
92
 
92
93
  Blocked reasons are `unknown_tool`, `tool_denied`, `invalid_arguments`, `permission_denied`, and `validation_failed`. Progress snapshots reuse status `started` because the tool call is still in flight.
93
94
 
95
+ Malformed streamed tool-call JSON (id+name present, arguments not a JSON object) does not fail the provider turn. Providers emit a tool call with `argumentsError`; `dispatchToolCall` blocks with reason `invalid_arguments` and `error.code: "invalid_json_arguments"`, persists a failed tool result, and never calls `execute()`. The model can self-correct within `maxToolRounds`/`maxTurns`.
96
+
94
97
  ## Request/response example
95
98
 
96
99
  ```json
package/docs/web-tools.md CHANGED
@@ -67,7 +67,7 @@ Default/hard limits: query 4/16 KiB; results 10/20; URLs 5/20; request 256 KiB/1
67
67
 
68
68
  Provider credentials never enter tool schemas/results, prompts, telemetry, URLs, or errors. Error text excludes remote bodies. Search snippets, Markdown, and extracted JSON are prompt-injection-capable data: never concatenate them into system instructions or use them to modify tools, permissions, credentials, trust, routing, or schemas. Firecrawl fetches target URLs remotely; Prism cannot claim target DNS pinning after handoff. Use controlled host fetch when that guarantee is required.
69
69
 
70
- Default tests use injected fake fetch and make no public request. Restricted smoke: `PRISM_LIVE_WEB=1 npm run test:live -w @arnilo/prism-web-tools` plus least-privilege provider environment credential. Browser automation, arbitrary HTML execution, model-selected providers, automatic OAuth forwarding, and generic web/MCP passthrough are unsupported.
70
+ Default tests use injected fake fetch and make no public request. Restricted smoke: `PRISM_LIVE_WEB=1 npm run test:live -w @arnilo/prism-web-tools` plus least-privilege provider environment credential. Prefer these tools over `@arnilo/prism-browser` for ordinary public retrieval; use browser automation only for interactive/authenticated/JavaScript-heavy work behind a host egress proxy. Arbitrary HTML execution, model-selected providers, automatic OAuth forwarding, and generic web/MCP passthrough are unsupported.
71
71
 
72
72
  ## Related APIs
73
73
 
package/docs/workflows.md CHANGED
@@ -72,6 +72,8 @@ All workflow limits and runtime `concurrency` reject non-safe integers, zero, ne
72
72
 
73
73
  A function node returns `suspend({ reason, data?, resumeSchema? })` to persist `status: "suspended"`. Its next invocation receives `ctx.resume` only after an approved resume. `resumeWorkflow(workflow, { runId }, options)` validates schema/version/ownership/`definitionHash`, claims the checkpoint before node execution, and continues the suspended node. Denial persists terminal `denied` status without invoking it. Existing failed/aborted checkpoint resume remains available without a human decision.
74
74
 
75
+ Coding-agent ask-user glue (opt-in, no Goal DB): `suspendAskUserDecision(request)` wraps `suspend` with durable question/options/`selectionMode`/`allowCustom` data + resume schema; resume with `createAskUserDecisionResumeValidator()` or `validateAskUserDecisionResume`. Goal→verify: `runCodingGoalVerify` / `createCodingGoalVerifyWorkflow` compose plan Markdown → named checks → approve suspend → bounded handoff over the same primitives (`examples/coding-goal-verify.ts`).
76
+
75
77
  Every node receives bounded `ctx.state`, `ctx.stateVersion`, and async `ctx.updateState(patch, { mode: "merge" | "replace" })`. Updates serialize, validate, redact, and snapshot before checkpoint save. `workflowNode({ workflow })` runs its child with the same ownership, agent/tool registries, execution policy, redactor, signal, checkpoints, and event bus; child state replaces parent state after success.
76
78
 
77
79
  `replayWorkflow(workflow, { sourceRunId, fromNodeId, runId? }, options)` requires a succeeded source/node, creates a new checkpoint, copies terminal evidence outside the selected node's downstream closure, restores selected-node pre-state, and records `{ sourceRunId, fromNodeId, rootRunId, depth }`. Source evidence is untouched. Copying any prior nested/tool approval is rejected; replay from that approval node or earlier so Phase 8 approval executes again.
@@ -299,4 +301,5 @@ Use workflows for known, durable, replayable graphs. Use optional supervisor del
299
301
  - [PostgreSQL persistence](postgres-persistence.md): durable `persistence.checkpoints`
300
302
  - [Observability](observability.md): exporting workflow/agent events
301
303
  - [Coding execution approval and sandboxing](coding-security.md): `ExecutionPolicy` for tool nodes
304
+ - [Coding agent tools](coding-agent-tools.md): opt-in `createGitTools()` / `git_pr_handoff` produce bounded host-owned PR payloads; durable coding plans/todos are workspace Markdown plus `state.coding` metadata helpers — workflows may compose them for restart/resume/background branches but Prism never pushes or opens PRs
302
305
  - [Release and install](release-and-install.md): atomic and profile installs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arnilo/prism",
3
- "version": "0.0.8",
3
+ "version": "0.0.11",
4
4
  "description": "Agent harness for AI providers, agents, sessions, and tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -110,15 +110,16 @@
110
110
  "packages/session-store-*",
111
111
  "packages/credentials-node",
112
112
  "packages/mcp",
113
+ "packages/evals",
114
+ "packages/workflows",
113
115
  "packages/coding-agent",
114
116
  "packages/coding-security",
115
- "packages/workflows",
116
- "packages/evals",
117
117
  "packages/memory",
118
118
  "packages/rag",
119
119
  "packages/server",
120
120
  "packages/supervisor",
121
121
  "packages/web-tools",
122
+ "packages/browser",
122
123
  "packages/prism-*"
123
124
  ],
124
125
  "scripts": {
@@ -134,8 +135,8 @@
134
135
  "sdk:ready": "npm run typecheck && npm test && npm run pack:dry-run"
135
136
  },
136
137
  "devDependencies": {
137
- "typescript": "^5.7.0",
138
- "@types/node": "^22.0.0"
138
+ "typescript": "^7.0.2",
139
+ "@types/node": "^26.1.1"
139
140
  },
140
141
  "engines": {
141
142
  "node": ">=20"