Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/analysis-route-small-fixes-bundle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gitsema": minor
---

Phase 143: closed a grab-bag of small HTTP/CLI flag-parity gaps across `src/server/routes/analysis.ts`. `POST /analysis/merge-audit` gained `base` (merge-base override); `POST /analysis/merge-preview` gained `top`/`iterations`/`edgeThreshold`/`enhancedKeywordsN`/`useEnhancedLabels`; `POST /analysis/branch-summary` gained `enhancedLabels`/`enhancedKeywordsN` (slices `nearestConcepts[].topKeywords` in the JSON response); `POST /analysis/clusters` gained `iterations`/`edgeThreshold`/`enhancedKeywordsN`; `POST /analysis/security-scan` gained `highConfidenceOnly`; `POST /analysis/impact` gained `chunks`/`level`/`lens` (`structural`/`hybrid` now makes it a thin `blast-radius` alias, closing a prior silent divergence from the CLI's default); `POST /analysis/semantic-diff` gained `hybrid`/`bm25Weight` (also fixing a pre-existing CLI bug where `diff`'s `--hybrid`/`--bm25-weight` flags were declared but never wired to anything); `POST /analysis/semantic-blame` gained `level` (file/symbol).
5 changes: 5 additions & 0 deletions .changeset/graph-family-http-mcp-exposure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gitsema": minor
---

The `graph` command family (`callers`, `callees`, `neighbors`, `path`, `relate`, `similar`, `unused`, `cycles`, `deps`, `co-change`, `blast-radius`) is now exposed over HTTP (`POST /api/v1/graph/*`) and MCP (`graph_path`, `graph_relate`, `graph_similar`, `graph_unused`, `cycles`, `deps`, `co_change`, `blast_radius` tools; `callers`/`callees` gained HTTP routes and reuse the existing `call_graph` MCP tool), matching the CLI's existing flag surface. `graph build` remains CLI-only — it's a mutating, truncate-and-rebuild index-maintenance operation, not a query, consistent with `index vacuum`/`gc`/`rebuild-fts`/etc.
5 changes: 5 additions & 0 deletions .changeset/guide-http-route-lens.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gitsema": minor
---

`POST /api/v1/guide/chat` (HTTP API) now accepts a `lens: 'semantic'|'structural'|'hybrid'` field, mirroring CLI `gitsema guide --lens` — under `structural`/`hybrid` it biases the guide agent's tool choice toward `call_graph`/`blast_radius`/`hotspots`, identically to the CLI. Remote multi-turn/session support (an HTTP equivalent of CLI `guide --interactive`) remains a deferred, unresolved design question — see `docs/feature-ideas.md`.
5 changes: 5 additions & 0 deletions .changeset/narrate-explain-http-parity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gitsema": minor
---

`POST /narrate` and `POST /explain` now accept an `evidenceOnly` field, letting HTTP callers explicitly request the same safe-by-default evidence-only mode as the CLI's `narrate`/`explain` (omitted = evidence-only, no LLM call) — both responses also gain a structured `evidence` array. `POST /explain` additionally accepts `log` (error/stack-trace context file) and `files` (search-scope glob), and both routes accept `lens`, which on `/explain` returns a `structuralContext` field (call-graph/co-change enrichment) when combined with a concrete `files` path under a `structural`/`hybrid` lens.
5 changes: 5 additions & 0 deletions .changeset/phase-148-insights-mcp-http-parity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gitsema": minor
---

`bisect`, `refactor-candidates`, `lifecycle`, `cherry-pick-suggest`, `file-diff`, `pr-report`, `regression-gate`, `code-review`, `map`, and `heatmap` are now available as MCP tools and `POST /api/v1/insights/*` HTTP routes, not just CLI commands — AI clients and remote callers can now reach them directly. Also fixes a pre-existing bug in `refactor-candidates`' default symbol-level scan that made it error out on any index with symbol embeddings.
5 changes: 5 additions & 0 deletions .changeset/watch-list-remove-http-routes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gitsema": minor
---

The HTTP API now exposes `GET /watch` (list saved watch queries) and `DELETE /watch/:name` (remove one by name), matching the CLI's `watch list`/`watch remove` — previously only `watch add`/`watch run` had HTTP routes.
5 changes: 5 additions & 0 deletions .changeset/workflow-http-route-parity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"gitsema": minor
---

