feat: add 5 missing entire CLI tools (16 total) - #2
Conversation
RED — tools not yet registered/implemented: - entire_version, entire_status (misc.ts) - entire_search (search.ts) - entire_explain_commit, entire_explain_checkpoint (explain.ts)
…in_commit, explain_checkpoint Add tools identified by gap analysis against entireio/skills: - entire_version: verify CLI installation (explain skill prerequisite) - entire_status: get active session ID (session-handoff workflow core) - entire_search: stable `entire search` command with repo/branch/author/date filters - entire_explain_commit: retrieve transcript by git commit SHA - entire_explain_checkpoint: retrieve checkpoint transcript with default/full/raw modes Also fix eslint.config.js tsconfigRootDir for worktree isolation. Total tools: 11 → 16
📝 WalkthroughWalkthroughThe PR expands the Entire CLI MCP server with three new tool groups—explain, search, and extended misc tools—bringing the total from 11 to 16 registered tools. Implementation, Vitest suites, and integration are included alongside ESLint infrastructure upgrades and documentation updates reflecting the expanded toolset. ChangesEntire MCP Tool Expansion and Integration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Pull request overview
Adds the missing Entire CLI MCP wrappers to bring the server to 16 tools, including search, explain, version, and status workflows, while updating registration, tests, lint config, and contributor documentation.
Changes:
- Added new MCP tools for
entire search,entire explain,entire version, andentire status. - Registered the new tool groups in the server entrypoint.
- Added Vitest coverage and updated CLAUDE.md/tooling configuration.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
src/tools/search.ts |
Adds the entire_search MCP tool with optional filters. |
src/tools/explain.ts |
Adds commit and checkpoint transcript explain tools. |
src/tools/misc.ts |
Adds version and status tools to miscellaneous tooling. |
src/index.ts |
Registers the new explain and search tool groups. |
src/__tests__/tools/search.test.ts |
Covers search tool command construction and errors. |
src/__tests__/tools/explain.test.ts |
Covers explain tool modes and error handling. |
src/__tests__/tools/misc.test.ts |
Covers version and status tool behavior. |
eslint.config.js |
Anchors TypeScript ESLint config to the repo root and updates ignores. |
CLAUDE.md |
Updates tool counts, structure, and tool list documentation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/__tests__/tools/search.test.ts`:
- Around line 30-83: The tests currently use expect.arrayContaining which allows
out-of-order matches and doesn't verify the full command shape; update each test
(the ones calling registerSearchTools and server.callTool("entire_search", ...))
to assert the exact argv order passed to runEntire by constructing the full
expected command array (including "search", the query and any flags like
"--repo", "--branch", "--author", "--date" in the correct order) and replacing
expect.arrayContaining assertions with a strict equality check in the
toHaveBeenCalledWith call (e.g., pass the exact expectedArgs array as the first
arg and keep expect.any(Object) for the options) so the tests fail if argument
order or composition regresses.
In `@src/tools/explain.ts`:
- Around line 19-22: The schema currently allows empty strings for
commit/checkpoint IDs; update the Zod schemas to reject empty identifiers by
replacing z.string() for the commit field in inputSchema with
z.string().nonempty("commit must be a non-empty string") (or z.string().min(1,
...)) and do the same for the checkpoint-related field used later (the one
currently defined around lines 59-61) so both commit and checkpoint inputs are
validated as non-empty strings; leave RepoDirSchema as-is.
In `@src/tools/search.ts`:
- Around line 24-26: The inputSchema currently allows an empty string for the
"query" field; update the zod validator for query in inputSchema to reject
blank/whitespace-only values by adding trimming and a minimum length/non-empty
constraint (e.g., use z.string().trim().min(1) or
z.string().nonempty().transform/trim) so any "" or all-space input fails schema
validation before invoking a search.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: a330f276-0ab8-4068-9793-7701329f9394
📒 Files selected for processing (9)
CLAUDE.mdeslint.config.jssrc/__tests__/tools/explain.test.tssrc/__tests__/tools/misc.test.tssrc/__tests__/tools/search.test.tssrc/index.tssrc/tools/explain.tssrc/tools/misc.tssrc/tools/search.ts
| it("calls `entire search <query>` with query as first arg", async () => { | ||
| vi.mocked(runEntire).mockResolvedValueOnce({ stdout: "3 results\n", stderr: "" }); | ||
| const server = makeServer(); | ||
| registerSearchTools(server); | ||
| await server.callTool("entire_search", { query: "auth refactor" }); | ||
| expect(runEntire).toHaveBeenCalledWith( | ||
| expect.arrayContaining(["search", "auth refactor"]), | ||
| expect.any(Object) | ||
| ); | ||
| }); | ||
|
|
||
| it("appends --repo when provided", async () => { | ||
| vi.mocked(runEntire).mockResolvedValueOnce({ stdout: "1 result\n", stderr: "" }); | ||
| const server = makeServer(); | ||
| registerSearchTools(server); | ||
| await server.callTool("entire_search", { query: "login", repo: "jurislm/entire" }); | ||
| expect(runEntire).toHaveBeenCalledWith( | ||
| expect.arrayContaining(["--repo", "jurislm/entire"]), | ||
| expect.any(Object) | ||
| ); | ||
| }); | ||
|
|
||
| it("appends --branch when provided", async () => { | ||
| vi.mocked(runEntire).mockResolvedValueOnce({ stdout: "0 results\n", stderr: "" }); | ||
| const server = makeServer(); | ||
| registerSearchTools(server); | ||
| await server.callTool("entire_search", { query: "deploy", branch: "main" }); | ||
| expect(runEntire).toHaveBeenCalledWith( | ||
| expect.arrayContaining(["--branch", "main"]), | ||
| expect.any(Object) | ||
| ); | ||
| }); | ||
|
|
||
| it("appends --author when provided", async () => { | ||
| vi.mocked(runEntire).mockResolvedValueOnce({ stdout: "2 results\n", stderr: "" }); | ||
| const server = makeServer(); | ||
| registerSearchTools(server); | ||
| await server.callTool("entire_search", { query: "fix", author: "Terry" }); | ||
| expect(runEntire).toHaveBeenCalledWith( | ||
| expect.arrayContaining(["--author", "Terry"]), | ||
| expect.any(Object) | ||
| ); | ||
| }); | ||
|
|
||
| it("appends --date when provided", async () => { | ||
| vi.mocked(runEntire).mockResolvedValueOnce({ stdout: "1 result\n", stderr: "" }); | ||
| const server = makeServer(); | ||
| registerSearchTools(server); | ||
| await server.callTool("entire_search", { query: "refactor", date: "week" }); | ||
| expect(runEntire).toHaveBeenCalledWith( | ||
| expect.arrayContaining(["--date", "week"]), | ||
| expect.any(Object) | ||
| ); | ||
| }); |
There was a problem hiding this comment.
Tighten CLI-arg assertions to catch order regressions.
Line 35 and similar checks use arrayContaining, so they don’t actually guarantee the command shape/order your test names claim.
💡 Suggested fix
- expect(runEntire).toHaveBeenCalledWith(
- expect.arrayContaining(["search", "auth refactor"]),
- expect.any(Object)
- );
+ expect(runEntire).toHaveBeenCalledWith(
+ ["search", "auth refactor"],
+ expect.any(Object)
+ );- expect(runEntire).toHaveBeenCalledWith(
- expect.arrayContaining(["--repo", "jurislm/entire"]),
- expect.any(Object)
- );
+ expect(runEntire).toHaveBeenCalledWith(
+ ["search", "login", "--repo", "jurislm/entire"],
+ expect.any(Object)
+ );🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/__tests__/tools/search.test.ts` around lines 30 - 83, The tests currently
use expect.arrayContaining which allows out-of-order matches and doesn't verify
the full command shape; update each test (the ones calling registerSearchTools
and server.callTool("entire_search", ...)) to assert the exact argv order passed
to runEntire by constructing the full expected command array (including
"search", the query and any flags like "--repo", "--branch", "--author",
"--date" in the correct order) and replacing expect.arrayContaining assertions
with a strict equality check in the toHaveBeenCalledWith call (e.g., pass the
exact expectedArgs array as the first arg and keep expect.any(Object) for the
options) so the tests fail if argument order or composition regresses.
| inputSchema: z.object({ | ||
| commit: z.string().describe("Git commit SHA (full or short)"), | ||
| repo_dir: RepoDirSchema, | ||
| }), |
There was a problem hiding this comment.
Validate non-empty identifiers for commit/checkpoint inputs.
Line 20 and Line 60 currently allow empty strings; reject these at schema level instead of invoking the CLI with invalid IDs.
💡 Suggested fix
- commit: z.string().describe("Git commit SHA (full or short)"),
+ commit: z.string().trim().min(1, { error: "Commit SHA cannot be empty." }).describe("Git commit SHA (full or short)"),
@@
- checkpoint_id: z.string().describe("Checkpoint ID"),
+ checkpoint_id: z.string().trim().min(1, { error: "Checkpoint ID cannot be empty." }).describe("Checkpoint ID"),Also applies to: 59-61
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/tools/explain.ts` around lines 19 - 22, The schema currently allows empty
strings for commit/checkpoint IDs; update the Zod schemas to reject empty
identifiers by replacing z.string() for the commit field in inputSchema with
z.string().nonempty("commit must be a non-empty string") (or z.string().min(1,
...)) and do the same for the checkpoint-related field used later (the one
currently defined around lines 59-61) so both commit and checkpoint inputs are
validated as non-empty strings; leave RepoDirSchema as-is.
| inputSchema: z.object({ | ||
| query: z.string().describe("Search query (topic, feature name, error text, file name, etc.)"), | ||
| repo: z.string().optional().describe('Repository filter, e.g. "jurislm/entire" or "owner/*"'), |
There was a problem hiding this comment.
Reject empty search queries at schema level.
Line 25 currently accepts "", which can trigger an unintended search invocation. Add trim + min-length validation to fail fast.
💡 Suggested fix
- query: z.string().describe("Search query (topic, feature name, error text, file name, etc.)"),
+ query: z
+ .string()
+ .trim()
+ .min(1, { error: "Search query cannot be empty." })
+ .describe("Search query (topic, feature name, error text, file name, etc.)"),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| inputSchema: z.object({ | |
| query: z.string().describe("Search query (topic, feature name, error text, file name, etc.)"), | |
| repo: z.string().optional().describe('Repository filter, e.g. "jurislm/entire" or "owner/*"'), | |
| inputSchema: z.object({ | |
| query: z | |
| .string() | |
| .trim() | |
| .min(1, { message: "Search query cannot be empty." }) | |
| .describe("Search query (topic, feature name, error text, file name, etc.)"), | |
| repo: z.string().optional().describe('Repository filter, e.g. "jurislm/entire" or "owner/*"'), |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/tools/search.ts` around lines 24 - 26, The inputSchema currently allows
an empty string for the "query" field; update the zod validator for query in
inputSchema to reject blank/whitespace-only values by adding trimming and a
minimum length/non-empty constraint (e.g., use z.string().trim().min(1) or
z.string().nonempty().transform/trim) so any "" or all-space input fails schema
validation before invoking a search.
Bug fix: entire_search now always passes --json to avoid opening interactive TUI in non-interactive MCP subprocess (per entire-search agent spec). Also adds --limit and --page pagination params. New tools: - entire_session_current: active session JSON for current worktree (used by session-to-skill workflow) - entire_dispatch: generate recent agent work summary (cloud/local modes) - entire_activity: display activity overview and repo breakdown 37/37 tests pass, typecheck + lint + build clean.
Summary
entire_version— verify CLI installation (explain skill prerequisite)entire_status— get active session ID (session-handoff workflow core)entire_search— stableentire searchwith repo/branch/author/date filters (excludes unreliablecheckpoint search --json)entire_explain_commit— retrieve transcript by git commit SHA (entire explain --commit <SHA> --no-pager)entire_explain_checkpoint— checkpoint transcript with default/full/raw modeseslint.config.jstsconfigRootDir for worktree isolationTotal tools: 11 → 16. All 21 tests pass, typecheck + lint + build clean.
Test plan
bun run test— 21/21 passbun run typecheck— no errorsbun run lint— no warningsbun run build— dist/ generated🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Documentation
Tests
Chores