feat: scaffold managed search subagents#833
Conversation
New command that calls the Entire search service to perform hybrid semantic + keyword search over checkpoints. Auth via GitHub token (GITHUB_TOKEN env var or `gh auth token`). Supports --json for agent consumption, --branch filtering, and --limit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Extract repeated test string to constant (goconst) - Suppress gosec G704 SSRF warning on trusted URL (gosec) - Handle tabwriter Flush error (gosec G104) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The search service now returns full checkpoint data (commit info, token usage, file stats, etc.) instead of just IDs and scores. Updated Result struct and display to use the new nested searchMeta and camelCase fields. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove TUI, tabwriter, and --json flag. Output is always JSON, making the command straightforward for agent and script consumption. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- TrimSpace on GITHUB_TOKEN env var to handle trailing newlines - Reject non-github.com remotes in ParseGitHubRemote with clear error - Add httptest-based tests for Search(): URL/query construction, auth header, branch/limit omission, JSON error handling, raw body error, and successful result parsing - truncateStr was already removed with the TUI deletion Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- entire login: GitHub OAuth device flow, stores token in .entire/auth.json - entire logout: removes stored credentials - entire auth-status: shows token source (file, env, or gh CLI) - Token resolution: .entire/auth.json → GITHUB_TOKEN → gh auth token - Search command uses new resolver instead of inline token logic Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removes GITHUB_TOKEN env var and gh CLI token fallbacks from ResolveGitHubToken so the CLI exclusively uses the token stored by 'entire login' (GitHub device flow). If no token is found, the user is directed to run 'entire login'. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Entire-Checkpoint: c175a1a3a7c5
- gosec: nolint OAuth endpoint URL (G101) and token field (G117) false positives - errcheck: explicit type assertion for error_description; handle readAuth errors in Set* funcs - nilnil: replace (nil, nil) with errNoAuth sentinel in readAuth - forbidigo: nolint os.Getwd() in authFilePath (walks up dirs, handles subdirectories) - perfsprint: errors.New for static strings, strconv.Itoa for int formatting Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The file manages a JSON file in .entire/auth.json, not a system keyring. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- auth_cmd.go: guard against panic on short tokens in auth-status masking - auth_cmd.go: use SetStoredAuth for atomic token+username write on login - auth_cmd.go: pass raw interval to WaitForAuthorization (floor moved to auth logic) - auth_cmd.go: call GetStoredToken directly, remove ResolveGitHubToken indirection - github_device.go: unexport pollForToken (internal implementation detail) - github_device.go: enforce 5s minimum polling interval inside WaitForAuthorization - resolve.go: remove ResolveGitHubToken wrapper, keep only SourceEntireDir constant - search_cmd.go: call GetStoredToken directly - search.go: use http.DefaultClient consistently (matches auth package) - store.go: replace deprecated os.IsNotExist with errors.Is(err, fs.ErrNotExist) - store.go: add SetStoredAuth for atomic single-write of token+username - store_test.go: add 5 tests covering walk-up, round-trip, no-file, atomic write, preservation - README.md: document device flow auth, remove GITHUB_TOKEN/--json references Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- store.go: unexport setStoredToken/setStoredUsername (dead external API) - store.go: move SourceEntireDir constant here, delete resolve.go - github_device.go: add io.LimitReader(1MB) to all three auth HTTP reads - README.md: add login/logout/auth-status to commands table and Authentication section Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- revive: rename 'real' variable to 'resolved' (shadows builtin) - usetesting: replace os.Chdir with t.Chdir (handles restore automatically) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Default to OS keyring (macOS Keychain, Linux Secret Service, Windows Credential Manager) via go-keyring. Fall back to .entire/auth.json when ENTIRE_TOKEN_STORE=file, matching the entiredb tokenstore pattern. - store.go: introduce tokenStore interface with keyringTokenStore and fileTokenStore implementations; sync.Once backend resolution - auth_cmd.go: use TokenSource() instead of hardcoded SourceEntireDir - store_test.go: TestMain forces file backend; resetBackend() between tests; add TestTokenSourceFileBackend Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- wrapcheck: nolint thin public wrappers over tokenStore interface - nolintlint: remove unused errcheck from TestMain nolint directive Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The CLI was calling /search/v1/{owner}/{repo} but the search worker
expects /search/v1/search with repo as a query parameter. Also updates
response types to match the worker's envelope format and removes the
unsupported --branch flag.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: b717aa3abf43
Replace raw JSON default output with an interactive TUI featuring: - Editable search bar (/ to focus, Enter to re-search) - Navigable results table (j/k or arrow keys) - Bordered detail card showing all checkpoint fields - --json flag preserves machine-readable output - Auto-JSON when piped, static table when ACCESSIBLE=1 - `entire search` with no args opens TUI with search bar focused Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 06f92d81abef
- Embed statusStyles in searchStyles, eliminating 6 duplicate fields - Remove redundant s() method, use inherited render() instead - Extract isTerminalWriter() to status_style.go for shared TTY detection - Remove unused height field and redundant zero-value cursor init - Use formatCommit() in detail card instead of inline duplication - Extract indentLines() helper to deduplicate line-indentation loops Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 1d48f1667fb4
- README: remove undocumented --branch flag, add --json and no-args usage - search.go: check Error field on HTTP 200, use dedicated http.Client instead of DefaultClient, remove unused Timing field - search_tui.go: remove phantom "enter select" from help bar - Tests: add TestSearch_ErrorFieldOn200, TestSearchModel_SearchModeEnter, TestSearchModel_SearchModeEnterEmpty; remove duplicate NavigationJK and tautological DerefStr tests Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: b30c1e2e013b
- Add --author and --date CLI flags for filtering search results - Support filter syntax in search bar: author:<name> date:<week|month> - Quoted values for multi-word filters: author:"Alice Smith" - Wildcard query (*) when only filters are provided - Pagination: 25 results per page, n/p or arrow keys to navigate - Alt-screen mode for full-terminal TUI - Filter hint shown below search bar in edit mode - Hide search command from --help (not GA yet) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 34f923edfe2a
…nation tests - Extract search.WildcardQuery constant for filter-only queries - Add Config.HasFilters() to centralize filter-awareness - Cache totalPages() in viewHelp to avoid redundant calls - Add tests for pagination: PageResults, TotalPages, SelectedResult, PageNavigation, and Config.HasFilters Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: d70c3fca57cf
Show username as the primary identifier in both the TUI table rows and
detail view, with the display name in parentheses (e.g. "dipree (Daniel
Adams)") instead of the previous format ("Daniel Adams (@dipree)").
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: b6453d19cf07
…ng in search - Add IsAccessibleMode() to no-query error guard so ACCESSIBLE=1 requires a query (matching --json behavior) instead of launching the TUI - Add Page field to search.Config and send page param to API, enabling lazy-fetch pagination in the TUI when navigating past loaded results - Use API total count for totalPages() so footer reflects true result count - Always reset Author/Date from parsed input on new interactive searches so startup filters don't persist invisibly across searches Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: ac93f036697d
The search API uses the limit param to cap total results fetched from the index, not just the page size. This means the page param alone doesn't enable pagination — total never exceeds limit. Work around this by requesting MaxLimit (200) in TUI mode so client-side pagination works with up to 8 pages of 25 results. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 1c0d807f956c
- Remove tautological TestNewSearchCmd_Flags (only checked cobra flags exist) - Rewrite TestSearchCmd_AccessibleModeRequiresQuery to verify exact error message through root.Execute() instead of accepting any error - Add tests for fetch-more error path, exhausted API capping total, "Loading more results..." view state, filter persistence to searchCfg, and apiPage initialization Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: b6c45b0e881f
…rminal panic Fixes from bugbot review: - Support ssh://git@github.com/owner/repo.git URL format in ParseGitHubRemote by using url.Parse for all scheme-based URLs - Strip quotes from date filter values (date:"week" → week) matching the existing behavior for author filters - Guard contentWidth with max(0) to prevent strings.Repeat panic on terminals narrower than 2 columns Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 193b538cd33e
CLI args like `entire search auth author:alice` were sending "auth author:alice" as the raw query instead of extracting the filter. Now runs ParseSearchInput on CLI args to extract inline filters, with --author/--date flags taking precedence. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 2da0d9d74b06
Support --branch flag, branch:name inline syntax in CLI args and TUI search bar, sent as branch query param to the search API. Included in HasFilters() so filter-only searches work. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 85fab7ef1506
The no-query + non-interactive error check ran after auth lookup, so in environments without credentials (CI) it would fail with "not authenticated" instead of the expected "query required" error. Move the check before auth/git operations since it only needs the parsed flags. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: d57341dbb0a2
…ng to search TUI - Wrap browse mode in a scrollable viewport with mouse wheel support - Add full-screen detail view (enter key) with viewport scrolling - Word-wrap long prompts in detail view - Truncate inline detail card to 15 lines with "enter for more" hint - Isolate search input mode (/ key) from results rendering - Show full response body in error messages instead of cryptic JSON parse errors - Add modeDetail with esc/backspace to return, / to search from any mode Co-Authored-By: Claude <noreply@anthropic.com> Entire-Checkpoint: c07dfe9d6805
- Add --page flag (1-based, default 1) and --limit (default 25) - JSON output includes total, page, total_pages, and limit metadata - All output modes now fetch MaxLimit (200) from API and paginate client-side, matching TUI behavior - Extract writeSearchJSON helper to keep maintainability index clean Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 923884bba18b
- Add --page flag with client-side pagination for JSON output - Fetch MaxLimit (200) results for all output modes, paginate locally - JSON output includes total, page, total_pages, limit metadata - Fix accessible table double-space separators to match computeColumns gap assumption (prevents 4-char terminal overflow) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 8f78632c349e
Entire-Checkpoint: 8f7b7819f5cc
Entire-Checkpoint: fd342fecde72
Entire-Checkpoint: 87df419289ee
There was a problem hiding this comment.
Pull request overview
Adds an entire search feature to the Entire CLI, including a Bubble Tea-powered interactive TUI, JSON output for automation/subagents, and automatic scaffolding of “managed search” subagent configs during setup.
Changes:
- Introduces a new
entire searchcommand with inline filters, pagination, JSON output, and an interactive TUI. - Adds scaffolding logic + tests to generate managed search subagent files for Claude, Codex, and Gemini during agent setup.
- Adds unit + integration tests covering search behavior, parsing, TUI state transitions, and subagent scaffolding.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| go.mod | Promotes Bubble Tea/Bubbles deps to direct requirements for the search TUI. |
| cmd/entire/cli/status_style.go | Refactors terminal detection into isTerminalWriter reused by search. |
| cmd/entire/cli/setup.go | Hooks setup now also scaffolds managed search subagents and reports scaffold status. |
| cmd/entire/cli/setup_subagents.go | Implements managed search subagent scaffolding + conflict handling + templates. |
| cmd/entire/cli/setup_subagents_test.go | Adds unit tests for create/update/idempotency/conflict behavior of scaffolding. |
| cmd/entire/cli/search/search.go | Implements search client, inline filter parsing, repo filter validation. |
| cmd/entire/cli/search/search_test.go | Adds unit tests for URL construction, errors, filters, parsing, validation. |
| cmd/entire/cli/search/github.go | Adds GitHub remote URL parsing helper for owner/repo inference. |
| cmd/entire/cli/search_tui.go | Adds Bubble Tea TUI (browse/search/detail), pagination, static accessible output. |
| cmd/entire/cli/search_tui_test.go | Adds extensive TUI model tests and formatting helper tests. |
| cmd/entire/cli/search_cmd.go | Adds new search Cobra command with auth + git remote detection + output modes. |
| cmd/entire/cli/search_cmd_test.go | Tests command help text and JSON pagination defaults / accessible behavior. |
| cmd/entire/cli/root.go | Registers the new search command. |
| cmd/entire/cli/integration_test/setup_gemini_hooks_test.go | Verifies Gemini enable scaffolds managed search subagent content. |
| cmd/entire/cli/integration_test/setup_codex_hooks_test.go | Adds integration smoke test for Codex hooks + managed search agent scaffold. |
| cmd/entire/cli/integration_test/setup_claude_hooks_test.go | Verifies Claude enable scaffolds managed search subagent content. |
| .claude/agents/search.md | Adds a committed managed search subagent file for Claude. |
| .codex/agents/search.toml | Adds a committed managed search subagent file for Codex. |
| .gemini/agents/search.md | Adds a committed managed search subagent file for Gemini. |
.claude/agents/search.md
Outdated
| --- | ||
| name: search | ||
| description: Search Entire checkpoint history and transcripts with `entire search`. Use proactively when the user asks about previous work, commits, sessions, prompts, or historical context in this repository. | ||
| tools: Bash | ||
| model: haiku | ||
| --- | ||
|
|
||
| <!-- ENTIRE-MANAGED SEARCH SUBAGENT v1 --> | ||
|
|
||
| You are the Entire search specialist for this repository. | ||
|
|
||
| Your only history-search mechanism is the `entire search` command. Do not fall back to `rg`, `grep`, `find`, `git log`, or ad hoc codebase browsing when the task is asking for historical search across Entire checkpoints and transcripts. |
There was a problem hiding this comment.
This committed Claude search subagent instructs using entire search and only “prefers” --json, which contradicts the PR’s requirement that managed search subagents must use entire search --json (and never run plain entire search, since it opens the TUI). Update this file’s description/instructions to require --json and explicitly forbid running without it, matching the scaffolded template used by setup.
.gemini/agents/search.md
Outdated
| --- | ||
| name: search | ||
| description: Search Entire checkpoint history and transcripts with `entire search`. Use proactively when the user asks about previous work, commits, sessions, prompts, or historical context in this repository. | ||
| kind: local | ||
| tools: | ||
| - run_shell_command | ||
| max_turns: 6 | ||
| timeout_mins: 5 | ||
| --- | ||
|
|
||
| <!-- ENTIRE-MANAGED SEARCH SUBAGENT v1 --> | ||
|
|
||
| You are the Entire search specialist for this repository. | ||
|
|
||
| Your only history-search mechanism is the `entire search` command. Do not fall back to `rg`, `grep`, `find`, `git log`, or ad hoc codebase browsing when the task is asking for historical search across Entire checkpoints and transcripts. | ||
|
|
||
| If `entire search` cannot run because authentication is missing, the repository is not set up correctly, or the command fails, stop and return a short prerequisite message. Do not make repo changes. |
There was a problem hiding this comment.
This committed Gemini search subagent still frames entire search (without --json) as the primary mechanism and only “prefers” JSON output. The PR description says managed search subagents must use entire search --json to avoid launching the interactive TUI; update this file to require --json and explicitly forbid plain entire search, consistent with the scaffolding template.
| # ENTIRE-MANAGED SEARCH SUBAGENT v1 | ||
| name = "search" | ||
| description = "Search Entire checkpoint history and transcripts with `entire search`. Use when the user asks about previous work, commits, sessions, prompts, or historical context in this repository." | ||
| sandbox_mode = "read-only" | ||
| model_reasoning_effort = "medium" | ||
| developer_instructions = """ | ||
| You are the Entire search specialist for this repository. | ||
|
|
||
| Your only history-search mechanism is the `entire search` command. Do not fall back to `rg`, `grep`, `find`, `git log`, or ad hoc codebase browsing when the task is asking for historical search across Entire checkpoints and transcripts. | ||
|
|
||
| If `entire search` cannot run because authentication is missing, the repository is not set up correctly, or the command fails, stop and return a short prerequisite message. Do not make repo changes. | ||
|
|
There was a problem hiding this comment.
This committed Codex search subagent describes entire search as the required mechanism and only “prefers” entire search --json. The PR intent is that managed subagents must always use entire search --json (never plain entire search, which opens the TUI). Update this file’s instructions accordingly so the checked-in managed agent matches the scaffolded template/behavior.
Committed subagent files (.claude, .gemini, .codex) said "prefer" --json but should require it to prevent launching the interactive TUI. Also add missing exhaustive switch cases in reportSearchSubagentScaffold. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 919b0ea21d83
Avoids name collisions with user-defined "search" subagents by using a namespaced identifier. Updates file names, template name fields, generated paths, and all unit/integration test expectations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: e2dbf2eabdd3
|
bugbot run |
Remove stale //nolint:unparam on setupAgentHooks (CI lint failure). Change setupAgentHooksNonInteractive error from "failed to install hooks" to "failed to setup hooks" since setupAgentHooks can also fail during search subagent scaffolding after hooks are already installed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 7d51fef6e8c9
|
bugbot run |
Summary
entire search --jsonso they do not open the interactive TUITest Plan
mise run test:ciNote
Medium Risk
Modifies the
entire enable/configuresetup path to write new agent files into repos, which could affect onboarding behavior and file overwrite semantics (though conflicts are explicitly avoided).Overview
Adds scaffolding of an Entire-managed
entire-searchsubagent when enabling hooks for Claude, Codex, or Gemini, with templates that explicitly requireentire search --json(to avoid opening the interactive TUI).Introduces
setup_subagents.goto create/update managed subagent files, skip overwriting user-owned files, and report status to the CLI output; wires this intosetupAgentHooksfor both interactive and--agentflows. Expands unit + integration coverage to assert the subagent files are generated and contain the required marker and--jsoninstructions.Written by Cursor Bugbot for commit a135fd3. Configure here.