@rethunk/mcp-multi-root-git 2.0.1 → 2.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.
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Lightweight test harness for MCP tool execute handlers.
3
+ *
4
+ * FastMCP does not expose a way to inject a custom transport, so the full
5
+ * MCP client/server stack cannot be wired up in tests without stdio or HTTP.
6
+ * Instead, we use a duck-typed fake server that satisfies the FastMCP interface
7
+ * just enough for tool registration: it has `sessions` (empty — tools use
8
+ * `workspaceRoot` arg which bypasses session root detection) and `addTool`
9
+ * which captures the tool definition so we can call `execute` directly.
10
+ *
11
+ * Context passed to execute is a no-op stub — none of the current tools
12
+ * use the context object (logging, progress, etc.).
13
+ *
14
+ * Usage:
15
+ * const tool = captureTool(registerBatchCommitTool);
16
+ * const result = await tool({ workspaceRoot: dir, commits: [...] });
17
+ * // result is string (markdown) or JSON-parseable string
18
+ */
19
+ // Stub context — no tool currently uses context
20
+ const STUB_CONTEXT = {
21
+ log: {
22
+ debug: () => undefined,
23
+ error: () => undefined,
24
+ info: () => undefined,
25
+ warn: () => undefined,
26
+ },
27
+ reportProgress: async () => undefined,
28
+ session: undefined,
29
+ };
30
+ // ---------------------------------------------------------------------------
31
+ // Fake server
32
+ // ---------------------------------------------------------------------------
33
+ function makeFakeServer() {
34
+ const tools = [];
35
+ const server = {
36
+ sessions: [],
37
+ addTool(tool) {
38
+ tools.push({ name: tool.name, execute: tool.execute });
39
+ },
40
+ };
41
+ return { server, tools };
42
+ }
43
+ // ---------------------------------------------------------------------------
44
+ // Public API
45
+ // ---------------------------------------------------------------------------
46
+ /**
47
+ * Register one tool and return a caller that invokes its execute handler.
48
+ * The returned function accepts tool args (always include `workspaceRoot`)
49
+ * and returns the raw result as a string.
50
+ */
51
+ export function captureTool(register, toolName) {
52
+ const { server, tools } = makeFakeServer();
53
+ register(server);
54
+ const pick = toolName ? tools.find((t) => t.name === toolName) : tools[0];
55
+ if (!pick) {
56
+ throw new Error(`captureTool: no tool captured${toolName ? ` named "${toolName}"` : ""}. Did you forget to call register?`);
57
+ }
58
+ return async (args) => {
59
+ const result = await pick.execute(args, STUB_CONTEXT);
60
+ if (typeof result === "string")
61
+ return result;
62
+ return JSON.stringify(result);
63
+ };
64
+ }
@@ -1,4 +1,9 @@
1
+ import { registerBatchCommitTool } from "./batch-commit-tool.js";
2
+ import { registerGitCherryPickTool } from "./git-cherry-pick-tool.js";
3
+ import { registerGitDiffSummaryTool } from "./git-diff-summary-tool.js";
1
4
  import { registerGitInventoryTool } from "./git-inventory-tool.js";
5
+ import { registerGitLogTool } from "./git-log-tool.js";
6
+ import { registerGitMergeTool } from "./git-merge-tool.js";
2
7
  import { registerGitParityTool } from "./git-parity-tool.js";
3
8
  import { registerGitStatusTool } from "./git-status-tool.js";
4
9
  import { registerListPresetsTool } from "./list-presets-tool.js";
@@ -8,5 +13,10 @@ export function registerRethunkGitTools(server) {
8
13
  registerGitInventoryTool(server);
9
14
  registerGitParityTool(server);
10
15
  registerListPresetsTool(server);
16
+ registerBatchCommitTool(server);
17
+ registerGitDiffSummaryTool(server);
18
+ registerGitLogTool(server);
19
+ registerGitMergeTool(server);
20
+ registerGitCherryPickTool(server);
11
21
  registerPresetsResource(server);
12
22
  }
package/docs/mcp-tools.md CHANGED
@@ -15,6 +15,11 @@ MCP clients expose tools as `{serverName}_{toolName}`. With the server registere
15
15
  | `git_inventory` | `rethunk-git_git_inventory` | Status + ahead/behind per path; default upstream each repo’s `@{u}`; pass **both** `remote` and `branch` for fixed tracking. `nestedRoots`, `preset`, `presetMerge`, `maxRoots`, `format`, plus workspace pick args. |
