Skip to content

feat(cli): expose 9 read-only graph tools as CLI subcommands#174

Merged
theagenticguy merged 1 commit into
mainfrom
fix/cli-wrappers-and-cochanges-harness
May 29, 2026
Merged

feat(cli): expose 9 read-only graph tools as CLI subcommands#174
theagenticguy merged 1 commit into
mainfrom
fix/cli-wrappers-and-cochanges-harness

Conversation

@theagenticguy
Copy link
Copy Markdown
Owner

Summary

Eight read-only graph capabilities were MCP-only with no codehub CLI subcommand, so a CLI- or CI-only user had to hand-parse SARIF / the graph to reach them (field-report Issue 3). This adds 9 subcommands that share the same underlying logic as their MCP-tool siblings, following the verdict CLI↔MCP shared-function pattern.

THIN (reuse an existing @opencodehub/analysis fn or IGraphStore/ITemporalStore reader)

findings, dead-code, license-audit, project-profile, risk-trends, dependencies.

EXTRACT (logic was inlined in the MCP handler — lifted verbatim into @opencodehub/analysis, then the MCP tool refactored to import it, so both surfaces share one impl)

  • ownersanalysis/owners.ts listOwners — slice-before-join + confidence-desc + .to ASC tiebreak preserved.
  • route-mapanalysis/route-map.ts listRouteMap — two-stage method handling + listRoutes limit:500 cap preserved.
  • api-impactanalysis/api-impact.ts listApiImpact (+ classifyShape/ShapeStatus relocated to analysis/shape.ts, re-exported so shape-check keeps working). Reuses the existing RiskLevel union — no second name added to the barrel. Known O(routes×files) re-fetch kept as-is so the MCP parity tests stay meaningful.

Each CLI command opens a read-only store via openStoreForCommand, exposes a storeFactory test seam (risk-trends uses a snapshotsFn seam since it reads .codehub/history, not the graph), branches on --json, and emits a plain table/JSON — not the MCP next_steps/staleness envelope. Registered with hyphenated names and non-variadic --repo, before parseAsync.

Also: fixes a pre-existing test failure on main

impact surfaces cochanges (tool-handlers.test.js) failed on clean main. Root cause: the fixture used node id F:foo (one colon), but looksLikeNodeId requires ≥2 colons (real OCH ids are Function:src/foo.ts:foo), so the target resolved as a name, never matched, and the cochanges side-section came back empty. The fixture now uses a realistic id. (Found while verifying Issue 4.)

Test plan

  • End-to-end against a live index: all 9 commands render correctly (findings, dead-code, license-audit, project-profile, dependencies, risk-trends, owners, route-map, api-impact); owners/route-map degrade gracefully where the repo has no such data.
  • MCP tools verified to delegate to the extracted lib fns (no duplicated logic); existing MCP tests stay green.
  • @opencodehub/analysis 128/128, @opencodehub/mcp 219/219, @opencodehub/cli 286/286 (+20 new CLI tests).
  • tsc --noEmit workspace clean; biome check clean on all 28 touched files.

Closes the last open item from the field report (Issues 1, 2, 4, 5, 6 + the Python import bugs already merged or in-flight).

…hanges test

Eight read-only graph capabilities were MCP-only with no `codehub` CLI
subcommand, so CLI/CI-only users couldn't reach them (field-report Issue 3).
Adds 9 subcommands sharing the SAME logic as their MCP siblings, following
the `verdict` CLI-MCP shared-function pattern.

THIN (reuse an existing @opencodehub/analysis fn or storage reader):
  findings, dead-code, license-audit, project-profile, risk-trends,
  dependencies.

EXTRACT (logic was inlined in the MCP handler with no analysis home — lifted
VERBATIM into @opencodehub/analysis, then the MCP tool refactored to import
it so both surfaces share one impl):
  - owners     -> analysis/owners.ts listOwners (slice-before-join preserved)
  - route-map  -> analysis/route-map.ts listRouteMap (two-stage method, 500 cap)
  - api-impact -> analysis/api-impact.ts listApiImpact (+ classifyShape moved to
                  analysis/shape.ts); reuses the existing RiskLevel union, no
                  second name added to the barrel.

Each CLI command opens a read-only store via openStoreForCommand, exposes a
storeFactory test seam (risk-trends uses a snapshotsFn seam since it reads
.codehub/history, not the graph), branches on --json, and emits a plain
table/JSON — NOT the MCP next_steps/staleness envelope. Registered with
hyphenated names and non-variadic --repo, before parseAsync.

Also fixes a pre-existing mcp test that failed on clean main: the "impact
surfaces cochanges" fixture used the node id `F:foo` (one colon), which
`looksLikeNodeId` rejects (real ids carry >=2 colons), so the target never
resolved and the cochanges side-section came back empty. Fixture now uses a
realistic `Function:src/foo.ts:foo` id.

Verified end-to-end against a live index: all 9 commands render correctly;
the MCP tools still delegate (no duplicated logic). analysis 128/128,
mcp 219/219, cli 286/286 (+20 new), tsc + biome clean.

Field-report Issue 3.
@theagenticguy theagenticguy enabled auto-merge (squash) May 29, 2026 22:49
@theagenticguy theagenticguy merged commit be15666 into main May 29, 2026
43 of 45 checks passed
@theagenticguy theagenticguy deleted the fix/cli-wrappers-and-cochanges-harness branch May 29, 2026 22:51
@github-actions github-actions Bot mentioned this pull request May 29, 2026
theagenticguy pushed a commit that referenced this pull request May 29, 2026
🤖 Automated release via release-please
---


