Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .claude/agents/code-analyst.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: code-analyst
description: Use when the user asks to understand code structure, impact of changes, find owners, audit dependencies, or navigate the codebase graph. Specializes in the OpenCodeHub MCP toolkit and always grounds claims in graph queries rather than text search.
tools: mcp__opencodehub__query, mcp__opencodehub__context, mcp__opencodehub__impact, mcp__opencodehub__route_map, mcp__opencodehub__api_impact, mcp__opencodehub__shape_check, mcp__opencodehub__tool_map, mcp__opencodehub__verdict, mcp__opencodehub__owners, mcp__opencodehub__license_audit, mcp__opencodehub__list_findings, mcp__opencodehub__list_findings_delta, mcp__opencodehub__list_dead_code, mcp__opencodehub__signature, mcp__opencodehub__detect_changes, Read, Grep, Glob
tools: mcp__codehub__query, mcp__codehub__context, mcp__codehub__impact, mcp__codehub__route_map, mcp__codehub__api_impact, mcp__codehub__shape_check, mcp__codehub__tool_map, mcp__codehub__verdict, mcp__codehub__owners, mcp__codehub__license_audit, mcp__codehub__list_findings, mcp__codehub__list_findings_delta, mcp__codehub__list_dead_code, mcp__codehub__signature, mcp__codehub__detect_changes, Read, Grep, Glob
model: sonnet
---

Expand Down
18 changes: 9 additions & 9 deletions .claude/skills/codehub-contract-map/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: codehub-contract-map
description: "Use when the user asks for a cross-repo contract map, an API-consumer matrix, or a service-interaction diagram across a repo group. Examples: \"map the HTTP contracts between services\", \"which services call the billing API\", \"show the contract matrix for the platform group\". GROUP MODE ONLY — requires a named group. DO NOT use on a single repo (use `codehub-document` with `reference/public-api.md`). DO NOT use if `mcp__opencodehub__group_list` does not include the group."
allowed-tools: "Read, Write, mcp__opencodehub__group_list, mcp__opencodehub__group_status, mcp__opencodehub__group_contracts, mcp__opencodehub__group_query, mcp__opencodehub__route_map, mcp__opencodehub__list_repos"
description: "Use when the user asks for a cross-repo contract map, an API-consumer matrix, or a service-interaction diagram across a repo group. Examples: \"map the HTTP contracts between services\", \"which services call the billing API\", \"show the contract matrix for the platform group\". GROUP MODE ONLY — requires a named group. DO NOT use on a single repo (use `codehub-document` with `reference/public-api.md`). DO NOT use if `mcp__codehub__group_list` does not include the group."
allowed-tools: "Read, Write, mcp__codehub__group_list, mcp__codehub__group_status, mcp__codehub__group_contracts, mcp__codehub__group_query, mcp__codehub__route_map, mcp__codehub__list_repos"
argument-hint: "<group-name> [--output <path>] [--committed]"
color: magenta
model: sonnet
Expand All @@ -13,9 +13,9 @@ Standalone group-only skill. Renders `group_contracts` into a Markdown + Mermaid

## Preconditions

1. A `<group-name>` positional argument is required. If missing or if `mcp__opencodehub__group_list` does not return the name, refuse with:
1. A `<group-name>` positional argument is required. If missing or if `mcp__codehub__group_list` does not return the name, refuse with:
`Contract map requires a named group — run 'codehub group list' to see registered groups.` (Spec 001 AC-3-4.)
2. `mcp__opencodehub__group_status({group})` must return `fresh: true` for every member. If any member is stale, abort and name each stale repo.
2. `mcp__codehub__group_status({group})` must return `fresh: true` for every member. If any member is stale, abort and name each stale repo.

## Arguments

Expand All @@ -30,12 +30,12 @@ Default output path:
## Process

