Skip to content

refactor(code-nav): consume codeIndexState, drop deprecated indexingStatus - #23

Merged
jlitola merged 2 commits into
mainfrom
refactor/code-index-state-migration
Apr 21, 2026
Merged

refactor(code-nav): consume codeIndexState, drop deprecated indexingStatus#23
jlitola merged 2 commits into
mainfrom
refactor/code-index-state-migration

Conversation

@jlitola

@jlitola jlitola commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Defensive swap from indexingStatus: IndexingStatus (backend-@deprecated) to codeIndexState: CodeIndexState across every code-navigation GraphQL result we read. Same shape as PR #22 (pkg deps typed fields): read the non-deprecated field while the legacy one is still served, so the CLI keeps working when the backend eventually removes it.

What changed on the wire

Before After
searchSymbols { … indexingStatus } searchSymbols { … codeIndexState }
listRepoFiles { … indexingStatus } listRepoFiles { … codeIndexState }
fetchCodeContext { … indexingStatus } fetchCodeContext { … codeIndexState }
grepRepoFile { … indexingStatus } grepRepoFile { … codeIndexState }

Enum mapping

IndexingStatus (old) CodeIndexState (new) Notes
INDEXED CURRENT Happy path — same semantics
STALE New: results served but a reindex is enqueued. We treat as happy-path, same as CURRENT.
INDEXING INDEXING Same string, same sentinel-promotion logic
PENDING PENDING Unchanged
FAILED FAILED Unchanged
NOT_FOUND NOT_FOUND Unchanged
UNRESOLVABLE UNRESOLVABLE Same string, same sentinel check

The CLI's two string checks (`=== "INDEXING"` and `=== "UNRESOLVABLE"`) fire on identical values in both enums — no behavioural change.

Scope

  • 4 Zod schemas renamed.
  • 4 GraphQL queries select `codeIndexState` instead of `indexingStatus`.
  • `throwIfIndexing` helper's input-type field renamed; two inline sentinel reads in `searchSymbols` mapping renamed.
  • Test fixtures migrated:
    • `indexingStatus: "INDEXED"` → `codeIndexState: "CURRENT"` (18 fixtures)
    • `indexingStatus: "INDEXING"` → `codeIndexState: "INDEXING"` (5 fixtures)
  • Two response-builder doc comments updated to reference the new field.

No envelope shape change. `codeIndexState` is consumed internally — never surfaced on any tool's envelope. `STALE` flows through identically to `CURRENT` today; future UX work could surface an "index being refreshed" note under `--verbose`, but that's a separate ticket.

Testing

  • 1326 tests pass (`bun test`).
  • Typecheck / lint / build clean.

Live-smoke (production pkgseer)

All four indexing-gated tools verified on `npm:express`:

  • `code files npm:express lib --limit 3` — resolves paths, `CURRENT` flows as happy-path.
  • `code read npm:express lib/express.js --lines 1-3` — returns bytes.
  • `code grep npm:express middleware lib/express.js` — returns matches.
  • `code search npm:express Router --json --wait 30` — `INDEXING` → retry promotes to typed error as before; resolves on second attempt with 2 results.

Test plan

  • `bun test` passes (1326 / 0)
  • `bun run typecheck` / `bun run build` / `bun run lint` clean
  • Live-smoke every indexing-gated tool against production pkgseer
  • No remaining references to `indexingStatus` in consumed code (grep-clean)

🤖 Generated with Claude Code

jlitola added 2 commits April 21, 2026 19:23
…tatus

The backend deprecated `indexingStatus: IndexingStatus` in favour of
`codeIndexState: CodeIndexState` across every code-navigation result
type (searchSymbols, listRepoFiles, fetchCodeContext, grepRepoFile,
plus several we don't consume). Legacy field still served. Defensive
migration ahead of removal, same shape as the `pkg deps` typed-field
swap in PR #22.

The enums are near-identical on the wire:

- `INDEXED` → `CURRENT` (same happy-path semantics).
- `INDEXED` → `STALE` is a new lifecycle state — results were served
  but the navpack is older than VersionManifest and a reindex is
  enqueued. We treat it as happy-path, same as `CURRENT` / legacy
  `INDEXED`.
- `INDEXING` / `PENDING` / `FAILED` / `NOT_FOUND` / `UNRESOLVABLE`
  values are unchanged.

Our sentinel checks (`=== "INDEXING"` and `=== "UNRESOLVABLE"`)
continue to fire on the same string values; string comparison
logic is unchanged.

Changes:

- All four GraphQL queries select `codeIndexState` instead of
  `indexingStatus`. Zod schemas renamed accordingly.
- `throwIfIndexing` helper and `searchSymbols` inline sentinel swap
  to reading `codeIndexState`. All consumers still gated on the
  same values.
- Test fixtures migrate from `indexingStatus: "INDEXED"` →
  `codeIndexState: "CURRENT"`; `indexingStatus: "INDEXING"` →
  `codeIndexState: "INDEXING"`.
- Doc comments on the response-builder modules updated to
  reference the new field name.

No envelope shape change. `codeIndexState` is consumed internally
only — never surfaced on the `list_files` / `read_file` /
`grep_file` / `search_symbols` envelopes. `STALE` results served
today flow through identically (we never branched on the absence
of a staleness indicator); future UX work could surface an
"index being refreshed" note in verbose mode, but that's out of
scope.

Live-smoke: all four indexing-gated tools (`code files`, `code read`,
`code grep`, `code search`) verified against production pkgseer on
`npm:express`. CURRENT state rendered as happy-path; INDEXING
retry (`code search … --wait 30`) still promotes to the typed
error and resolves on retry.
…ndexState

Follows the field rename landed in this PR's main commit. The
tools.md paragraph described the success-sentinel shape as
`indexingStatus`; updated to `codeIndexState: "INDEXING"`
to match what the service layer actually reads off the wire now.
@jlitola
jlitola merged commit 8bf5cd2 into main Apr 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant