Skip to content

feat(cli): pakx list, doctor, search#2

Merged
arwenizEr merged 1 commit into
mainfrom
feat/list-doctor-search
May 21, 2026
Merged

feat(cli): pakx list, doctor, search#2
arwenizEr merged 1 commit into
mainfrom
feat/list-doctor-search

Conversation

@arwenizEr
Copy link
Copy Markdown
Collaborator

Summary

Three new subcommands round out the v0.1 read-side of the CLI.

  • pakx list — read agents.lock, optionally cross-check against Adapter::list(), print [ok] / [drift] status per entry.
  • pakx doctor — 5-section health check: manifest parses → lockfile parses → manifest hash matches lockfile (drift) → adapter detection + agents: whitelist consistency → on-disk state vs lockfile.
  • pakx search <query> — fan out via RegistryClient and print source / name / version / description rows. Currently only the OfficialMcpSource is wired; Smithery / Glama / GitHub-raw land alongside pakx publish.

Plus: pakx-core::lockfile::io (read_from returns Option<Lockfile> so callers can distinguish missing vs corrupt; write_to writes the canonical form).

Test plan

  • cargo fmt --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • 3 new list tests (no lockfile, empty lockfile, entries)
  • 3 new doctor tests (no manifest, no lockfile, all-pass)
  • 3 new search tests with wiremock (results, query passthrough, empty)
  • CI test matrix green

🤖 Generated with Claude Code

- pakx-core: new lockfile::io with read_from (returns Option<Lockfile>
  so callers can distinguish missing vs corrupt) and write_to. Exported
  as read_lockfile_from / write_lockfile_to.
- pakx list [-C dir] [--no-check] [--claude-home DIR]: prints each
  lockfile entry. With cross-check enabled (default), tags entries with
  [ok] when adapter.list() confirms presence or [drift] otherwise.
- pakx doctor [-C dir] [--claude-home DIR]: 5-section health check —
  manifest, lockfile, manifest-hash drift, adapter detection vs
  agents: whitelist, on-disk vs lockfile drift. Exits non-zero on
  warn/fail.
- pakx search <query> [-n LIMIT] [--mcp-base-url URL]: fans out via
  RegistryClient (currently only OfficialMcpSource) and prints
  source / name / version / description rows.
- main.rs: wire all three new subcommands.
- Tests: 3 list, 3 doctor, 3 search integration tests with
  wiremock + temp tree. Workspace test count rises to ~117.

Smithery and GitHub-raw skill sources still pending — that wiring
will land alongside `pakx publish` in the SaaS-layer build.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@arwenizEr arwenizEr merged commit 04ef3e2 into main May 21, 2026
2 of 5 checks passed
arwenizEr added a commit that referenced this pull request May 21, 2026
Same-named query against two different registry deployments was
mapping to the same on-disk cache file, returning the stale earlier
response. Reproduced on ubuntu CI in the federated search test:
test #1 cached `acme/one`+`acme/two` for the OfficialMcpSource at
mock-url-A; test #2 set up mock-url-B serving different content, but
the empty-query cache key `official-mcp:search:` collided and the
later test read the earlier mock's body.

Cache key is now `{tag}@{base_url}:search:{query}` (and equivalent
for fetch). Different registries can no longer collide.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
arwenizEr added a commit that referenced this pull request May 21, 2026
* feat(registry-client): add Smithery source (search-only at v0.1)

- SmitherySource against registry.smithery.ai (configurable base URL,
  TTL-cached like OfficialMcpSource). Returns Package rows from
  /servers with qualifiedName as canonical id, displayName as name,
  description, and full extra JSON in install_hints.
- fetch() returns NotFound at v0.1 since Smithery's connection /
  config schema differs from the official MCP Registry's packages[]
  shape; install via Smithery lands in Phase A v2 once the
  translator grows a Smithery codepath.
- pakx search now defaults to fanning out to both OfficialMcp +
  Smithery (parallel via RegistryClient::search). Flags:
  --smithery-base-url URL (hidden, testing); --no-smithery (opt out).
- 5 new wiremock-backed source tests + 1 new end-to-end federated
  search test covering both sources.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(registry-client): include base URL in cache key

Same-named query against two different registry deployments was
mapping to the same on-disk cache file, returning the stale earlier
response. Reproduced on ubuntu CI in the federated search test:
test #1 cached `acme/one`+`acme/two` for the OfficialMcpSource at
mock-url-A; test #2 set up mock-url-B serving different content, but
the empty-query cache key `official-mcp:search:` collided and the
later test read the earlier mock's body.

Cache key is now `{tag}@{base_url}:search:{query}` (and equivalent
for fetch). Different registries can no longer collide.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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