<details><summary>analysis: 0.3.3</summary>

##
[0.3.3](analysis-v0.3.2...analysis-v0.3.3)
(2026-05-29)


### Features

* **cli:** expose 9 read-only graph tools as CLI subcommands
([#174](#174))
([be15666](be15666))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @opencodehub/storage bumped to 0.2.3
    * @opencodehub/wiki bumped to 0.2.3
</details>

<details><summary>cli: 0.5.6</summary>

##
[0.5.6](cli-v0.5.5...cli-v0.5.6)
(2026-05-29)


### Features

* **cli:** expose 9 read-only graph tools as CLI subcommands
([#174](#174))
([be15666](be15666))
* **cli:** status surfaces retrieval mode (summaries / vectors /
embedder)
([#172](#172))
([611e818](611e818))


### Bug Fixes

* **cli:** doctor verifies the bandit[sarif] formatter, not just the
binary ([#171](#171))
([0d78c92](0d78c92))
* **scanners:** exclude indexer-ignored dirs from vulture/radon/ty (drop
.venv noise)
([#168](#168))
([848aa34](848aa34))


### Documentation

* **repo:** clarify `sql` targets the temporal store, not the node/edge
graph ([#173](#173))
([814774a](814774a))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @opencodehub/analysis bumped to 0.3.3
    * @opencodehub/ingestion bumped to 0.4.5
    * @opencodehub/mcp bumped to 0.4.5
    * @opencodehub/pack bumped to 0.2.4
    * @opencodehub/scanners bumped to 0.2.3
    * @opencodehub/search bumped to 0.2.3
    * @opencodehub/storage bumped to 0.2.3
    * @opencodehub/wiki bumped to 0.2.3
</details>

<details><summary>cobol-proleap: 0.1.9</summary>

##
[0.1.9](cobol-proleap-v0.1.8...cobol-proleap-v0.1.9)
(2026-05-29)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @opencodehub/ingestion bumped to 0.4.5
</details>

<details><summary>ingestion: 0.4.5</summary>

##
[0.4.5](ingestion-v0.4.4...ingestion-v0.4.5)
(2026-05-29)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @opencodehub/analysis bumped to 0.3.3
    * @opencodehub/scip-ingest bumped to 0.2.5
    * @opencodehub/storage bumped to 0.2.3
</details>

<details><summary>mcp: 0.4.5</summary>

##
[0.4.5](mcp-v0.4.4...mcp-v0.4.5)
(2026-05-29)


### Features

* **cli:** expose 9 read-only graph tools as CLI subcommands
([#174](#174))
([be15666](be15666))


### Documentation

* **repo:** clarify `sql` targets the temporal store, not the node/edge
graph ([#173](#173))
([814774a](814774a))


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @opencodehub/analysis bumped to 0.3.3
    * @opencodehub/pack bumped to 0.2.4
    * @opencodehub/scanners bumped to 0.2.3
    * @opencodehub/search bumped to 0.2.3
    * @opencodehub/storage bumped to 0.2.3
</details>

<details><summary>pack: 0.2.4</summary>

##
[0.2.4](pack-v0.2.3...pack-v0.2.4)
(2026-05-29)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @opencodehub/analysis bumped to 0.3.3
    * @opencodehub/ingestion bumped to 0.4.5
    * @opencodehub/storage bumped to 0.2.3
</details>

<details><summary>scanners: 0.2.3</summary>

##
[0.2.3](scanners-v0.2.2...scanners-v0.2.3)
(2026-05-29)


### Bug Fixes

* **scanners:** exclude indexer-ignored dirs from vulture/radon/ty (drop
.venv noise)
([#168](#168))
([848aa34](848aa34))
</details>

<details><summary>scip-ingest: 0.2.5</summary>

##
[0.2.5](scip-ingest-v0.2.4...scip-ingest-v0.2.5)
(2026-05-29)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @opencodehub/analysis bumped to 0.3.3
</details>

<details><summary>search: 0.2.3</summary>

##
[0.2.3](search-v0.2.2...search-v0.2.3)
(2026-05-29)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @opencodehub/storage bumped to 0.2.3
</details>

<details><summary>storage: 0.2.3</summary>

##
[0.2.3](storage-v0.2.2...storage-v0.2.3)
(2026-05-29)


### Features

* **cli:** status surfaces retrieval mode (summaries / vectors /
embedder)
([#172](#172))
([611e818](611e818))
</details>

<details><summary>wiki: 0.2.3</summary>

##
[0.2.3](wiki-v0.2.2...wiki-v0.2.3)
(2026-05-29)


### Dependencies

* The following workspace dependencies were updated
  * dependencies
    * @opencodehub/storage bumped to 0.2.3
</details>

<details><summary>root: 0.6.7</summary>

##
[0.6.7](root-v0.6.6...root-v0.6.7)
(2026-05-29)


### Features

* **cli:** expose 9 read-only graph tools as CLI subcommands
([#174](#174))
([be15666](be15666))
* **cli:** status surfaces retrieval mode (summaries / vectors /
embedder)
([#172](#172))
([611e818](611e818))


### Bug Fixes

* **cli:** doctor verifies the bandit[sarif] formatter, not just the
binary ([#171](#171))
([0d78c92](0d78c92))
* **scanners:** exclude indexer-ignored dirs from vulture/radon/ty (drop
.venv noise)
([#168](#168))
([848aa34](848aa34))


### Documentation

* **repo:** clarify `sql` targets the temporal store, not the node/edge
graph ([#173](#173))
([814774a](814774a))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.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