1. Run the preconditions. Refuse on missing/unknown group.
2. `mcp__opencodehub__group_list` — confirm `<group-name>` exists; read member list.
3. `mcp__opencodehub__group_status({group})` — confirm freshness per member. Abort with named stale repos otherwise.
4. `mcp__opencodehub__group_contracts({group})` — the spine. Returns `{producer_repo, consumer_repo, path, method, shape}`.
2. `mcp__codehub__group_list` — confirm `<group-name>` exists; read member list.
3. `mcp__codehub__group_status({group})` — confirm freshness per member. Abort with named stale repos otherwise.
4. `mcp__codehub__group_contracts({group})` — the spine. Returns `{producer_repo, consumer_repo, path, method, shape}`.
5. If `group_contracts` returns `[]` (zero inter-repo contracts): still write the artifact with a `No inter-repo contracts detected` banner and an empty matrix. Do not error. (Spec 001 AC-5-5.)
6. `mcp__opencodehub__group_query({group, text: "api handlers"})` — disambiguate producer-side locations.
7. For each member repo: `mcp__opencodehub__route_map({repo})` for handler-path citations.
6. `mcp__codehub__group_query({group, text: "api handlers"})` — disambiguate producer-side locations.
7. For each member repo: `mcp__codehub__route_map({repo})` for handler-path citations.
8. Build the consumer/producer matrix: rows = producers, columns = consumers, cell = contract count.
9. Build the Mermaid `flowchart LR` showing inter-repo edges, labeled with contract counts.
10. Assemble the output using the template below.
Expand Down
38 changes: 19 additions & 19 deletions .claude/skills/codehub-document/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: codehub-document
description: "Use when the user asks to generate, regenerate, or refresh long-form codebase documentation, an architecture book, a module map, or a per-repo reference — especially after `codehub analyze` finishes or after a large merge. Examples: \"document this repo\", \"regenerate the architecture docs\", \"write a module map for the monorepo\", \"produce a group-wide portfolio doc\". DO NOT use if the repo is not indexed — run `codehub analyze` first and confirm `mcp__opencodehub__list_repos` returns the repo. DO NOT use for PR descriptions (use `codehub-pr-description`), onboarding docs (use `codehub-onboarding`), or cross-repo contract maps alone (use `codehub-contract-map`)."
allowed-tools: "Read, Write, Edit, Glob, Grep, Bash(codehub:*), mcp__opencodehub__list_repos, mcp__opencodehub__project_profile, mcp__opencodehub__query, mcp__opencodehub__context, mcp__opencodehub__impact, mcp__opencodehub__dependencies, mcp__opencodehub__owners, mcp__opencodehub__risk_trends, mcp__opencodehub__route_map, mcp__opencodehub__tool_map, mcp__opencodehub__list_dead_code, mcp__opencodehub__list_findings, mcp__opencodehub__verdict, mcp__opencodehub__group_list, mcp__opencodehub__group_query, mcp__opencodehub__group_status, mcp__opencodehub__group_contracts, mcp__opencodehub__sql, Task"
description: "Use when the user asks to generate, regenerate, or refresh long-form codebase documentation, an architecture book, a module map, or a per-repo reference — especially after `codehub analyze` finishes or after a large merge. Examples: \"document this repo\", \"regenerate the architecture docs\", \"write a module map for the monorepo\", \"produce a group-wide portfolio doc\". DO NOT use if the repo is not indexed — run `codehub analyze` first and confirm `mcp__codehub__list_repos` returns the repo. DO NOT use for PR descriptions (use `codehub-pr-description`), onboarding docs (use `codehub-onboarding`), or cross-repo contract maps alone (use `codehub-contract-map`)."
allowed-tools: "Read, Write, Edit, Glob, Grep, Bash(codehub:*), mcp__codehub__list_repos, mcp__codehub__project_profile, mcp__codehub__query, mcp__codehub__context, mcp__codehub__impact, mcp__codehub__dependencies, mcp__codehub__owners, mcp__codehub__risk_trends, mcp__codehub__route_map, mcp__codehub__tool_map, mcp__codehub__list_dead_code, mcp__codehub__list_findings, mcp__codehub__verdict, mcp__codehub__group_list, mcp__codehub__group_query, mcp__codehub__group_status, mcp__codehub__group_contracts, mcp__codehub__sql, Task"
argument-hint: "[output-dir] [--group <name>] [--committed] [--refresh] [--section <name>]"
color: indigo
model: sonnet
Expand All @@ -18,9 +18,9 @@ Primary artifact generator. Produces a tree of cross-linked Markdown under `.cod

## Preconditions (check before Phase 0)

1. `mcp__opencodehub__list_repos` returns the target. If not, emit `Run codehub analyze first — repo <name> is not indexed.` and stop.
1. `mcp__codehub__list_repos` returns the target. If not, emit `Run codehub analyze first — repo <name> is not indexed.` and stop.
2. `codehub status` reports fresh. If stale, emit `Run 'codehub analyze' first — index is stale` and stop.
3. Group mode only: `mcp__opencodehub__group_status({group})` must return `fresh: true` for every member. If any member is stale, abort and name each stale repo.
3. Group mode only: `mcp__codehub__group_status({group})` must return `fresh: true` for every member. If any member is stale, abort and name each stale repo.

## Arguments

Expand All @@ -38,24 +38,24 @@ Phase 0 writes `<docs-root>/.context.md` and `<docs-root>/.prefetch.md` so Phase

**Wave 0a — independent precompute (one message, parallel)**. Issue all of these in a single tool-use batch:

- `mcp__opencodehub__list_repos`
- `mcp__opencodehub__project_profile`
- `mcp__opencodehub__sql` — schema probe: `SELECT table_name, column_name FROM information_schema.columns WHERE table_name IN ('nodes','relations') ORDER BY table_name, column_name`
- `mcp__opencodehub__route_map`
- `mcp__opencodehub__tool_map`
- `mcp__opencodehub__dependencies`
- `mcp__opencodehub__risk_trends`
- `mcp__opencodehub__list_dead_code`
- `mcp__opencodehub__list_findings`
- Group mode only: `mcp__opencodehub__group_list`, `mcp__opencodehub__group_status`, `mcp__opencodehub__group_contracts`
- `mcp__codehub__list_repos`
- `mcp__codehub__project_profile`
- `mcp__codehub__sql` — schema probe: `SELECT table_name, column_name FROM information_schema.columns WHERE table_name IN ('nodes','relations') ORDER BY table_name, column_name`
- `mcp__codehub__route_map`
- `mcp__codehub__tool_map`
- `mcp__codehub__dependencies`
- `mcp__codehub__risk_trends`
- `mcp__codehub__list_dead_code`
- `mcp__codehub__list_findings`
- Group mode only: `mcp__codehub__group_list`, `mcp__codehub__group_status`, `mcp__codehub__group_contracts`

**Wave 0b — depends on 0a (one message, parallel)**. Needs schema column names + profile entry points from 0a, so it is a second batch. Issue in one message:

- `mcp__opencodehub__sql` — top communities (`SELECT … FROM nodes WHERE kind='Community' ORDER BY cohesion DESC LIMIT 10`)
- `mcp__opencodehub__sql` — top processes (`SELECT … FROM nodes WHERE kind='Process' ORDER BY step_count DESC LIMIT 10`)
- `mcp__opencodehub__sql` — relations slice for diagrams (filtered per the schema probe)
- `mcp__opencodehub__owners` × top-5 folders (derived from `project_profile` entry points + file-count heuristic)
- Group mode only: `mcp__opencodehub__group_query` for any canonical cross-repo search terms
- `mcp__codehub__sql` — top communities (`SELECT … FROM nodes WHERE kind='Community' ORDER BY cohesion DESC LIMIT 10`)
- `mcp__codehub__sql` — top processes (`SELECT … FROM nodes WHERE kind='Process' ORDER BY step_count DESC LIMIT 10`)
- `mcp__codehub__sql` — relations slice for diagrams (filtered per the schema probe)
- `mcp__codehub__owners` × top-5 folders (derived from `project_profile` entry points + file-count heuristic)
- Group mode only: `mcp__codehub__group_query` for any canonical cross-repo search terms

**Wave 0c — inline Write (no tool batch)**. Deterministic post-processing; no MCP calls:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Group mode populates `cross_repo_refs[]`:
## `--refresh` algorithm

1. Load `.docmeta.json` from the existing output tree.
2. Fetch the current `codehub_graph_hash` from `mcp__opencodehub__list_repos`. If it matches the manifest's hash exactly, skip to step 5.
2. Fetch the current `codehub_graph_hash` from `mcp__codehub__list_repos`. If it matches the manifest's hash exactly, skip to step 5.
3. For each `section` in the manifest:
- Compute `max(mtime(source))` across `sections[i].sources[]` via `stat`.
- If `max(source_mtime) > sections[i].mtime`: mark the section stale.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ Produce `{{ docs_root }}/analysis/dead-code.md`: three tables enumerating unrefe
|---|---|---|
| Shared context | `Read {{ context_path }}` | always first |
| Prefetch ledger | `Read {{ prefetch_path }}` | always first |
| Dead-code inventory | `mcp__opencodehub__list_dead_code({repo: "{{ repo }}"})` | mid-run (rarely cached; the tool is cheap) |
| Dead-code inventory | `mcp__codehub__list_dead_code({repo: "{{ repo }}"})` | mid-run (rarely cached; the tool is cheap) |
| Last-modified per path | from `list_dead_code` response fields when present, else `git log -1 --format=%cs -- <path>` via shell | mid-run |
| Graph hash | `{{ graph_hash }}` for the empty-state banner timestamp anchor | cached |

## 4. Process

1. `Read {{ context_path }}` and `Read {{ prefetch_path }}`. Confirm graph hash and any cached dead-code digest.
2. Call `mcp__opencodehub__list_dead_code({repo: "{{ repo }}"})`. Partition the response into three buckets: `Unreferenced exports`, `Unreferenced files`, `Dead imports`.
2. Call `mcp__codehub__list_dead_code({repo: "{{ repo }}"})`. Partition the response into three buckets: `Unreferenced exports`, `Unreferenced files`, `Dead imports`.
3. If all three buckets are empty: skip to step 7 (empty-state banner).
4. For `Unreferenced exports`: draft a table with columns `Symbol | Path | Last modified`. Path is a backtick `path:LOC`. Last modified is an ISO date.
5. For `Unreferenced files`: draft a table with columns `File | Lines | Last modified`. File is a backtick `path`. Lines is an integer LOC count.
Expand All @@ -57,7 +57,7 @@ Produce `{{ docs_root }}/analysis/dead-code.md`: three tables enumerating unrefe

| Need | Tool | Why |
|---|---|---|
| Unreferenced symbols + files | `mcp__opencodehub__list_dead_code` | graph-aware; deletes are safe |
| Unreferenced symbols + files | `mcp__codehub__list_dead_code` | graph-aware; deletes are safe |
| Last-modified per path | `list_dead_code` fields, else `git log -1` shell | graph does not always carry mtime |
| LOC per unreferenced file | `Read` then line count | graph stores node spans, not file LOC |
| Cross-check at import site | `Read` at `path:LOC` | verify import survives before listing as dead |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ Produce `{{ docs_root }}/analysis/ownership.md`: a ranked table of folders in `{
| Shared context | `Read {{ context_path }}` | always first |
| Prefetch ledger | `Read {{ prefetch_path }}` | always first |
| Owners summary | `{{ context_path }} § Owners summary` | cached |
| Owners per folder | `{{ prefetch_path }} § owners` or `mcp__opencodehub__owners({path: <folder>})` | cached when present |
| Folder roster | `mcp__opencodehub__sql({query: "SELECT DISTINCT file_path FROM nodes WHERE kind='File'"})` + folder-prefix grouping | mid-run, only if `.context.md` roster is truncated |
| Owners per folder | `{{ prefetch_path }} § owners` or `mcp__codehub__owners({path: <folder>})` | cached when present |
| Folder roster | `mcp__codehub__sql({query: "SELECT DISTINCT file_path FROM nodes WHERE kind='File'"})` + folder-prefix grouping | mid-run, only if `.context.md` roster is truncated |
| Top-contributor share | `owners` response field `share` | cached or mid-run |

## 4. Process

1. `Read {{ context_path }}` and `Read {{ prefetch_path }}`. Confirm Owners summary and cached owners digest.
2. Build the folder roster: use `.context.md § Owners summary` when it enumerates folders; otherwise group `File` nodes by top-level folder prefix (`packages/<x>/src`, `src/<module>`, etc.).
3. For each folder (top 15 by file count): resolve top owner and share from `{{ prefetch_path }} § owners` when present, else call `mcp__opencodehub__owners({path: <folder>})`. Capture top owner, share %, total contributors.
3. For each folder (top 15 by file count): resolve top owner and share from `{{ prefetch_path }} § owners` when present, else call `mcp__codehub__owners({path: <folder>})`. Capture top owner, share %, total contributors.
4. Rank folders by top-owner share, descending. Draft the ranking table with columns `Folder | Top owner | Share | Total contributors`. Every Folder cell is a backtick path.
5. Identify Single Points of Failure: folders or files where the top owner's share is > 70%. For each SPOF: draft a bullet under the `## Single points of failure` H2 stating the path, the owner's share percentage, and a one-sentence mitigation (pair reviewer, knowledge-transfer session, cross-training target, etc.).
6. Draft the intro (1-2 paragraphs): what "share" means (commit share, not line share), the window, and what a > 70% share signals for bus factor.
Expand All @@ -54,14 +54,14 @@ Produce `{{ docs_root }}/analysis/ownership.md`: a ranked table of folders in `{

| Need | Tool | Why |
|---|---|---|
| Contributor share per folder | `mcp__opencodehub__owners` | authoritative over git-blame |
| Contributor share per folder | `mcp__codehub__owners` | authoritative over git-blame |
| Cached owners digest | `{{ prefetch_path }} § owners` | precomputed; do not re-call for cached paths |
| Folder roster | `{{ context_path }} § Owners summary` | precomputed |
| Folder roster (fallback) | `mcp__opencodehub__sql` over `File` nodes | only when `.context.md` slice is truncated |
| Folder roster (fallback) | `mcp__codehub__sql` over `File` nodes | only when `.context.md` slice is truncated |

## 7. Fallback paths

- If `mcp__opencodehub__owners` fails for a path: cite the top-3 authors from a manual git-log walk and mark the row `*git-log fallback*` in the Top owner cell.
- If `mcp__codehub__owners` fails for a path: cite the top-3 authors from a manual git-log walk and mark the row `*git-log fallback*` in the Top owner cell.
- If `.context.md § Owners summary` is absent: use the `sql` folder roster and call `owners` per folder. Cite the fallback in the Work log.
- If no folder crosses the > 70% threshold: still emit the `## Single points of failure` H2 with a single line `No folders exceed the 70% bus-factor threshold.` — the H2 must exist for Phase E cross-references.
- If owners data is completely missing (new repo, shallow clone): write the gap to the Work log, skip the Write step, and do not emit an empty file with a single-row table.
Expand Down
Loading
Loading