The HTTP `POST /analysis/workflow` route now supports all 8 productized workflow templates that CLI `workflow run` has (`pr-review`, `incident`, `release-audit`, `onboarding`, `ownership-intel`, `arch-drift`, `knowledge-portal`, `regression-forecast`) instead of just 3, and accepts `role`/`ref` body fields (mirroring CLI `--role`/`--ref`) generally rather than gated to a single template.
24 changes: 21 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -400,8 +400,8 @@ git repo
[ src/core/models/ ] types.ts — shared embedding/result type definitions
[ src/cli/ ] program.ts (COMMAND_GROUPS) + register/*.ts + commands/*.ts — Commander.js CLI
[ src/mcp/ ] server.ts + tools/{search,analysis,clustering,graph,infrastructure,workflow,narrator}.ts — MCP stdio server
[ src/server/ ] app.ts + routes/{search,analysis,evolution,graph,guide,narrator,blobs,commits,projections,remote,status,watch}.ts — HTTP API server (remote backend)
[ src/mcp/ ] server.ts + tools/{search,analysis,clustering,graph,infrastructure,workflow,narrator,insights}.ts — MCP stdio server
[ src/server/ ] app.ts + routes/{search,analysis,insights,evolution,graph,guide,narrator,blobs,commits,projections,remote,status,watch}.ts — HTTP API server (remote backend)
[ src/client/ ] remoteClient.ts — client for remote server mode
```

Expand Down Expand Up @@ -567,7 +567,7 @@ node dist/cli/index.js tools mcp

The MCP server reads the same environment variables as the CLI. It runs against the `.gitsema/index.db` in the current working directory when the server is started.

**Exposed tools (38 total, registered across `src/mcp/tools/{search,analysis,clustering,infrastructure,workflow,narrator,graph}.ts`):**
**Exposed tools (56 total, registered across `src/mcp/tools/{search,analysis,clustering,infrastructure,workflow,narrator,graph,insights}.ts`):**

| Tool | Description |
|---|---|
Expand Down Expand Up @@ -608,7 +608,25 @@ The MCP server reads the same environment variables as the CLI. It runs against
| `call_graph` | Structural call-graph traversal — callers/callees of a symbol (Phase 108) |
| `graph_neighbors` | Typed neighborhood of a graph node — any edge kinds, direction, depth (Phase 108) |
| `hotspots` | Architectural risk = co-change × call-coupling × churn; `lens` selects which signals (Phase 110) |
| `graph_path` | Shortest typed path between two graph nodes (Phase 108/147) |
| `graph_relate` | Structural callers/callees + semantically similar blobs/symbols for a node (Phase 109/147) |
| `graph_similar` | Structural (Jaccard shape) + semantic similarity to a node (Phase 109/147) |
| `graph_unused` | Symbols/files with no inbound calls/imports edges (Phase 109/147) |
| `cycles` | Cycle detection over typed edges, default `imports` (Phase 107/147) |
| `deps` | Dependency/dependent closure over imports/calls/extends/implements edges (Phase 107/147) |
| `co_change` | Files that historically change together with a path (Phase 107/147) |
| `blast_radius` | Structural dependents + semantic neighbors — "what breaks if I touch this" (Phase 109/147) |
| `get_skill` | Return the gitsema agent skill (usage + result-interpretation guidance for every tool) — MCP-only, so clients can ground tool usage |
| `semantic_bisect` | Binary search over commit history to find where a concept diverged from a "good" baseline (Phase 148) |
| `refactor_candidates` | Find pairs of symbols/chunks/files similar enough to be refactoring candidates (Phase 148) |
| `concept_lifecycle` | Lifecycle stages (born → growing → mature → declining → dead) of a concept over history (Phase 148) |
| `cherry_pick_suggest` | Suggest commits to cherry-pick by semantic similarity of commit messages (Phase 148) |
| `file_diff` | Semantic diff (cosine distance) between two versions of a single file (Phase 148) |
| `pr_report` | Composite PR report: semantic diff, impacted modules, change-points, reviewer suggestions (Phase 148) |
| `regression_gate` | CI gate: per-query base/head drift check against a threshold (Phase 148) |
| `code_review` | Historical analogues + regression-risk heuristic for a unified diff (Phase 148) |
| `activity_heatmap` | Count of distinct blob changes per time period, week or month (Phase 148) |
| `semantic_map` | Most recent k-means cluster snapshot + per-cluster blob-assignment counts (Phase 148) |

---

Expand Down
31 changes: 17 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,9 @@ Both commands are **safe-by-default**: with no narrator model configured (or wit
| `--until <ref\|date>` | — | Only include commits before this ref or date |
| `--range <rev-range>` | — | Git revision range (e.g. `v1.0..HEAD`) (`narrate` only) |
| `--focus <area>` | `all` | Filter commits by area: `bugs`, `features`, `ops`, `security`, `deps`, `performance`, `all` (`narrate` only) |
| `--log <path>` | — | Path to an error log/stack-trace file to include as LLM context (`explain` only) |
| `--files <glob>` | — | Restrict search to files matching this glob (`explain` only); currently only consumed by `--lens` structural enrichment, not commit filtering (see below) |
| `--lens <lens>` | `semantic` | `semantic\|structural\|hybrid` (`explain` only) — under `structural`/`hybrid` with a concrete `--files` path, appends grounded call-graph/co-change context after the result |
| `--format <fmt>` | `md` | Output format when narrating: `md`, `text`, `json` (legacy: prefer `--out`) |
| `--out <spec>` | — | Output spec (repeatable): `text\|json[:file]\|markdown[:file]` (overrides `--format`) |
| `--max-commits <n>` | `500` | Maximum commits to analyse (`narrate` only) |
Expand Down Expand Up @@ -550,18 +553,18 @@ Track semantic drift of a single file across its Git history.

| Command | Description |
|---|---|
| `gitsema graph build` | Build/rebuild `graph_nodes` and `edges` from `structural_refs`, `symbols`, and `blob_commits` (truncate-and-rebuild; requires prior `gitsema index --graph`) |
| `gitsema co-change <path> [-k/--top <n>]` | Files that historically change together with `<path>` |
| `gitsema deps <identifier> [--reverse] [--depth <n>] [--edge-types <types>]` | Import/dependency closure of a file or symbol (default edge types: `imports,calls,extends,implements`) |
| `gitsema graph cycles [--edge-types <types>]` / `gitsema cycles [--edge-types <types>]` | Detect cycles in the structural graph (default: `imports`) |
| `gitsema graph callers <symbol> [--depth <n>]` | Reverse `calls` traversal — who (transitively) calls `<symbol>` (default depth 3, max 3) |
| `gitsema graph callees <symbol> [--depth <n>]` | Forward `calls` traversal — what `<symbol>` (transitively) calls (default depth 3, max 3) |
| `gitsema graph neighbors <node> [--edge-types <types>] [--direction <dir>] [--depth <n>] [--out <spec>]` | Typed neighborhood of `<node>` — any edge kinds by default (default depth 1, max 3) |
| `gitsema graph path <a> <b> [--out <spec>]` | Shortest typed path from `<a>` to `<b>` (max depth 3) |
| `gitsema blast-radius <symbol> [--lens <lens>] [--depth <n>] [-k/--top <n>] [--weight-structural <n>] [--out <spec>]` | What changes if I touch this — structural dependents (`calls`/`imports`/`extends`/`implements`/`references`, reverse traversal) and/or semantically similar blobs (default lens: hybrid) |
| `gitsema relate <symbol> [--lens <lens>] [-k/--top <n>] [--out <spec>]` | Callers/callees (structural, depth 1) and semantically similar blobs, labeled — both lenses, lose neither (default lens: hybrid) |
| `gitsema similar <symbol> [--lens <lens>] [-k/--top <n>] [--weight-structural <n>] [--out <spec>]` | Symbols/files with a similar call/import shape (structural, Jaccard overlap) and/or semantically similar (vector) (default lens: hybrid) |
| `gitsema unused [--edge-types <types>]` | Symbols/files with no inbound `calls`/`imports` edges — structural complement to `dead-concepts` |
| `gitsema graph build` | Build/rebuild `graph_nodes` and `edges` from `structural_refs`, `symbols`, and `blob_commits` (truncate-and-rebuild; requires prior `gitsema index --graph`). CLI-only — a mutating index-maintenance operation, not exposed over HTTP/MCP (Phase 147), same as `index vacuum`/`gc`/etc |
| `gitsema co-change <path> [-k/--top <n>]` | Files that historically change together with `<path>`. Also `POST /api/v1/graph/co-change` and MCP `co_change` |
| `gitsema deps <identifier> [--reverse] [--depth <n>] [--edge-types <types>]` | Import/dependency closure of a file or symbol (default edge types: `imports,calls,extends,implements`). Also `POST /api/v1/graph/deps` and MCP `deps` |
| `gitsema graph cycles [--edge-types <types>]` / `gitsema cycles [--edge-types <types>]` | Detect cycles in the structural graph (default: `imports`). Also `POST /api/v1/graph/cycles` and MCP `cycles` |
| `gitsema graph callers <symbol> [--depth <n>]` | Reverse `calls` traversal — who (transitively) calls `<symbol>` (default depth 3, max 3). Also `POST /api/v1/graph/callers` and MCP `call_graph` (`direction: callers`) |
| `gitsema graph callees <symbol> [--depth <n>]` | Forward `calls` traversal — what `<symbol>` (transitively) calls (default depth 3, max 3). Also `POST /api/v1/graph/callees` and MCP `call_graph` (`direction: callees`) |
| `gitsema graph neighbors <node> [--edge-types <types>] [--direction <dir>] [--depth <n>] [--out <spec>]` | Typed neighborhood of `<node>` — any edge kinds by default (default depth 1, max 3). Also `POST /api/v1/graph/neighbors` and MCP `graph_neighbors` |
| `gitsema graph path <a> <b> [--out <spec>]` | Shortest typed path from `<a>` to `<b>` (max depth 3). Also `POST /api/v1/graph/path` and MCP `graph_path` |
| `gitsema blast-radius <symbol> [--lens <lens>] [--depth <n>] [-k/--top <n>] [--weight-structural <n>] [--out <spec>]` | What changes if I touch this — structural dependents (`calls`/`imports`/`extends`/`implements`/`references`, reverse traversal) and/or semantically similar blobs (default lens: hybrid). Also `POST /api/v1/graph/blast-radius` and MCP `blast_radius` |
| `gitsema relate <symbol> [--lens <lens>] [-k/--top <n>] [--out <spec>]` | Callers/callees (structural, depth 1) and semantically similar blobs, labeled — both lenses, lose neither (default lens: hybrid). Also `POST /api/v1/graph/relate` and MCP `graph_relate` |
| `gitsema similar <symbol> [--lens <lens>] [-k/--top <n>] [--weight-structural <n>] [--out <spec>]` | Symbols/files with a similar call/import shape (structural, Jaccard overlap) and/or semantically similar (vector) (default lens: hybrid). Also `POST /api/v1/graph/similar` and MCP `graph_similar` |
| `gitsema unused [--edge-types <types>]` | Symbols/files with no inbound `calls`/`imports` edges — structural complement to `dead-concepts`. Also `POST /api/v1/graph/unused` and MCP `graph_unused` |
| `gitsema hotspots [--lens <lens>] [-k/--top <n>] [--out <spec>]` | Architectural risk = co-change (temporal) × call-coupling (structural) × churn — geometric mean of the signals the lens selects (default lens: hybrid). Also `POST /api/v1/graph/hotspots` and MCP `hotspots` |

`--out <spec>` on the six commands above (repeatable: `text\|json[:file]\|html[:file]\|markdown[:file]`) renders a unified subgraph view: `html` is an interactive force-graph with clickable nodes (Phase 112), `text`/`markdown` are an ASCII tree / nested bullet list. Omitting `--out` leaves each command's own default text output unchanged.
Expand All @@ -571,7 +574,7 @@ Track semantic drift of a single file across its Git history.
| Command | Description |
|---|---|
| `gitsema repos` | Manage tracked repositories for multi-repo indexing |
| `gitsema watch` | Manage saved searches and watch mode notifications |
| `gitsema watch add/list/remove/run` | Manage saved searches and watch mode notifications. Also `POST /api/v1/watch/add`, `GET /api/v1/watch`, `DELETE /api/v1/watch/:name`, `POST /api/v1/watch/run` |
| `gitsema pr-report [options]` | Compose a semantic PR report: diff, impacted modules, change-points, reviewer suggestions |
| `gitsema regression-gate [options]` | CI gate: fail if key concepts drift beyond threshold between two refs |
| `gitsema bisect <good> <bad> <query>` | Semantic git bisect — binary search to find where a concept diverged from a "good" baseline |
Expand All @@ -586,7 +589,7 @@ Track semantic drift of a single file across its Git history.
| Command | Description |
|---|---|
| `gitsema workflow list` | List available productized workflow templates |
| `gitsema workflow run <name>` | Run a named workflow template (`pr-review` \| `incident` \| `release-audit`) |
| `gitsema workflow run <name>` | Run a named workflow template (`pr-review` \| `incident` \| `release-audit` \| `onboarding` \| `ownership-intel` \| `arch-drift` \| `knowledge-portal` \| `regression-forecast`). Flags: `--file`, `--query`, `--role` (onboarding topic, alias for `--query`), `--ref` (regression-forecast base ref), `--base` (declared for pr-review, currently a no-op), `--top`, `--format`/`--dump`/`--out` |

### Repo Insights

Expand Down
Loading
Loading