16
16
  | `git_parity` | `rethunk-git_git_parity` | Compare `git rev-parse HEAD` for path pairs. `pairs`, `preset`, `presetMerge`, `format`, plus workspace pick args. |
17
17
  | `list_presets` | `rethunk-git_list_presets` | List preset names/counts from `.rethunk/git-mcp-presets.json`; invalid JSON/schema surface as errors. Workspace pick + `format` only. |
18
+ | `git_log` | `rethunk-git_git_log` | Path-filtered, time-windowed `git log` across one or more workspace roots. Returns commit history with author, date, subject, and shortstat. Args: `since`, `paths`, `grep`, `author`, `maxCommits`, `branch`, plus workspace pick args + `format`. |
19
+ | `git_diff_summary` | `rethunk-git_git_diff_summary` | Structured, token-efficient diff viewer. Returns per-file diffs with additions/deletions counts, truncated to configurable line limits, with lock files/dist/vendor excluded by default. Args: `range`, `fileFilter`, `maxLinesPerFile`, `maxFiles`, `excludePatterns`, plus workspace pick args + `format`. **Read-only.** |
20
+ | `batch_commit` | `rethunk-git_batch_commit` | Create multiple sequential git commits in a single call. Each entry stages the listed files then commits with the given message. Stops on first failure. Optional `push: "after"` pushes the current branch to its upstream once every commit lands. Args: `commits` (array of `{message, files}`), `push?`, plus workspace pick args + `format`. **Mutating — not idempotent.** |
21
+ | `git_merge` | `rethunk-git_git_merge` | Merge one or more source branches into a destination. Default strategy `auto` cascades fast-forward → rebase → merge-commit per source, preferring linear history. Refuses on dirty tree; stops on first conflict with structured path report. Optional `deleteMergedBranches` / `deleteMergedWorktrees` cascade cleanup, always skipping protected names (main/master/dev/develop/stable/trunk/prod/production/release\*/hotfix\*). Args: `sources`, `into?`, `strategy?`, `message?`, cleanup flags + workspace pick + `format`. **Mutating.** |
22
+ | `git_cherry_pick` | `rethunk-git_git_cherry_pick` | Play commits from one or more sources onto a destination. Sources may be SHAs, `A..B` ranges, or branch names (expanded to `onto..<branch>`, oldest-first). Uses `--empty=drop` so patch-equivalent re-applies add nothing. Refuses on dirty tree; stops on first conflict, aborting cleanly. Same cleanup flags as `git_merge` (branch-kind sources only, protected names skipped). Args: `sources`, `onto?`, cleanup flags + workspace pick + `format`. **Mutating.** |
18
23
 
19
24
  Pass **`format: "json"`** on any tool for structured JSON instead of markdown (default).
20
25
 
@@ -43,6 +48,297 @@ To keep responses compact, **optional fields are omitted when they would be empt
43
48
 
44
49
  **When to bump `MCP_JSON_FORMAT_VERSION` or change payload shape:** [AGENTS.md](../AGENTS.md) — *Changing contracts*.
45
50
 
51
+ ### `git_log` — parameters
52
+
53
+ | Parameter | Type | Default | Notes |
54
+ |-----------|------|---------|-------|
55
+ | `since` | string | `"7.days"` | Passed to `git log --since=`. Accepts ISO timestamps (`2026-04-01T00:00:00Z`) or git relative forms (`48.hours`, `2.weeks.ago`). |
56
+ | `paths` | string[] | (all) | Restrict to commits touching these paths (appended after `--`). |
57
+ | `grep` | string | — | Filter by commit message regex (git `--grep`, always case-insensitive). |
58
+ | `author` | string | — | Filter by author name or email (`--author=`). |
59
+ | `maxCommits` | int | `50` | Max commits per root. Hard cap: `500`. |
60
+ | `branch` | string | `HEAD` | Ref/branch to log from. |
61
+ | `workspaceRoot` | string | — | Explicit root; highest priority. |
62
+ | `rootIndex` | int | — | Pick one of several MCP roots (0-based). |
63
+ | `allWorkspaceRoots` | boolean | `false` | Fan out across all MCP roots. |
64
+ | `format` | `"markdown"` \| `"json"` | `"markdown"` | Output format. |
65
+
66
+ ### `git_log` — JSON shape (`format: "json"`)
67
+
68
+ ```json
69
+ {
70
+ "groups": [{
71
+ "workspace_root": "/abs/path",
72
+ "repo": "my-repo",
73
+ "branch": "main",
74
+ "commits": [{
75
+ "sha7": "a1bf184",
76
+ "shaFull": "a1bf184c3d...",
77
+ "subject": "feat(satcom): upgrade to PROTOCOL_VERSION 4",
78
+ "author": "Damon Blais",
79
+ "email": "damon@example.com",
80
+ "date": "2026-04-12T18:32:01-07:00",
81
+ "ageRelative": "42m ago",
82
+ "filesChanged": 4,
83
+ "insertions": 16,
84
+ "deletions": 5
85
+ }],
86
+ "truncated": true,
87
+ "omittedCount": 12
88
+ }]
89
+ }
90
+ ```
91
+
92
+ v2 field-omission rules: `filesChanged`, `insertions`, `deletions` are omitted when zero/absent (new file with no shortstat). `truncated` and `omittedCount` are omitted when `false`/`0`. A group emits `error` instead of `commits` when git fails for that root.
93
+
94
+ ### `git_log` — error codes
95
+
96
+ | Code | Meaning |
97
+ |------|---------|
98
+ | `git_not_found` | `git` binary not on `PATH`. |
99
+ | `not_a_git_repo` | The resolved workspace root is not inside a git repository. |
100
+ | `invalid_since` | The `since` string contains shell metacharacters and was rejected. |
101
+ | `invalid_paths` | One of the `paths` entries contains shell metacharacters and was rejected. |
102
+ | `git_log_failed` | `git log` exited non-zero (e.g. unknown branch ref). |
103
+ | `root_index_out_of_range` | `rootIndex` exceeds the number of MCP file roots. |
104
+
105
+ ### `git_diff_summary` — parameters
106
+
107
+ | Parameter | Type | Default | Notes |
108
+ |-----------|------|---------|-------|
109
+ | `range` | string | unstaged | Diff range. `"staged"` / `"cached"` for index; `"HEAD"` for last commit; `"A..B"` or `"A...B"` for revision ranges; single ref. Default: unstaged working-tree changes. |
110
+ | `fileFilter` | string | — | Glob pattern to restrict output to matching files (e.g. `"*.ts"`, `"src/**"`). |
111
+ | `maxLinesPerFile` | int | `50` | Max diff lines to include per file (1–2000). |
112
+ | `maxFiles` | int | `30` | Max files to include in output (1–500). |
113
+ | `excludePatterns` | string[] | lock files, dist, vendor | Glob patterns to exclude. Defaults to `*.lock`, `*.lockb`, `bun.lock`, `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `*.min.js`, `*.min.css`, `vendor/**`, `node_modules/**`, `dist/**`. Pass an empty array to disable. |
114
+ | `workspaceRoot` | string | — | Explicit root; highest priority. |
115
+ | `rootIndex` | int | — | Pick one of several MCP roots (0-based). |
116
+ | `format` | `"markdown"` \| `"json"` | `"markdown"` | Output format. |
117
+
118
+ ### `git_diff_summary` — JSON shape (`format: "json"`)
119
+
120
+ ```json
121
+ {
122
+ "range": "unstaged changes",
123
+ "totalFiles": 2,
124
+ "totalAdditions": 10,
125
+ "totalDeletions": 5,
126
+ "files": [{
127
+ "path": "src/foo.ts",
128
+ "status": "modified",
129
+ "additions": 8,
130
+ "deletions": 3,
131
+ "truncated": false,
132
+ "diff": "@@ -1,3 +1,8 @@\n-const x = 1;\n+const x = 2;"
133
+ }],
134
+ "truncatedFiles": 1,
135
+ "excludedFiles": ["yarn.lock"]
136
+ }
137
+ ```
138
+
139
+ `status` is one of `"modified"`, `"added"`, `"deleted"`, `"renamed"`. `oldPath` is present only for renamed files. `truncatedFiles` and `excludedFiles` are omitted when zero/empty (v2 field-omission contract).
140
+
141
+ ### `git_diff_summary` — error codes
142
+
143
+ | Code | Meaning |
144
+ |------|---------|
145
+ | `git_not_found` | `git` binary not on `PATH`. |
146
+ | `not_a_git_repository` | The resolved workspace root is not inside a git repository. |
147
+ | `unsafe_range_token` | The `range` string contains characters outside the safe token set. |
148
+ | `git_diff_failed` | `git diff` exited non-zero. |
149
+
150
+ ---
151
+
152
+ ### `batch_commit` — parameters
153
+
154
+ | Parameter | Type | Notes |
155
+ |-----------|------|-------|
156
+ | `commits` | `{message: string, files: string[]}[]` | Commits to create in order. 1–50 entries. Each `files` entry is a path relative to the git root; all must stay within the git toplevel. |
157
+ | `push` | `"never"` \| `"after"` | Default `"never"`. `"after"` pushes the current branch to its upstream **once all commits succeed**. Never auto-sets upstream — branches without an upstream fail with `push_no_upstream`. Commits are **not** rolled back on push failure. Enum reserved for future modes such as `"force-with-lease"`. |
158
+ | `workspaceRoot` | string | Explicit root; highest priority. |
159
+ | `rootIndex` | int | Pick one of several MCP roots (0-based). |
160
+ | `format` | `"markdown"` \| `"json"` | Output format. Default: `"markdown"`. |
161
+
162
+ ### `batch_commit` — JSON shape (`format: "json"`)
163
+
164
+ ```json
165
+ {
166
+ "ok": true,
167
+ "committed": 2,
168
+ "total": 2,
169
+ "results": [{
170
+ "index": 0,
171
+ "ok": true,
172
+ "sha": "a1b2c3d",
173
+ "message": "feat: add foo",
174
+ "files": ["src/foo.ts"]
175
+ }, {
176
+ "index": 1,
177
+ "ok": true,
178
+ "sha": "b2c3d4e",
179
+ "message": "chore: update config",
180
+ "files": ["config.json"]
181
+ }],
182
+ "push": {
183
+ "ok": true,
184
+ "branch": "main",
185
+ "upstream": "origin/main"
186
+ }
187
+ }
188
+ ```
189
+
190
+ On first failure `ok` is `false`, `committed` reflects only the entries that succeeded before the error, and the failing entry includes `error` and `detail` fields. Remaining entries are skipped and not included in `results`.
191
+
192
+ The `push` object is present only when `push: "after"` was requested **and** every commit landed. On push failure the top-level `ok` stays `true` (the commits themselves succeeded) while `push.ok` is `false` and `push.error` carries the code.
193
+
194
+ ### `batch_commit` — error codes (per-result `error` field)
195
+
196
+ | Code | Meaning |
197
+ |------|---------|
198
+ | `path_escapes_repository` | One of the listed file paths resolves outside the git toplevel. |
199
+ | `stage_failed` | `git add` failed (e.g. untracked path or permission error). |
200
+ | `commit_failed` | `git commit` failed (e.g. nothing staged, hooks rejected). |
201
+ | `not_a_git_repository` | The resolved workspace root is not inside a git repository. |
202
+
203
+ ### `batch_commit` — push error codes (`push.error` field)
204
+
205
+ | Code | Meaning |
206
+ |------|---------|
207
+ | `push_detached_head` | HEAD is detached; no branch to push. |
208
+ | `push_no_upstream` | Current branch has no configured upstream. `batch_commit` will not auto-set one — do `git push -u origin <branch>` yourself (or re-run without `push`). |
209
+ | `push_failed` | `git push` exited non-zero (network error, non-fast-forward, hook rejection). `detail` carries the stderr/stdout from git. |
210
+
211
+ ---
212
+
213
+ ### `git_merge` — parameters
214
+
215
+ | Parameter | Type | Notes |
216
+ |-----------|------|-------|
217
+ | `sources` | `string[]` | Source branches to merge, in order. 1–20 entries. Each must be a valid git ref token. |
218
+ | `into` | string | Destination branch. Defaults to the currently checked-out branch. Rejected when HEAD is detached. |
219
+ | `strategy` | `"auto"` \| `"ff-only"` \| `"rebase"` \| `"merge"` | Default `"auto"`: cascade **fast-forward → rebase → merge-commit** per source. `"ff-only"` fails on divergence. `"rebase"` rebases source onto destination and fast-forwards; no merge-commit fallback. `"merge"` always creates a merge commit (`--no-ff`). |
220
+ | `message` | string | Merge commit message, used only when a merge commit is created. Defaults to `Merge branch '<source>' into <into>`. |
221
+ | `deleteMergedBranches` | boolean | Default `false`. After **all** sources land cleanly, delete each source branch locally (`git branch -d`). **Protected names always skipped** (main, master, dev, develop, stable, trunk, prod, production, `release/*`, `release-*`, `hotfix/*`, `hotfix-*`). Never touches remote refs. |
222
+ | `deleteMergedWorktrees` | boolean | Default `false`. After success, remove any local worktree currently checked out on a source branch (`git worktree remove`). Protected tails always skipped. |
223
+ | `workspaceRoot`, `rootIndex`, `format` | — | Standard workspace pick + output format. |
224
+
225
+ ### `git_merge` — JSON shape (`format: "json"`)
226
+
227
+ ```json
228
+ {
229
+ "ok": true,
230
+ "into": "main",
231
+ "strategy": "auto",
232
+ "headSha": "a1b2c3d4e5f6…",
233
+ "applied": 2,
234
+ "total": 2,
235
+ "results": [
236
+ {
237
+ "source": "feature/a",
238
+ "ok": true,
239
+ "outcome": "fast_forward",
240
+ "mergedSha": "a1b2c3d4e5f6…",
241
+ "branchDeleted": true,
242
+ "worktreeRemoved": "/tmp/agent-a"
243
+ },
244
+ {
245
+ "source": "feature/b",
246
+ "ok": true,
247
+ "outcome": "rebase_then_ff",
248
+ "mergedSha": "b2c3d4e5f6a1…"
249
+ }
250
+ ]
251
+ }
252
+ ```
253
+
254
+ **`outcome`** (per source): `fast_forward`, `rebase_then_ff`, `merge_commit`, `up_to_date`, or `conflicts`. Cleanup fields (`branchDeleted`, `worktreeRemoved`) are only emitted when the corresponding flag was set and the operation actually ran — both are omitted for up-to-date sources and are never populated on partial-failure runs.
255
+
256
+ On conflict: top-level `ok` is `false`, the conflicting entry has `ok: false` with `conflictStage` (`"rebase"` or `"merge"`), `conflictPaths` (array of paths with unresolved markers), and an `error` code. Remaining sources are not attempted.
257
+
258
+ ### `git_merge` — error codes
259
+
260
+ | Code | Meaning |
261
+ |------|---------|
262
+ | `unsafe_ref_token` | A source or `into` contains characters outside the argv-safe subset (spaces, shell meta, `..`, `@{`, leading `-`, trailing `.lock`). |
263
+ | `into_detached_head` | HEAD is detached and no `into` was given — the tool needs a concrete destination branch. |
264
+ | `working_tree_dirty` | Uncommitted changes present. Commit, stash, or discard before merging. |
265
+ | `checkout_failed` | Could not switch to `into`. `detail` carries git's stderr. |
266
+ | `destination_not_found` | `into` does not resolve to a commit. |
267
+ | `not_a_git_repository` | The resolved workspace root is not inside a git repository. |
268
+ | `source_not_found` (per source) | A source branch name does not resolve. |
269
+ | `cannot_fast_forward` (per source) | `strategy: "ff-only"` refused because branches have diverged. |
270
+ | `rebase_conflicts` (per source) | Rebase encountered conflicts. Repo state is cleaned before returning. |
271
+ | `merge_conflicts` (per source) | Merge commit encountered conflicts. Repo state is cleaned before returning. |
272
+ | `merge_failed` (per source) | `git merge --ff-only` failed unexpectedly. `detail` carries stderr. |
273
+ | `merge_base_failed` (per source) | `git merge-base` failed (usually unrelated histories). |
274
+
275
+ ---
276
+
277
+ ### `git_cherry_pick` — parameters
278
+
279
+ | Parameter | Type | Notes |
280
+ |-----------|------|-------|
281
+ | `sources` | `string[]` | Source specs. 1–50 entries. Each entry is one of: a full/short SHA, an `A..B` / `A...B` range, or a branch name. Branch names expand to `onto..<branch>` (oldest-first). |
282
+ | `onto` | string | Destination branch. Defaults to the currently checked-out branch. Rejected when HEAD is detached. |
283
+ | `deleteMergedBranches` | boolean | Default `false`. After all commits apply, delete each **branch-kind** source locally (`git branch -d`) when it is fully merged into the destination by SHA-reachability (not patch-equivalence). Protected names always skipped; never touches remote refs. |
284
+ | `deleteMergedWorktrees` | boolean | Default `false`. After success, remove any local worktree attached to a branch-kind source (`git worktree remove`). Protected tails always skipped. |
285
+ | `workspaceRoot`, `rootIndex`, `format` | — | Standard workspace pick + output format. |
286
+
287
+ ### `git_cherry_pick` — JSON shape (`format: "json"`)
288
+
289
+ ```json
290
+ {
291
+ "ok": true,
292
+ "onto": "main",
293
+ "headSha": "a1b2c3d…",
294
+ "picked": 3,
295
+ "applied": 2,
296
+ "results": [
297
+ { "source": "feature/a", "kind": "branch", "resolvedCommits": 2, "keptCommits": 2 },
298
+ { "source": "abcdef1", "kind": "sha", "resolvedCommits": 1, "keptCommits": 1 }
299
+ ]
300
+ }
301
+ ```
302
+
303
+ **`picked`** is the number of unique SHAs fed to `git cherry-pick` after SHA-reachability filtering. **`applied`** is the number of new commits actually added to HEAD — may be less than `picked` because the tool passes `--empty=drop` to git, so patch-equivalent commits are skipped at apply time without error.
304
+
305
+ **`kind`** is `"sha"`, `"range"`, or `"branch"`. **`resolvedCommits`** is how many commits the source expanded to; **`keptCommits`** is how many survived SHA-reachability dedupe. Cleanup fields (`branchDeleted`, `worktreeRemoved`) are only emitted for branch-kind sources when the corresponding flag was set and the operation succeeded.
306
+
307
+ On conflict, the response has `ok: false` and a top-level `conflict` object:
308
+
309
+ ```json
310
+ {
311
+ "ok": false,
312
+ "onto": "main",
313
+ "picked": 2,
314
+ "applied": 0,
315
+ "results": [ ... ],
316
+ "conflict": {
317
+ "stage": "cherry-pick",
318
+ "commit": "abcdef1",
319
+ "paths": ["src/foo.ts"],
320
+ "detail": "…git stderr…"
321
+ }
322
+ }
323
+ ```
324
+
325
+ Repo state is cleaned (`git cherry-pick --abort`) before returning — no partially-applied index.
326
+
327
+ ### `git_cherry_pick` — error codes
328
+
329
+ | Code | Meaning |
330
+ |------|---------|
331
+ | `unsafe_ref_token` | A source or `onto` contains characters outside the argv-safe subset. |
332
+ | `onto_detached_head` | HEAD is detached and no `onto` was given. |
333
+ | `working_tree_dirty` | Uncommitted changes present. Commit, stash, or discard before cherry-picking. |
334
+ | `checkout_failed` | Could not switch to `onto`. |
335
+ | `destination_not_found` | `onto` does not resolve to a commit. |
336
+ | `source_not_found` | A source spec resolves to neither a branch, a range, nor a commit. |
337
+ | `range_resolution_failed` | `git rev-list` failed to expand a range spec. |
338
+ | `not_a_git_repository` | The resolved workspace root is not inside a git repository. |
339
+
340
+ ---
341
+
46
342
  ## Resource
47
343
 
48
344
  | URI | Purpose |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rethunk/mcp-multi-root-git",
3
- "version": "2.0.1",
3
+ "version": "2.2.0",
4
4
  "description": "MCP stdio server: multi-root git status, inventory, and HEAD parity checks. Generic tools usable by any workspace.",
5
5
  "type": "module",
6
6
  "private": false,
@@ -14,6 +14,7 @@
14
14
  "docs/install.md",
15
15
  "docs/mcp-tools.md",
16
16
  "AGENTS.md",
17
+ "CHANGELOG.md",
17
18
  "HUMANS.md",
18
19
  "README.md",
19
20
  "LICENSE"
@@ -59,9 +60,9 @@
59
60
  "zod": "^4.3.6"
60
61
  },
61
62
  "devDependencies": {
62
- "@biomejs/biome": "^2.4.10",
63
- "@types/node": "^22.0.0",
64
- "rimraf": "^6.0.1",
63
+ "@biomejs/biome": "^2.4.11",
64
+ "@types/node": "^22.19.17",
65
+ "rimraf": "^6.1.3",
65
66
  "typescript": "^6.0.2"
66
67
  }
67
68
  }