diff --git a/.agents/lessons.md b/.agents/lessons.md index b8985a1a..7a220182 100644 --- a/.agents/lessons.md +++ b/.agents/lessons.md @@ -25,3 +25,8 @@ Persistent log of corrections and insights from past sessions. Read when relevan - **Never fabricate quantitative explanations to rationalize surprising data** — when a CI / perf / benchmark number is unexpected (e.g. went up after a "performance" PR), the failure mode is to invent a plausible-sounding cause without verification ("+8 doc files were added since the baseline"). This is intellectual dishonesty that compounds: the fabricated cause gets baked into PR bodies, commit messages, follow-up reasoning, and other agents inherit it as fact. **Pattern:** when a number surprises you, say "I don't know yet" and either (a) instrument / re-run to find the real cause, or (b) accept the unknown and surface it explicitly to the user. Verifiable claim formats: `git diff --name-status A..B | grep '^A'` for file-add counts, `gh run view --log` for CI numbers, repeated CI runs on the same commit for variance characterisation. **Never** invent a numeric explanation that "sounds right". Hit on PR #104 (perf-baseline refresh) — claimed "8 new doc files indexed since cc8daed" explaining a +71ms CI regression; actual delta was 1 file. User caught it; PR was closed. - **PR titles: no `SCHEMA N` / `SCHEMA_VERSION` suffix** — schema bumps belong in the PR body, changeset, and `db.ts`; putting `(SCHEMA 37)` in the title adds noise and duplicates what reviewers see in the diff. Title = what shipped (`feat(index): callback dispatch synthesis`), not the integer. - **Perf-baseline flakes are often GHA runner tiers, not code regressions** — `ubuntu-latest` jobs on the same commit can land on fast (~630 ms total) or slow (~1117 ms) runners; cross-job spread dwarfs the +25% gate. **Pattern:** compare pass vs fail CI logs on the same SHA before re-baselining or blaming a PR; capture baseline medians from slow-tier CI logs, use `CODEMAP_PERF_RUNS=5` in CI, and honour `CODEMAP_PERF_REGRESSION_PCT` env during compare (not just `--update`). Hit on main CI May 2026 — #136 merge blocked by `index_create_ms` +31.7% while `total_ms` was only +15%. +- **Workspaces need `"."` listed explicitly** — `workspaces: ["apps/*"]` alone drops the root package from changesets: Release fails with "changeset … which is not in the workspace". Always `workspaces: [".", "apps/*"]` from day one when adding `apps/docs`. +- **Blume `audit` skips `basePath`-relative paths** — with `deployment.base: "/codemap"`, the canonical-bad-target / non-canonical-in-sitemap / indexable-page-not-in-sitemap checks fire on paths that are correct under the subpath. Skip them: `blume audit --fail-on error --skip canonical_bad_target,non_canonical_in_sitemap,indexable_page_not_in_sitemap`. +- **Changelog → maintainer `docs/` links** — old release notes link to `../docs/roadmap.md` / plans. Do **not** stub those under `apps/docs/content/docs/` (pollutes the site). `apps/docs/scripts/validate.ts` filters `BLUME_BROKEN_LINK` on `changelog:*` only; audit still skips `BLUME_AUDIT_LINK_TO_BROKEN` globally. +- **TypeDoc needs classic TypeScript 5–6** — `typedoc@0.28` peers `typescript@5 || 6`; pinning root `typescript@7` breaks `docs:api` (`SyntaxKind` undefined). Keep `typescript@6.0.3` for TypeDoc; typecheck stays on `tsgo` (`@typescript/native-preview`). +- **Don't override root `zod` onto Blume with `"zod": "$zod"`** — forcing the workspace onto zod 4 breaks Blume's frontmatter schema (`config.frontmatter.extend` null). Pin `js-yaml` to `4.3.0` (not `>=4.1.2`) so Astro/Blume don't pull js-yaml v5 ESM breakage. Drop the `$zod` override when adding `apps/docs`; keep root `dependencies.zod` at 4.x for codemap itself. diff --git a/.agents/rules/docs-voice-priming.md b/.agents/rules/docs-voice-priming.md new file mode 100644 index 00000000..b024bc52 --- /dev/null +++ b/.agents/rules/docs-voice-priming.md @@ -0,0 +1,14 @@ +--- +description: Docs voice primer — read docs-voice skill before authoring apps/docs prose. +globs: + - "apps/docs/**" +alwaysApply: false +--- + +# Docs voice (priming) + +Before authoring or editing public docs prose, **read the [`docs-voice` skill](../skills/docs-voice/SKILL.md)**. + +Voice, peer framing (code-index / agent-context tools only — never store/adapter middlewares), card/header grammar, and anti-pitch live in the skill — not duplicated here. + +Product north-star: [`product-tenets`](../skills/product-tenets/SKILL.md). diff --git a/.agents/skills/docs-governance/LIFECYCLE.md b/.agents/skills/docs-governance/LIFECYCLE.md index dc5acf82..2afe5e9d 100644 --- a/.agents/skills/docs-governance/LIFECYCLE.md +++ b/.agents/skills/docs-governance/LIFECYCLE.md @@ -225,3 +225,20 @@ Shipped agent templates under `templates/agent-content/**` follow the same consu | **Maintainer-only** | Never leak into served shards | Module paths under `src/`, CI wiring, dual-file sync, dogfood paths | When lifting durable policy from a closed plan or audit into agent-content, verify parity across CLI help, MCP tool descriptions, served shards, root README, and changeset bodies — not just one surface. + +--- + +## README surfaces (public site vs npm landing vs maintainer docs) + +Codemap has three reading surfaces with distinct jobs; never blur them. + +| Surface | Canonical home | Job | Deploy | +| ---------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------- | -------------------------------------------------- | +| **Public docs site** | `https://stainless-code.com/codemap` | Canonical user docs — install, guides, concepts, recipes, reference, library API | FTP `/codemap` on merge of a **`docs`**-labeled PR | +| **Root `README.md`** (npm landing) | repo root | npm/repo landing digest only — install + one-query hook + pointer to the site | ships in the npm package | +| **Maintainer `docs/`** | `docs/` at repo root (Tier B) | Governance, architecture internals, plans, audits, research — never leaked to the site | tracked in-repo; not deployed | + +- **Site is canonical for user docs.** Root `README.md` summarizes and links; it does not restate guide/reference prose ([`docs/README.md` Rule 1](../../../docs/README.md)). +- **`docs` label deploys.** A PR merged with the **`docs`** label triggers `deploy-docs.yml` → FTP to `/codemap`. Releases and `workflow_dispatch` also deploy. +- **Maintainer `docs/` stays separate.** Curated lifts to the site only; never dump `docs/*.md` wholesale into `apps/docs/` ([`docs/README.md` Rule 1](../../../docs/README.md)). +- **Docs-only changeset = `patch`** (pre-1.0; schema-breaking is the only `minor` trigger — see [`.agents/lessons.md`](../../lessons.md)). diff --git a/.agents/skills/docs-voice/SKILL.md b/.agents/skills/docs-voice/SKILL.md new file mode 100644 index 00000000..d02f4f8f --- /dev/null +++ b/.agents/skills/docs-voice/SKILL.md @@ -0,0 +1,115 @@ +--- +name: docs-voice +description: Voice, tone, and format for the public Codemap docs (`apps/docs`, built with Blume). Use when authoring or editing apps/docs prose — landing, guides, concepts, recipes, reference, generated API — or deciding headline grammar, benefit framing, peer framing, or anti-pitch wording. +--- + +# Docs voice — Codemap docs (`apps/docs`, built with Blume) + +Keep landing, guides, concepts, recipes, reference, and generated API reading like one voice. + +## Voice in one line + +Senior-dev to senior-dev: concrete, SQL-literate, dry, honest about scope. No +hype. The differentiators are radical honesty (say what's planned / diverges / +was rejected) and the "when **not** to use it" anti-pitch — keep both. + +## Do + +- **Lead with the pain, then the mechanism.** "Agents burn tokens scanning files + to find one symbol…" → then "`codemap query --json` returns the row in one SQL + round-trip." +- **Concrete before abstract.** Name `codemap query` / `--recipe` / `createCodemap` + / `defineConfig` before the coinage "predicate-as-API" or "structural index." +- **CLI-first AND programmatic.** Show the CLI shape first; pair with the library + shape (`createCodemap`, `defineConfig`, adapters) when the page is API-shaped. + The published package entry is the SSOT for generated `/reference/api` (TypeDoc). +- **SQL is the API.** When a page answers a structural question, show the SQL or + the `--recipe` — not a paragraph of prose pretending to be the answer. Recipes + are named SQL patterns; cite the recipe id. +- **Section headers by page type.** Marketing = period-terminated benefit + sentence ("Query your codebase."); guides = action verb ("Find a symbol with + one query"); reference = precise noun; concepts = model noun + consequence. +- **Card titles = the outcome; card bodies = the API / SQL.** +- **One idea per sentence in leads.** Short claim first, then expand. +- **State experimental / pre-1.0 status once per surface, one wording** (see + Canonical patterns). +- **Sidebar icons: all-or-none per sibling list.** Blume does not reserve an + icon column — sparse `sidebar.icon` jaggeds labels. Guides, Concepts, + Recipes, Reference leaves: none unless every peer has a natural glyph. + Section `meta.ts` icons and tab icons stay. +- **Peer framing is structural, not brand-vs-brand.** When comparing, contrast + axes (query API, semantic layer, extraction depth, CI substrate) — see + [`docs/why-codemap.md`](../../../docs/why-codemap.md) § Codemap vs alternatives. + Do not clone peer design in prose; reach for the underlying spec + ([`plan-pr-inspiration-discipline`](../../rules/plan-pr-inspiration-discipline.md)). + +## Don't + +- Don't open a page with a 60+ word sentence. +- Don't restate the frontmatter `description` in the first body sentence — the + docs site renders `description` as the page subtitle, so an echoing opener + duplicates content. Open with a concrete scenario/pain instead. +- Don't title cards with bare feature nouns ("Fan-in") when the outcome is the + hook ("Find what depends on a file in one query"). +- Don't manufacture social proof, download counts, "trusted by", or maturity + adjectives ("production-grade", "battle-tested", "world-class") at pre-1.0 — + live queries, source, the changelog, and the benchmark are the proof. +- Don't claim Codemap owns semantic search, refactoring, or editor ergonomics — + peers (LSP, embeddings, verdict linters) own those slots; Codemap owns + structural facts + predicate-as-API. Say when to reach for something else. +- Don't hype ("blazing-fast", "revolutionary", "AI-powered"). Indexed queries + are sub-ms; let the number and the benchmark carry it. +- Don't treat store/adapter middlewares as competitors — different problem + space. Codemap's peers are code-index / agent-context tools; the contrast is + structural-SQL + recipes vs pre-baked graph verbs / embeddings. +- Don't invent Lucide icons for prose nav leaves to "fill out" a section — + strip to none instead of decorating half the list. +- Don't paste maintainer internals (`src/` module names, CI wiring, dual-file + sync, dogfood paths) into public pages — see + [`consumer-surfaces`](../../rules/consumer-surfaces.md). + +## Canonical patterns (use verbatim) + +- **Experimental disclaimer** (banner / pill / callout / stability page): + "Experimental — the API may change between minor releases. Pin your version." +- **Pre-1.0 semver:** breaking changes are expected and ship in **minor + releases** (`0.x` → `0.y`), **not majors**. Schema-breaking changes that force + a `.codemap/index.db` rebuild are the trigger for `minor`; everything else + (additive CLI, public types, docs) is `patch`. +- **Brand one-liner** (memorable beat, not hype): "Query your codebase." +- **Category label** (what it is — pair with the brand beat, then the + mechanism): "local codebase intelligence" / "codebase intelligence tool". + Same breath as SQLite / SQL / recipes — never as a standalone slogan. +- **Public site URL:** `https://stainless-code.com/codemap` (canonical user + docs). Root `README.md` is the npm landing digest; maintainer `docs/` is + separate. +- **Peer set:** other codebase intelligence / code-index / agent-context tools + — static-analysis linters (knip / ts-prune / jscpd / ESLint), Aider RepoMap, + LSP servers, and the SQLite-backed cohort (srclight, ctxpp, KotaDB, …). Not + store/adapter middlewares. +- **Anti-pitch source of truth:** [`docs/why-codemap.md`](../../../docs/why-codemap.md) + § When to reach for something else — link, don't restate. + +## Product tenets + +Decisions and messaging should align with [`product-tenets`](../product-tenets/SKILL.md). + +## Verify + +`content/**` MDX is excluded from oxfmt (nested `.oxfmtrc.json` ignores +`content/**` — the `:::` directive collapse bug); `.astro` is not oxfmt-managed. +Build green before commit ([`verify-after-each-step`](../../rules/verify-after-each-step.md)): + +```bash +bun run docs:validate -- --strict && bun run docs:check -- --isolated && bun run docs:build && bun run docs:audit +``` + +Scheduled drift sync: [`update-docs`](../update-docs/SKILL.md). + +## Reference + +- Priming: [`docs-voice-priming`](../../rules/docs-voice-priming.md) +- Tenets: [`product-tenets`](../product-tenets/SKILL.md) +- Lifecycle / README surfaces: [`docs-governance`](../docs-governance/SKILL.md) +- Anti-pitch + peer framing: [`docs/why-codemap.md`](../../../docs/why-codemap.md) +- Consumer-vs-maintainer split: [`consumer-surfaces`](../../rules/consumer-surfaces.md) diff --git a/.agents/skills/harden-pr/LEDGER.md b/.agents/skills/harden-pr/LEDGER.md index 5e6e1584..7a65cfe6 100644 --- a/.agents/skills/harden-pr/LEDGER.md +++ b/.agents/skills/harden-pr/LEDGER.md @@ -12,6 +12,12 @@ By-design or false-positive findings — do not re-raise. - **[correctness]** `src/application/impact-engine.ts:147` — explicit inPath on single-definition symbol enables first-hop scopeFiles: by-design — matches show `--in` disambiguation (plan P2.1). - **[correctness]** `src/application/impact-engine.ts:162` — per-file walk LIMIT before global dedup: by-design v1 — plan architecture per-defining-file walks; global limit still applies at slice. +- **[docs]** `apps/docs/pages/_home/FinalCta.astro` — `pnx` typo: by-design — [`pnx`](https://pnpm.io/cli/pnx) is pnpm's `dlx` alias (user-locked homepage wording). +- **[surfaces]** homepage InstallBox bunx-only vs getting-started multi-PM tabs: by-design — hero chip stays single-command; guides own `package-install` tabs. +- **[surfaces]** `apps/docs/content/reference/env.mdx` — `CODEMAP_TEST_BENCH`: by-design — real `CODEMAP_ROOT` alias used by CLI bootstrap / benches. +- **[surfaces]** `apps/docs/content/reference/roadmap.mdx` — footer link to repo `docs/roadmap.md`: by-design — curated public subset points at maintainer SSOT. +- **[security]** `apps/docs/public/.htaccess` HSTS `includeSubDomains`: by-design — same apex-host policy as sister docs deploys; confirm with host ops if changing. +- **[surfaces]** `src/version.ts` `CODEMAP_VERSION` “inlined at build time”: out of PR diff — leave; scrub if a version-export docs PR touches that file. `). Your other rules stay. + +## Live content (CLI + MCP + HTTP) + +| Surface | Skill | Rule | +| ---------------------- | -------------------------- | ------------------------- | +| CLI | `codemap skill` | `codemap rule` | +| MCP | `codemap://skill` | `codemap://rule` | +| HTTP (`codemap serve`) | `GET /resources/{uri}` | same for `codemap://rule` | + +Also useful: `codemap://schema`, `codemap://recipes`, `codemap://mcp-instructions`. + +## MCP wiring + +```bash +codemap agents init --mcp +``` + +Writes PM-aware spawn for the project’s package manager (`npx`, `pnpm exec`, `yarn exec`, `bunx`, or dlx of `@stainless-code/codemap@latest` when not installed). Merge is idempotent — foreign MCP servers are preserved. + +| Target | Typical files written | +| ----------------- | ---------------------------------------------------------- | +| Cursor | `.cursor/mcp.json` | +| Claude Code | `.mcp.json` + `.claude/settings.json` | +| VS Code / Copilot | `.vscode/mcp.json` | +| Continue / Cline / Gemini / Amazon Q | project MCP JSON under each tool’s path | +| Windsurf | user-global Cascade MCP config (when Windsurf is selected) | + +Optional IDE mirrors for rules/skills: Cursor, Windsurf, Continue, Cline, Amazon Q, plus root pointers (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `.github/copilot-instructions.md`). + +## Session start + +Long-running `codemap mcp` stays up for the IDE session (no idle timeout). At session start, call **`context`** — project root, schema version, recipe cards, hub leaders, and `index_freshness` (`pending_sync`, `commit_drift`, optional `warning`). + +Watcher is default-ON for `mcp` / `serve`. Opt out: `--no-watch` or `CODEMAP_WATCH=0`. When the watcher is off (e.g. WSL `/mnt/*`), use `codemap agents init --git-hooks`. + +Tool taxonomy and resources: [MCP reference](/reference/mcp). Allowlist: `CODEMAP_MCP_TOOLS` — see [Env](/reference/env). + +## HTTP twin + +```bash +TOKEN=$(openssl rand -hex 32) +codemap serve --port 7878 --token "$TOKEN" +curl -s -X POST http://127.0.0.1:7878/tool/query \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $TOKEN" \ + -d '{"sql":"SELECT name, file_path FROM symbols LIMIT 5"}' +``` + +Same tools as MCP; `--token` required when `--host` is not loopback. diff --git a/apps/docs/content/guides/apply.mdx b/apps/docs/content/guides/apply.mdx new file mode 100644 index 00000000..70797980 --- /dev/null +++ b/apps/docs/content/guides/apply.mdx @@ -0,0 +1,75 @@ +--- +title: Apply & rename +description: Turn recipe diff rows into on-disk edits — dry-run, fixpoint, and rename. +search: + tags: ["guide", "apply", "rename"] +--- + +You’ve got rows that say what to change — `file_path`, `line_start`, `before_pattern`, `after_pattern`. `codemap apply` validates the on-disk line still matches `before_pattern`, then writes `after_pattern`. + +Apply recipes live under [Recipes → Apply / migrate](/recipes#apply--migrate). Preview shape: `--format diff` or `diff-json` ([Formats](/reference/formats)). + +## Recipe apply + +```bash +codemap query --recipe rename-preview \ + --params old=usePermissions,new=useAccess,kind=function \ + --format diff + +codemap apply rename-preview \ + --params old=usePermissions,new=useAccess,kind=function \ + --dry-run + +codemap apply rename-preview \ + --params old=usePermissions,new=useAccess,kind=function \ + --yes +``` + +`--dry-run` validates only. `--yes` is required for real writes (and on non-TTY). Recipes that are not `auto_fixable` need `--force` (or config allowlist) before writes. + +## Rename alias + +`codemap rename` is `apply rename-preview` with friendlier argv. Homonyms: pass `--define-in ` to anchor the definition file (`--in-file` only narrows output paths). + +```bash +codemap rename usePermissions useAccess --kind function --dry-run +codemap rename helper worker --define-in lib/helper.ts --yes +codemap rename --params old=foo,new=bar,define_in=lib/a.ts --dry-run +``` + +## Rows and unified diffs + +Skip the recipe when you already have rows (agent / codemod / audit `added`): + +```bash +codemap query --recipe stale-imports --format diff-json > rows.json +codemap apply --rows rows.json --dry-run +codemap apply --rows - --yes < rows.json + +codemap apply --diff-input edits.patch --dry-run +codemap apply --diff-input edits.patch --yes --commit "chore: drop stale imports" +``` + +## Fixpoint and commit + +```bash +codemap apply migrate-import-source \ + --params from=@old/pkg,to=@new/pkg \ + --yes --until-empty --max-passes 10 + +codemap apply rename-preview \ + --params old=foo,new=bar \ + --yes --commit "refactor: rename foo → bar" +``` + +`--until-empty` loops apply → reindex → repeat until no rows (or `--max-passes`). `--commit` runs `git add` on touched files + commit after a clean apply. + +## MCP twins + +| CLI | MCP | +| --------------------------- | ------------------- | +| `codemap apply ` | `apply` | +| `codemap apply --rows …` | `apply_rows` | +| `codemap apply --diff-input`| `apply_diff_input` | + +Writes still need `yes: true`. Non-`auto_fixable` recipes need `force: true`. Full tool table: [MCP](/reference/mcp). diff --git a/apps/docs/content/guides/audit-baselines.mdx b/apps/docs/content/guides/audit-baselines.mdx new file mode 100644 index 00000000..a95aaf18 --- /dev/null +++ b/apps/docs/content/guides/audit-baselines.mdx @@ -0,0 +1,67 @@ +--- +title: Audit & baselines +description: Diff the index against a saved baseline or a git merge-base — PR attribution included. +search: + tags: ["guide", "audit", "baseline", "ci"] +--- + +“Did this PR introduce new deprecated symbols?” needs a before picture. Save a row snapshot with `--save-baseline`, or diff against a git ref with `audit --base`. + +## Query baselines + +Snapshot any query / recipe result into `query_baselines` inside the index DB (survives `--full` and schema rebuilds): + +```bash +codemap query --json --recipe deprecated-symbols --save-baseline +codemap query --json --recipe deprecated-symbols --save-baseline=pre-refactor + +codemap query --json --recipe deprecated-symbols --baseline +codemap query --json --recipe deprecated-symbols --baseline=pre-refactor --summary + +codemap query --baselines +codemap query --drop-baseline pre-refactor +``` + +`--baseline` returns `{ baseline, current_row_count, added, removed }` (exact row identity via `JSON.stringify`). Incompatible with non-`json` `--format` / `--group-by`. Ad-hoc SQL must pass an explicit `=` on `--save-baseline`. + +## audit --base (PR merge-base) + +Materialises `` via `git archive`, reindexes into a sha-keyed cache, then diffs. No baseline setup required: + +```bash +codemap audit --base origin/main --json +codemap audit --base origin/main --summary +codemap audit --base origin/main --ci # SARIF + non-zero on additions +``` + +With `--format json`, each **added** row carries `attribution`: `introduced` (branch-new) or `inherited` (already present at the merge base). Summary adds `added_introduced` / `added_inherited` per delta. + +v1 deltas: `files`, `dependencies`, `deprecated`. + +## audit --baseline (prefix) + +Convention: save `-files`, `-dependencies`, `-deprecated`, then: + +```bash +codemap query --save-baseline=base-files "SELECT path FROM files" +# … or the recipes / SQL you care about for each delta slot + +codemap audit --baseline base --json +``` + +Missing slots are silently absent. Per-delta overrides: `--files-baseline`, `--dependencies-baseline`, `--deprecated-baseline` (compose with `--base` or `--baseline`). + +## GitHub Action + +Default `mode: audit` on `pull_request` runs against `github.base_ref` (override with `audit-base`). Recipe mode can pass `baseline` for `--baseline` on `query --recipe`. Details: [GitHub Action](/guides/github-action). + +## MCP + +| Goal | Tool | +| ----------------- | ---------------- | +| Save snapshot | `save_baseline` | +| List | `list_baselines` | +| Drop | `drop_baseline` | +| Diff vs base / prefix | `audit` | + +`audit` accepts `base` (git ref) and/or `baseline_prefix` / per-delta `baselines`. One-shot row diff on `query` / `query_recipe` also accepts `baseline`. diff --git a/apps/docs/content/guides/cli-overview.mdx b/apps/docs/content/guides/cli-overview.mdx new file mode 100644 index 00000000..f5cdee20 --- /dev/null +++ b/apps/docs/content/guides/cli-overview.mdx @@ -0,0 +1,102 @@ +--- +title: CLI overview +description: Common Codemap CLI commands — index, query, recipes, serve, and agents init. +search: + tags: ["guide", "cli"] +--- + +Index the tree once per session, then ask structural questions with SQL or a recipe id. Full flag list: [CLI reference](/reference/cli). + +## Index + +```bash +codemap # incremental +codemap --full # full rebuild +codemap --files src/a.ts src/b.tsx # targeted re-index after edits +codemap validate --json # stale / missing / unindexed / rejected +``` + +State lives under `.codemap/` by default (`--state-dir` / `CODEMAP_STATE_DIR` overrides). + +## Query + +```bash +codemap query --json "SELECT name, file_path FROM symbols WHERE name = 'foo'" +codemap query --json --recipe fan-in +codemap query --json --recipe find-symbol-definitions --params name=usePermissions +codemap query --recipes-json # full catalog (bundled + project-local) +codemap query --print-sql fan-in # SQL only — no DB required +``` + +N statements in one bootstrap: + +```bash +echo '{"statements":["SELECT COUNT(*) AS n FROM symbols","SELECT COUNT(*) AS n FROM files"]}' \ + | codemap query batch --stdin --compact +``` + +Outcome aliases are thin wrappers over `query --recipe` (every query flag passes through): + +```bash +codemap dead-code --json # → untested-and-dead +codemap deprecated --ci # → deprecated-symbols --ci +codemap hotspots --json # → fan-in (import hubs — not churn×complexity) +codemap boundaries --format sarif # → boundary-violations +``` + +## Lookups & graphs + +```bash +codemap show runQueryCmd +codemap show foo --kind function --in src/cli +codemap snippet runQueryCmd --json +codemap impact handleQuery # blast radius (callers / dependents) +codemap affected --json # changed sources → tests to run +codemap trace --from createCodemap --to openDatabase +codemap explore handleQuery executeQuery --depth 1 +codemap node handleQuery +``` + +## Apply / ingest (one-liners) + +```bash +codemap apply rename-preview --params old=foo,new=bar --dry-run +codemap rename foo bar --kind function --dry-run +codemap ingest-coverage coverage/coverage-final.json +codemap ingest-churn churn.json +``` + +Full workflows: [Apply](/guides/apply) · [Coverage & churn](/guides/coverage-churn). + +## Resource cards + +```bash +codemap file src/db.ts +codemap schema +codemap symbols handleQuery +``` + +Same JSON as `codemap://files/…`, `codemap://schema`, `codemap://symbols/…`. + +## Agents & transports + +```bash +codemap agents init # scaffold .agents/ pointers +codemap agents init --mcp # + PM-aware MCP config +codemap mcp # stdio MCP (watcher default-ON) +codemap serve --port 7878 # HTTP twin: POST /tool/{name} +codemap skill # live skill markdown +codemap rule # live rule markdown +``` + +Opt out of the embedded watcher: `codemap mcp --no-watch` or `CODEMAP_WATCH=0`. + +## CI-shaped output + +```bash +codemap query --recipe deprecated-symbols --format sarif +codemap query --recipe boundary-violations --ci +codemap audit --base origin/main --json +``` + +Formats: [Formats](/reference/formats). Baselines: [Audit & baselines](/guides/audit-baselines). CI wiring: [GitHub Action](/guides/github-action). diff --git a/apps/docs/content/guides/config.mdx b/apps/docs/content/guides/config.mdx new file mode 100644 index 00000000..eba2ec23 --- /dev/null +++ b/apps/docs/content/guides/config.mdx @@ -0,0 +1,56 @@ +--- +title: Config +description: Project config for Codemap — include/exclude globs, boundaries, synthesis, and churn. +search: + tags: ["guide", "config"] +--- + +Optional config lives at `/config.{ts,js,json}` (default `.codemap/config.*`). Default export: a plain object or an async factory. Unknown keys are rejected (Zod, strict). + +## Minimal shape + +```ts +import { defineConfig } from "@stainless-code/codemap"; + +export default defineConfig({ + include: ["src/**/*.{ts,tsx}", "src/**/*.css"], + excludeDirNames: ["node_modules", ".git", "dist", "build"], + boundaries: [ + { + name: "ui-cant-touch-server", + from_glob: "src/ui/**", + to_glob: "src/server/**", + }, + ], + synthesis: { + heuristicCalls: false, + }, +}); +``` + +JSON works the same (no `defineConfig`). Setting **`include` replaces** the default glob list entirely — it does not merge. + +## Common knobs + +| Field | Role | +| ------------------ | -------------------------------------------------------------------- | +| `root` | Project root; usually CLI `--root` / cwd (optional in config) | +| `databasePath` | SQLite path (rel. to root or absolute); default `/index.db` | +| `include` | Globs relative to project root (replaces defaults when set) | +| `excludeDirNames` | Directory name segments to skip (replaces defaults when set) | +| `tsconfigPath` | Alias resolution; `null` disables | +| `fts5` | Opt-in full-text (`source_fts`); CLI `--with-fts` wins | +| `boundaries` | Architecture rules → `boundary_rules` / `boundary-violations` recipe | +| `synthesis` | e.g. `heuristicCalls` for opt-in heuristic call edges | +| `churn` | Half-life / `since` / optional precomputed `file` | +| `apply` | `autoApplyRecipes` allowlist for `codemap apply` | + +Types and helpers: [API reference](/reference/api). Library entry: [Programmatic](/guides/programmatic). + +## State directory + +Default `.codemap/`. Override with `--state-dir` or `CODEMAP_STATE_DIR`. Codemap rewrites `/.gitignore` to a canonical blacklist on every boot (`index.db`, WAL/SHM, …). Project-tracked sources (`recipes/`, config) stay trackable. + +## Project-local recipes + +Drop SQL into `.codemap/recipes/.sql` (+ optional `.md` for params/actions). Discoverable via `codemap query --recipes-json`; project ids win on collision (`shadows: true` in the catalog). diff --git a/apps/docs/content/guides/coverage-churn.mdx b/apps/docs/content/guides/coverage-churn.mdx new file mode 100644 index 00000000..b02f9fc1 --- /dev/null +++ b/apps/docs/content/guides/coverage-churn.mdx @@ -0,0 +1,43 @@ +--- +title: Coverage & churn +description: Load coverage and churn into the index so risk recipes have measured numbers. +search: + tags: ["guide", "coverage", "churn"] +--- + +Structural dead-code guesses without runtime evidence are noisy. Load coverage (and optional churn) once, then rank with the [Coverage & churn recipes](/recipes#coverage--churn-risk). + +## Ingest coverage + +```bash +codemap ingest-coverage coverage/coverage-final.json # Istanbul +codemap ingest-coverage lcov.info # LCOV +codemap ingest-coverage ./coverage/tmp --runtime # V8 directory +codemap ingest-coverage ./coverage --json +``` + +Auto-detects Istanbul `.json` / LCOV `.info`; pass `--runtime` for V8 dirs. MCP: `ingest_coverage` (`path`, optional `runtime`). + +## Ingest churn + +Git history fills `file_churn` on each index by default. For fixtures or non-git trees: + +```bash +codemap ingest-churn churn.json --json +``` + +Config `churn.file` can replace git-derived churn. MCP: `ingest_churn`. + +## Recipes that unlock + +| After ingest | Recipe ids | +| ------------------------------------ | -------------------------------------------------------------------------- | +| Coverage | `worst-covered-exports`, `files-by-coverage`, `coverage-confirmed-dead`, `untested-and-dead`, `high-complexity-untested`, `text-in-deprecated-functions` | +| Coverage (improves / overrides) | `high-crap-score`, `refactor-risk-ranking` | +| Churn (git default or ingest/config) | `churn-complexity-hotspots` | + +Empty `file_churn` → check `context` / `churn_hint`. Full catalog: [Recipes](/recipes). + +## high-crap-score caveat + +Without measured coverage, `high-crap-score` can still emit rows using **graph-estimated** coverage tiers (85% / 40% / 0%). Parse `coverage_source` on each row before CI gates — prefer `ingest-coverage` first so scores use measured data. diff --git a/apps/docs/content/guides/getting-started.mdx b/apps/docs/content/guides/getting-started.mdx new file mode 100644 index 00000000..ae468b9b --- /dev/null +++ b/apps/docs/content/guides/getting-started.mdx @@ -0,0 +1,58 @@ +--- +title: Getting started +description: Install Codemap and run your first structural query against a local SQLite index. +search: + tags: ["guide", "install"] +--- + +Agents burn tokens scanning files to find one symbol. A SQLite index (`.codemap/index.db`) answers the same question in one SQL round-trip. + +Experimental — the API may change between minor releases. Pin your version. + +## Install + +```package-install +npm i -D @stainless-code/codemap +``` + +Or run the published binary without adding a dependency — same CLI either way: + +```package-install +npx @stainless-code/codemap +``` + +**Engines:** Node `^20.19.0 || >=22.12.0` and/or Bun `>=1.0.31`. + +## Index once + +```bash +codemap +``` + +Default is incremental. Use `codemap --full` for a clean rebuild after a schema bump or when the index looks wrong. + +## First query + +Ad-hoc SQL: + +```bash +codemap query --json "SELECT name, kind, file_path, line_start FROM symbols WHERE name = 'createCodemap'" +``` + +Or a bundled recipe (no SQL to invent): + +```bash +codemap query --json --recipe find-symbol-definitions --params name=createCodemap +``` + +`--json` is what agents and automation want; omit it for `console.table` in a terminal. + +## Wire agents (optional) + +```bash +codemap agents init --mcp +``` + +That scaffolds thin pointer rules/skills under `.agents/` and writes PM-aware MCP config (`npx`, `pnpm exec`, `bunx`, …). Full content is served live by `codemap skill` / `codemap rule` (and MCP resources `codemap://skill` / `codemap://rule`) — updating the package refreshes what agents see. + +Next: [CLI overview](/guides/cli-overview) · [Agents & MCP](/guides/agents-mcp) · [Recipes](/recipes). diff --git a/apps/docs/content/guides/github-action.mdx b/apps/docs/content/guides/github-action.mdx new file mode 100644 index 00000000..a4b33bf0 --- /dev/null +++ b/apps/docs/content/guides/github-action.mdx @@ -0,0 +1,95 @@ +--- +title: GitHub Action +description: Run Codemap audits in CI — SARIF, PR comments, and fail-on gates. +search: + tags: ["guide", "ci", "action"] +--- + +The composite Action runs the Codemap CLI in CI — default on `pull_request` is an audit against the PR base, emitting SARIF for Code Scanning. + +## Minimal workflow + +```yaml +name: Codemap +on: + pull_request: +jobs: + audit: + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write # SARIF upload + pull-requests: write # only if pr-comment: true + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: stainless-code/codemap@main # pin a tag/sha in production +``` + +Default `mode: audit` uses `github.base_ref` when `audit-base` is empty. On non-PR events with no explicit `command:`, the Action no-ops. + +## Modes + +| `mode` | Behavior | +| --------- | ------------------------------------------------------------------------ | +| `audit` | `codemap audit --base --format ` (default on PRs) | +| `recipe` | `codemap query --recipe ` — set `recipe` (+ optional `params`) | +| `command` | Escape hatch — raw CLI args; overrides mode/recipe inputs | + +`mode: aggregate` is reserved and currently rejected. + +## Inputs + +| Input | Notes | +| ------------------- | ---------------------------------------------------------------------- | +| `working-directory` | Monorepo subdirectory | +| `package-manager` | Override autodetect (`npm` / `pnpm` / `yarn` / `bun`, …) | +| `version` | Pin CLI; empty → project dep or `dlx @latest` | +| `mode` / `recipe` | See Modes | +| `params` | Multiline `key=value` for parametrised recipes (`mode: recipe`) | +| `baseline` | Saved baseline name → `query --baseline` (`mode: recipe`) | +| `audit-base` | Git ref for `audit --base`; empty → `github.base_ref` on PRs | +| `format` | Default `sarif`; also `json`, `annotations`, … | +| `output-path` | Written artifact path (default `codemap.sarif`) | +| `upload-sarif` | Default `true` — needs Advanced Security on private repos | +| `pr-comment` | Opt-in markdown summary via `codemap pr-comment` | +| `fail-on` | `any` (default) or `never` | +| `changed-since` | Filter rows to files changed since a ref | +| `group-by` | `owner` / `directory` / `package` | +| `state-dir` | Override `.codemap/` | +| `token` | SARIF upload + PR comment; empty → `github.token` | +| `command` | Raw CLI args (overrides mode / recipe / baseline / …) | + +## Outputs + +| Output | Notes | +| ---------------- | -------------------------------------------------- | +| `agent` | Resolved package manager | +| `exec` | Shell-ready invoke string | +| `install_method` | `project-installed` / `dlx-pinned` / `dlx-latest` | +| `output-file` | Echo of `output-path` | + +Recipe example: + +```yaml +- uses: stainless-code/codemap@main + with: + mode: recipe + recipe: deprecated-symbols + format: sarif + params: | + # optional key=value lines +``` + +Audit against an explicit base: + +```yaml +- uses: stainless-code/codemap@main + with: + mode: audit + audit-base: origin/main + output-path: codemap-audit.sarif +``` + +List recipe ids locally with `codemap query --recipes-json`. Baselines: [Audit & baselines](/guides/audit-baselines). Formats: [Formats](/reference/formats). CLI twin: [CLI overview](/guides/cli-overview). diff --git a/apps/docs/content/guides/index.mdx b/apps/docs/content/guides/index.mdx new file mode 100644 index 00000000..ceca7cbe --- /dev/null +++ b/apps/docs/content/guides/index.mdx @@ -0,0 +1,22 @@ +--- +title: Guides +description: Task-oriented guides — CLI, MCP, config, CI, and the library API. +search: + tags: ["guide"] +--- + +Pick a guide by job: + +| Guide | Job | +| ---------------------------------------------- | ------------------------------------------------ | +| [Getting started](/guides/getting-started) | Install, index, first query | +| [CLI overview](/guides/cli-overview) | Daily commands — query, recipes, show, impact | +| [Agents & MCP](/guides/agents-mcp) | Templates, MCP, HTTP (`codemap serve`) | +| [Apply & rename](/guides/apply) | Recipe apply, rows, diffs, rename | +| [Audit & baselines](/guides/audit-baselines) | `--save-baseline`, `audit --base`, PR attribution| +| [Coverage & churn](/guides/coverage-churn) | `ingest-coverage` / `ingest-churn` + risk recipes| +| [Config](/guides/config) | Globs, boundaries, FTS5, churn | +| [GitHub Action](/guides/github-action) | CI audits → SARIF / PR comments | +| [Programmatic](/guides/programmatic) | `createCodemap` / `defineConfig` | + +Product framing: [Concepts](/concepts). Named SQL patterns: [Recipes](/recipes). Flags and types: [Reference](/reference). diff --git a/apps/docs/content/guides/meta.ts b/apps/docs/content/guides/meta.ts new file mode 100644 index 00000000..699e4cb7 --- /dev/null +++ b/apps/docs/content/guides/meta.ts @@ -0,0 +1,17 @@ +import { defineMeta } from "blume"; + +export default defineMeta({ + title: "Guides", + icon: "book-open", + pages: [ + "getting-started", + "cli-overview", + "agents-mcp", + "apply", + "audit-baselines", + "coverage-churn", + "config", + "github-action", + "programmatic", + ], +}); diff --git a/apps/docs/content/guides/programmatic.mdx b/apps/docs/content/guides/programmatic.mdx new file mode 100644 index 00000000..d677b71a --- /dev/null +++ b/apps/docs/content/guides/programmatic.mdx @@ -0,0 +1,48 @@ +--- +title: Programmatic +description: Use Codemap as a library — createCodemap, defineConfig, and language adapters. +search: + tags: ["guide", "api"] +--- + +Embed the same index the CLI uses — scripts, custom tools, test harnesses. Exhaustive types and JSDoc: [API reference](/reference/api). + +## Quick start + +```ts +import { createCodemap } from "@stainless-code/codemap"; + +const cm = await createCodemap({ root: "/path/to/repo" }); +await cm.index({ mode: "incremental" }); +await cm.index({ mode: "full" }); +await cm.index({ mode: "files", files: ["src/a.ts"] }); + +const rows = cm.query("SELECT name FROM symbols LIMIT 5"); +``` + +`createCodemap` configures a process-global runtime. **One active project root per process** — a second call with a different `root` throws. Re-init with the same root is fine. + +## Config helpers + +```ts +import { defineConfig, parseCodemapUserConfig } from "@stainless-code/codemap"; + +export default defineConfig({ + include: ["src/**/*.{ts,tsx}"], + fts5: false, +}); +``` + +Pass inline overrides: `createCodemap({ root, config: { fts5: true } })`. File path: `configFile` (same as CLI `--config`). See [Config](/guides/config). + +## Also exported + +| Export | Role | +| --------------------------------------------------- | ----------------------------------------- | +| `createCodemap` / `Codemap` | Index + `query` handle | +| `defineConfig` / `codemapUserConfigSchema` | User config | +| `BUILTIN_ADAPTERS` / `getAdapterForExtension` | Language adapters | +| `LanguageAdapter` / `ParsedFilePayload` / … | Adapter types | +| `CODEMAP_VERSION` | Package version string | + +Prefer `createCodemap` over holding a raw DB handle. Full library API: [/reference/api](/reference/api). diff --git a/apps/docs/content/recipes/affected-tests.mdx b/apps/docs/content/recipes/affected-tests.mdx new file mode 100644 index 00000000..2f44c4a2 --- /dev/null +++ b/apps/docs/content/recipes/affected-tests.mdx @@ -0,0 +1,37 @@ +--- +title: affected-tests +description: Find tests likely affected by changed source paths. +search: + tags: ["recipe"] +--- + +Reverse dependency walk from changed sources → test files that import them (or match test detection). Not a verdict — CI composes the runner and exit policy. + +Prefer the CLI/MCP convenience verb (builds `changed_files` for you): + +```bash +codemap affected --json +git diff --name-only origin/main | codemap affected --stdin --json +codemap affected src/lib/cache.ts --json +codemap affected --changed-since origin/main --json +``` + +Recipe form (when you already have paths): + +```bash +codemap query --json --recipe affected-tests --params changed_files=src/lib/cache.ts +``` + +Multiple paths for `query_recipe` / recipe params are joined with ASCII RS (char 30) — the `affected` verb handles that. + +## Params + +| Param | Required | Default | Notes | +| --------------- | -------- | ------- | --------------------------------------------------------------------- | +| `changed_files` | yes | — | Project-relative paths (RS-delimited when multiple) | +| `test_glob` | no | — | SQLite `GLOB` on `files.path`; **replaces** default `*.test.*` / `*.spec.*` suffix globs when set. Empty string keeps `test_suites` only. | +| `max_depth` | no | `50` | Max reverse-dependency hops (`0` = only directly-changed test files) | + +## Rows + +Each row: `test_path`, `impact_depth` (`0` = the test file itself changed). Catalog: `codemap query --recipes-json`. diff --git a/apps/docs/content/recipes/fan-in.mdx b/apps/docs/content/recipes/fan-in.mdx new file mode 100644 index 00000000..4f466c6f --- /dev/null +++ b/apps/docs/content/recipes/fan-in.mdx @@ -0,0 +1,21 @@ +--- +title: fan-in +description: Rank files by how many other files import them (import hubs). +search: + tags: ["recipe"] +--- + +High fan-in means changes ripple through many consumers — protect with tests before refactoring. + +```bash +codemap query --json --recipe fan-in +codemap hotspots --json # outcome alias → same recipe +``` + +No params. The `dependencies` table aggregates static imports, dynamic imports, and resolved module-graph edges. + +:::note +`hotspots` / `fan-in` rank **import hubs**. Change-frequency × complexity is a different recipe: `churn-complexity-hotspots`. +::: + +Inspect SQL: `codemap query --print-sql fan-in`. Full catalog: `codemap query --recipes-json`. Related: `codemap impact ` for a single target’s dependents. diff --git a/apps/docs/content/recipes/find-symbol-definitions.mdx b/apps/docs/content/recipes/find-symbol-definitions.mdx new file mode 100644 index 00000000..b39dafd0 --- /dev/null +++ b/apps/docs/content/recipes/find-symbol-definitions.mdx @@ -0,0 +1,25 @@ +--- +title: find-symbol-definitions +description: Locate every definition of a named symbol with column-precise positions. +search: + tags: ["recipe"] +--- + +Fast tier — equality on `name` (same idea as `codemap show `). + +```bash +codemap query --json --recipe find-symbol-definitions --params name=usePermissions +``` + +## Params + +| Param | Required | Notes | +| ------ | -------- | --------------------------------------------------------------------- | +| `name` | yes | Exact symbol name (case-sensitive). For `LIKE` patterns, use `find-symbol-by-kind` or `show --query 'name:%pat%'`. | + +## When to use it + +- Jump-to-definition for agents before grepping +- Feed `rename-preview` — preview with `codemap apply rename-preview --params old=,new=NEW --dry-run` + +Rows include `file_path`, `line_start`, and `name_column_start` / `name_column_end` (byte offsets on that line). Full catalog: `codemap query --recipes-json`. Twin without a recipe: `codemap show `. diff --git a/apps/docs/content/recipes/index.mdx b/apps/docs/content/recipes/index.mdx new file mode 100644 index 00000000..4a3dccbe --- /dev/null +++ b/apps/docs/content/recipes/index.mdx @@ -0,0 +1,137 @@ +--- +title: Recipes +description: Bundled query recipes — find symbols, fan-in, affected tests, and more. +search: + tags: ["recipe"] +--- + +Hand-rolling joins across `symbols`, `calls`, and `dependencies` is slow. Recipes are named SQL patterns — `codemap query --recipe ` (MCP: `query_recipe`). Prefer a recipe until you know the join paths. + +## Featured + +| Recipe | Outcome | +| ----------------------------------------------------------- | ------------------------------------------------ | +| [find-symbol-definitions](/recipes/find-symbol-definitions) | Exact-name definition rows (file + column range) | +| [affected-tests](/recipes/affected-tests) | Tests that transitively import changed sources | +| [fan-in](/recipes/fan-in) | Top files by how many others depend on them | + +## Catalog truth + +```bash +codemap query --recipes-json +codemap query --print-sql +``` + +Project overrides live in `.codemap/recipes/` ([Config](/guides/config)). Params and per-row actions are in each recipe’s companion `.md`. Tables below list every bundled id by theme — one-line outcome only; SQL stays in the catalog / `--print-sql`. + +CI presentation (`--format sarif` / `codeclimate` / `badge`): [Formats](/reference/formats). Diff-shape rows → [Apply](/guides/apply). Coverage / churn unlock: [Coverage & churn](/guides/coverage-churn). + +## Symbol & reference lookup + +| Id | Outcome | +| -------------------------- | ----------------------------------------------------------------------- | +| `find-symbol-definitions` | Exact-name definitions (`WHERE name = ?` — same tier as `codemap show`) | +| `find-symbol-by-kind` | Symbols by `kind` + `name_pattern` (`LIKE`) | +| `find-symbol-references` | Binding-resolved references to a definition (name + defining file) | +| `find-references` | Every identifier use matching a name (write flag + enclosing scope) | +| `find-call-sites` | Parse-resolved call sites of a named function (AST provenance only) | +| `find-export-sites` | Direct exports and re-exports of a named binding | +| `find-import-sites` | Import sites of a named binding across files | +| `find-jsx-usages` | JSX element rows for a component / tag name | +| `find-by-param-type` | Parameters whose type annotation exactly matches a string | +| `find-decorator-usage` | Decorator sites linked to decorated symbols when resolvable | +| `find-async-functions` | Async functions with stringified return type | +| `find-throws-jsdoc` | Structured `@throws` tags from JSDoc | +| `find-write-sites` | Writes to an identifier (assignments, mutations, declarations) | +| `find-re-exported-bindings` | Identifier refs resolved via a re-export chain | +| `find-dynamic-imports` | Dynamic `import()` sites (literal specs may resolve to a path) | +| `markers-by-kind` | Marker counts by kind (`TODO`, `FIXME`, …) | +| `visibility-tags` | Symbols with JSDoc visibility tags (`public` / `private` / …) | +| `components-by-hooks` | React components ranked by hook count | +| `tests-by-file` | Test counts per test file | +| `env-var-audit` | Distinct `process.env.X` accesses with use count and file fan-out | + +## Graphs & types + +| Id | Outcome | +| --------------------------- | ------------------------------------------------------------------------------------------------ | +| `call-path` | Shortest path between two symbols on `calls` (optional import fallback; AST provenance) | +| `fan-in` | Top files by how many others depend on them | +| `fan-out` | Top files by dependency edge count | +| `fan-out-sample` | Fan-out leaders plus sample dependency targets | +| `fan-out-sample-json` | Same as `fan-out-sample` with `sample_targets` as a JSON array | +| `type-ancestors` | Transitive `extends` + direct `implements` for a class / interface | +| `type-descendants` | Symbols that `extends` / `implements` a type (pass `file_path` on homonyms) | +| `symbol-neighborhood` | Callers, callees, and one-hop file dependencies around a symbol | +| `circular-imports` | Files in import cycles, grouped by `cycle_id` | +| `calls-including-heuristic` | Heuristic callback-synthesis edges (`provenance = 'heuristic'`) — needs `synthesis.heuristicCalls: true` | +| `unresolved-call-sites` | Call sites that did not resolve after the call-resolution pass | +| `barrel-chains` | Resolved re-export chains to terminal definitions | +| `barrel-files` | Top files by export count (barrel / public-API candidates) | +| `find-barrel-files` | Files flagged `is_barrel = 1` | +| `affected-tests` | Tests that transitively import changed sources (also `codemap affected`) | + +## CI / dead code / boundaries + +| Id | Outcome | +| ------------------------------- | ------------------------------------------------------------------------------------ | +| `deprecated-symbols` | Symbols with `@deprecated` JSDoc (`reason` / `evidence_json` on rows) | +| `unimported-exports` | Exports with no import row for that file + name | +| `boundary-violations` | Import edges matching a `boundaries.deny` rule in config | +| `untested-and-dead` | Exported functions that look structurally dead and lack measured coverage | +| `stale-imports` | Diff-shape unused import specifiers (structural; not a formatter) | +| `unused-type-members` | Exported type members never directly imported | +| `components-touching-deprecated` | Components that hook or call `@deprecated` symbols | +| `text-in-deprecated-functions` | `@deprecated` functions in files with TODO/FIXME/HACK and low coverage | +| `find-side-effect-files` | Files with module-level side effects (`has_side_effects = 1`) | +| `find-side-effect-imports` | Side-effect-only imports (`import "./mod"` with no bindings) | + +## Coverage & churn risk + +Needs coverage and/or churn data in the index — see [Coverage & churn](/guides/coverage-churn). Without ingest, some recipes still run on graph estimates; parse `coverage_source` before gating CI. + +| Id | Outcome | +| ---------------------------- | ----------------------------------------------------------------------------------------------- | +| `worst-covered-exports` | Worst-covered exported functions (test-writing targets) | +| `files-by-coverage` | Files ranked ascending by statement coverage | +| `coverage-confirmed-dead` | Structurally dead exports with an explicit coverage `confidence` column | +| `high-crap-score` | Symbols ranked by CRAP (`CC² × (1 − coverage/100)³ + CC`) — check `coverage_source` | +| `churn-complexity-hotspots` | Files/symbols by churn × cyclomatic complexity (not the `hotspots` alias → `fan-in`) | +| `refactor-risk-ranking` | Files by `(fan_in + 1) × (100 − avg_coverage_pct)` | +| `high-complexity-untested` | Functions with cyclomatic complexity ≥ 10 and measured coverage < 50% | + +## Apply / migrate + +Diff-shape rows (`file_path`, `line_start`, `before_pattern`, `after_pattern`) feed `codemap apply`. Workflow: [Apply](/guides/apply). Preview with `--format diff` / `diff-json`. + +| Id | Outcome | +| ---------------------- | ---------------------------------------------------------------------------- | +| `rename-preview` | Diff preview for symbol renames (also `codemap rename`) | +| `migrate-deprecated` | Migrate call sites / usages of a deprecated symbol to a replacement | +| `migrate-import-source` | Exact-match import `source` path migration | +| `migrate-jsx-prop` | JSX attribute name renames | +| `add-jsdoc-deprecated` | Prepend `@deprecated` JSDoc above `export function ` definitions | +| `deprecated-usages` | Rewrite the first line of an existing `@deprecated` block (docs sync) | +| `replace-marker-kind` | Replace marker kind tokens on disk (e.g. `TODO` → `FIXME`) | + +## Smells & quality + +| Id | Outcome | +| -------------------------- | -------------------------------------------------------------------- | +| `duplicates` | Symbols whose `body_hash` collides (identical function bodies) | +| `large-functions` | Functions / methods with `body_line_count` ≥ 50 | +| `deeply-nested-functions` | Functions with nesting depth ≥ 4 | +| `high-cognitive-complexity` | Functions above cognitive-complexity threshold (default 15) | +| `find-await-in-loop` | `await` sites inside loop bodies | +| `find-swallowed-errors` | `catch` bodies that only log to `console.*` | +| `find-leftover-console` | Every `console.*` call site | +| `find-skipped-tests` | `describe.skip` / `it.skip` / `.only` / `.todo` sites | +| `files-largest` | Top files by line count | + +## Index / ops + +| Id | Outcome | +| ----------------------- | ------------------------------------------------------------------------ | +| `index-summary` | Single row: counts for files, symbols, imports, components, dependencies | +| `files-hashes` | Indexed files with `content_hash` (staleness inputs) | +| `call-resolution-stats` | Counts from the call-resolution phase (AST vs unresolved, …) | diff --git a/apps/docs/content/recipes/meta.ts b/apps/docs/content/recipes/meta.ts new file mode 100644 index 00000000..1057bc54 --- /dev/null +++ b/apps/docs/content/recipes/meta.ts @@ -0,0 +1,7 @@ +import { defineMeta } from "blume"; + +export default defineMeta({ + title: "Recipes", + icon: "flask-conical", + pages: ["find-symbol-definitions", "affected-tests", "fan-in"], +}); diff --git a/apps/docs/content/reference/api/index.mdx b/apps/docs/content/reference/api/index.mdx new file mode 100644 index 00000000..c586576e --- /dev/null +++ b/apps/docs/content/reference/api/index.mdx @@ -0,0 +1,41 @@ +--- +title: API +description: Library API for the published @stainless-code/codemap package entry. +sidebar: + label: Overview +search: + tags: ["api", "reference"] +--- + +import Card from "blume/components/content/Card.astro"; +import CardGroup from "blume/components/content/CardGroup.astro"; + +One package entry — everything below is re-exported from `@stainless-code/codemap`. Quick start: [Programmatic](/guides/programmatic). Hub: [Reference](/reference). + +Experimental — the API may change between minor releases. Pin your version. Pre-1.0: breaking changes ship in **minor** releases (`0.x` → `0.y`), not majors. + +## Library surface + + + + Index / query runtime — `createCodemap`, `Codemap` + + + Config helpers + Zod schemas + + + `LanguageAdapter`, `BUILTIN_ADAPTERS`, … + + + Config, parse, and adapter types + + + +```ts +import { + createCodemap, + defineConfig, + BUILTIN_ADAPTERS, + CODEMAP_VERSION, +} from "@stainless-code/codemap"; +``` diff --git a/apps/docs/content/reference/api/meta.ts b/apps/docs/content/reference/api/meta.ts new file mode 100644 index 00000000..c2ece689 --- /dev/null +++ b/apps/docs/content/reference/api/meta.ts @@ -0,0 +1,8 @@ +import { defineMeta } from "blume"; + +export default defineMeta({ + title: "API", + icon: "code", + // TypeDoc single entry (`src/index.ts`) → `modules.mdx` (see typedoc.json entryFileName). + pages: ["modules"], +}); diff --git a/apps/docs/content/reference/cli.mdx b/apps/docs/content/reference/cli.mdx new file mode 100644 index 00000000..94cf25ac --- /dev/null +++ b/apps/docs/content/reference/cli.mdx @@ -0,0 +1,103 @@ +--- +title: CLI +description: Codemap CLI commands and flags. +search: + tags: ["reference", "cli"] +--- + +Live help always wins: `codemap --help` and `codemap --help`. Digest below mirrors the published CLI surface. + +## Index (default argv) + +```bash +codemap +codemap --full +codemap --files +codemap --root +codemap --config +codemap --state-dir +codemap --with-fts +codemap version # also: --version / -V +codemap unlock # clear stale index.lock +``` + +## query + +```bash +codemap query --json "" +codemap query --json --recipe [--params k=v,…] +codemap query --recipes-json +codemap query --print-sql +codemap query --summary +codemap query --changed-since +codemap query --group-by directory|owner|package +codemap query --save-baseline[=name] +codemap query --baseline[=name] +codemap query --baselines +codemap query --drop-baseline +codemap query --format +codemap query --ci # SARIF + non-zero on findings + quiet +``` + +N statements, one bootstrap (MCP `query_batch`): + +```bash +echo '{"statements":["SELECT 1","SELECT COUNT(*) AS n FROM symbols"]}' \ + | codemap query batch --stdin +codemap query batch --file queries.json --summary --compact +``` + +Outcome aliases (pass query flags through): `dead-code`, `deprecated`, `boundaries`, `hotspots` (→ `fan-in`), `coverage-gaps`. + +## Lookups & graphs + +```bash +codemap show [--kind …] [--in ] [--query '…'] [--print-sql] +codemap snippet […] +codemap impact [--direction up|down|both] [--via …] [--depth N] [--in ] +codemap affected [paths…] [--stdin] [--changed-since ] [--json] +codemap trace --from --to +codemap explore … [--depth N] [--kind …] [--budget-chars N] +codemap node +``` + +## Resource twins + +Same JSON as MCP / HTTP resources: + +```bash +codemap file # → codemap://files/{path} +codemap schema # → codemap://schema +codemap symbols [--in ] +``` + +## audit / apply / rename / ingest + +```bash +codemap audit --base [--json] [--summary] [--format sarif] [--ci] +codemap audit --baseline +codemap apply --params … [--dry-run|--yes] [--force] +codemap apply --yes --until-empty [--max-passes N] +codemap apply --yes --commit "" +codemap apply --rows - --yes +codemap apply --diff-input --dry-run +codemap rename [--define-in ] [--kind …] [apply flags…] +codemap ingest-coverage [--runtime] [--json] +codemap ingest-churn [--json] +codemap pr-comment +``` + +## Agents & transports + +```bash +codemap agents init [--force] [--mcp] [--interactive] [--targets …] [--git-hooks] +codemap skill +codemap rule +codemap mcp [--no-watch] +codemap serve [--port N] [--host …] [--token …] [--no-watch] +codemap watch [--debounce ms] [--quiet] +codemap context [--compact] [--for ""] [--json] +codemap validate [--json] +``` + +Guides: [CLI overview](/guides/cli-overview) · [Apply](/guides/apply) · [Audit & baselines](/guides/audit-baselines) · [Agents & MCP](/guides/agents-mcp). Env: [Env](/reference/env). Formats: [Formats](/reference/formats). diff --git a/apps/docs/content/reference/env.mdx b/apps/docs/content/reference/env.mdx new file mode 100644 index 00000000..055a28c4 --- /dev/null +++ b/apps/docs/content/reference/env.mdx @@ -0,0 +1,22 @@ +--- +title: Env +description: Environment variables that affect Codemap CLI and serve. +search: + tags: ["reference", "env"] +--- + +CLI flags override env when both exist. Prefer project config ([Config](/guides/config)) for durable settings. + +| Variable | Role | +| ---------------------------- | -------------------------------------------------------------------- | +| `CODEMAP_ROOT` | Project root when `--root` omitted (also `CODEMAP_TEST_BENCH`) | +| `CODEMAP_STATE_DIR` | State directory (default `.codemap/`); `--state-dir` wins | +| `CODEMAP_WATCH` | `0` / `false` opts out of default-ON watcher on `mcp` / `serve` | +| `CODEMAP_NO_WATCH` | `1` — same opt-out as `CODEMAP_WATCH=0` | +| `CODEMAP_FORCE_WATCH` | `1` — override WSL `/mnt/*` auto-disable | +| `CODEMAP_MCP_TOOLS` | Comma-separated MCP tool allowlist (snake_case names) | +| `CODEMAP_PARSE_TIMEOUT_MS` | Fixed per-file parse budget (ms); unset = 10s + size scaling (cap 30s) | +| `CODEMAP_PARSE_WORKERS` | Worker pool size (positive integer, max 32) | +| `CODEMAP_WORKER_RECYCLE_EVERY` | Recycle workers after N files (default `250`) | + +HTTP serve auth uses `--token` (not an env default). Watcher / git-hooks guidance: [Index lifecycle](/concepts/index-lifecycle) · [Agents & MCP](/guides/agents-mcp). diff --git a/apps/docs/content/reference/formats.mdx b/apps/docs/content/reference/formats.mdx new file mode 100644 index 00000000..43051820 --- /dev/null +++ b/apps/docs/content/reference/formats.mdx @@ -0,0 +1,30 @@ +--- +title: Formats +description: Codemap query output formats — JSON, SARIF, Code Climate, badge, and more. +search: + tags: ["reference", "formats"] +--- + +`--format` (and `--ci`) apply to flat row lists — not `--summary` / `--group-by` / baseline envelopes. Use JSON for triage; use SARIF / badge / annotations for gates. Full set: `text` | `json` | `sarif` | `annotations` | `mermaid` | `diff` | `diff-json` | `codeclimate` | `badge`. + +| Format | Use | +| -------------- | ---------------------------------------------------------------- | +| `text` | Human table / text (CLI default) | +| `json` | Machine shape (`--json`); agents and automation | +| `sarif` | SARIF 2.1.0 → GitHub Code Scanning | +| `annotations` | GitHub Actions `::notice` lines | +| `mermaid` | Graph edges — needs `{from, to, …}` rows; rejects >50 edges | +| `diff` | Unified edit preview from `{file_path, line_start, before_pattern, after_pattern}` | +| `diff-json` | Same row contract as JSON (feeds [Apply](/guides/apply)) | +| `codeclimate` | GitLab Code Quality artifact (locatable rows; flat `minor`) | +| `badge` | Issue-count summary; `--badge-style json` for CI gates | + +```bash +codemap query --recipe deprecated-symbols --format sarif +codemap query --recipe deprecated-symbols --ci +codemap query --recipe boundary-violations --format codeclimate +codemap query --recipe boundary-violations --format badge --badge-style json +codemap audit --base origin/main --format sarif +``` + +`rule.id` is `codemap.` (or `codemap.adhoc`). SARIF / annotations / codeclimate / badge auto-detect path columns (`file_path` / `path` / `to_path` / `from_path`). CI wiring: [GitHub Action](/guides/github-action). diff --git a/apps/docs/content/reference/index.mdx b/apps/docs/content/reference/index.mdx new file mode 100644 index 00000000..1694785b --- /dev/null +++ b/apps/docs/content/reference/index.mdx @@ -0,0 +1,17 @@ +--- +title: Reference +description: CLI flags, env vars, MCP tools, output formats, and the library API. +search: + tags: ["reference"] +--- + +| Page | Contents | +| ----------------------------- | ------------------------------------------------------- | +| [CLI](/reference/cli) | Commands and common flags | +| [Env](/reference/env) | Environment variables | +| [MCP](/reference/mcp) | Tools and resources | +| [Formats](/reference/formats) | JSON, SARIF, Code Climate, badge, … | +| [API](/reference/api) | Library API for `@stainless-code/codemap` | +| [Roadmap](/reference/roadmap) | Forward-looking work (not a changelog) | + +Task-oriented walkthroughs: [Guides](/guides). Named SQL patterns: [Recipes](/recipes). diff --git a/apps/docs/content/reference/mcp.mdx b/apps/docs/content/reference/mcp.mdx new file mode 100644 index 00000000..d317b752 --- /dev/null +++ b/apps/docs/content/reference/mcp.mdx @@ -0,0 +1,78 @@ +--- +title: MCP +description: Codemap MCP tools and resources for agent sessions. +search: + tags: ["reference", "mcp"] +--- + +Start with `codemap agents init --mcp`, then `codemap mcp` (stdio; watcher default-ON). HTTP twin: `codemap serve` → `POST /tool/{name}`. Wiring guide: [Agents & MCP](/guides/agents-mcp). + +## Session start + +1. Call **`context`** — root, schema version, recipe cards, hub leaders, `index_freshness`, optional `codebase_map` / `map_id`. +2. Read **`codemap://rule`** (always-on priming: query the index for structure, don’t grep). +3. Catalog / DDL when needed: **`codemap://recipes`**, **`codemap://schema`**. + +MCP initialize also injects operational **`instructions`** (tool selection playbook). Full narrative stays on `codemap://skill` / `codemap://rule`. + +## All 21 tools + +| Tool | Role | +| ------------------- | -------------------------------------------------------------------- | +| `context` | Session bootstrap — freshness, hubs, recipe cards, optional map | +| `validate` | Per-file staleness | +| `query` | Ad-hoc SQL | +| `query_batch` | N statements / one round-trip | +| `query_recipe` | Named recipe by id | +| `show` | Exact / field-qualified symbol lookup | +| `snippet` | Same rows as `show` + disk text | +| `impact` | Blast radius (callers / dependents) | +| `trace` | Call path + snippets | +| `explore` | Multi-symbol neighborhood survey | +| `node` | One-hop symbol card | +| `affected` | Changed sources → tests | +| `audit` | Drift vs git `base` and/or baseline prefix / per-delta baselines | +| `save_baseline` | Snapshot rows (`{name, sql? \| recipe?}`) | +| `list_baselines` | Saved baselines | +| `drop_baseline` | Delete a baseline by name | +| `ingest_coverage` | Load Istanbul / LCOV / V8 coverage | +| `ingest_churn` | Load precomputed `file_churn` JSON | +| `apply` | Apply a recipe’s diff rows (`yes: true` for writes) | +| `apply_rows` | Apply pre-built rows | +| `apply_diff_input` | Apply unified diff text | + +## Goal → tool (summary) + +| Goal | Tool | Recipe twin (when applicable) | +| ---------------------------- | ---------------------------- | ------------------------------------ | +| Exact symbol | `show` / `snippet` | `find-symbol-definitions` | +| Ad-hoc SQL | `query` / `query_batch` | — | +| Named pattern | `query_recipe` | any catalog id | +| Blast radius | `impact` | `fan-in` (file hubs) | +| Call path | `trace` | `call-path` | +| Neighborhood | `explore` / `node` | `symbol-neighborhood` | +| Tests to run | `affected` | `affected-tests` | +| Drift vs baseline / base | `audit` | — | +| Save / list / drop baseline | `save_baseline` / `list_baselines` / `drop_baseline` | — | +| Freshness / bootstrap | `context` / `validate` | — | +| Coverage / churn ingest | `ingest_coverage` / `ingest_churn` | — | +| Apply recipe / rows / diff | `apply` / `apply_rows` / `apply_diff_input` | — (writes need `yes: true`) | + +Output shapes match CLI `--json` envelopes (snake_case). Array tools append a second content block prefixed `@codemap/index_freshness`; object tools merge freshness inline. + +Baselines workflow: [Audit & baselines](/guides/audit-baselines). Apply: [Apply](/guides/apply). Coverage: [Coverage & churn](/guides/coverage-churn). + +Allowlist: `CODEMAP_MCP_TOOLS` — see [Env](/reference/env). + +## Resources + +| URI | Content | +| --------------------------- | -------------------------------------------- | +| `codemap://rule` | Always-on priming rule | +| `codemap://skill` | Full skill (recipes + schema + patterns) | +| `codemap://schema` | Live DDL | +| `codemap://recipes` | Catalog | +| `codemap://recipes/{id}` | One recipe | +| `codemap://mcp-instructions`| Initialize playbook text | +| `codemap://files/{path}` | Live file card | +| `codemap://symbols/{name}` | Live symbol card | diff --git a/apps/docs/content/reference/meta.ts b/apps/docs/content/reference/meta.ts new file mode 100644 index 00000000..b50158a1 --- /dev/null +++ b/apps/docs/content/reference/meta.ts @@ -0,0 +1,8 @@ +import { defineMeta } from "blume"; + +export default defineMeta({ + title: "Reference", + icon: "code", + pages: ["cli", "env", "mcp", "formats", "api", "roadmap"], +}); + diff --git a/apps/docs/content/reference/roadmap.mdx b/apps/docs/content/reference/roadmap.mdx new file mode 100644 index 00000000..1d7bd294 --- /dev/null +++ b/apps/docs/content/reference/roadmap.mdx @@ -0,0 +1,59 @@ +--- +title: Roadmap +description: Forward-looking work — not a mirror of shipped CLI or schema. +search: + tags: ["reference", "roadmap"] +sidebar: + badge: "Planned" +--- + +Shipped behavior lives in [Guides](/guides), [Concepts](/concepts), and the +[changelog](/changelog). This page is the forward-looking list. Pull requests +welcome — open an issue first for anything below so we can agree on shape. + +## Next + +- **Community language adapters** — optional packages (e.g. Tree-sitter) with a + peer dependency on `@stainless-code/codemap` and a public registration API + beyond the built-in adapters. +- **GitHub Marketplace Action listing** — publish the in-tree Action + (`action.yml`, SARIF / annotations, CI helpers) to the Marketplace with + floating `v1` tags. +- **LSP diagnostic-push** — recipes as editor diagnostics (not rename / + go-to-definition; TypeScript already owns those). +- **Framework route extraction** — Express / React Router / NestJS-style + `http_routes` substrate for reachability recipes. +- **FTS default-on evaluation** — measure the DB size tax of defaulting + `source_fts` on; today full-text search stays opt-in (`--with-fts` / + `fts5: true`). + +## Later + +- **Framework plugin layer** — declarative entry-point hints (globs + optional + AST parse of tool configs) so dead-code / unimported-export recipes respect + Vite / Next / Vitest roots — no JS eval at index time. +- **Zero-deps shell installer** — `curl | sh` / PowerShell binary fetch beside + npm for consumers without a JS toolchain. +- **MCP shared daemon per project** — one watcher + one SQLite writer shared + across concurrent agent sessions (long-running `mcp` / `serve` only; one-shot + CLI stays cold-start fast). +- **Monorepo / workspace awareness** — discover workspaces and index + per-workspace dependency graphs. + +## Out of scope + +Codemap stays a structural-index primitive. In particular: + +- **SQL (and recipes) stay the API** — no pre-baked pass/fail verdict primitive; + SARIF / audit deltas are output modes. +- **No rename / go-to-def LSP engine** — read-side `show` / `snippet` / `impact` + already cover agent lookup; diagnostic-push is the only LSP track above. +- **No LLM or embeddings in the box** — the agent host owns meaning; we supply + structure. +- **No opinionated autofix engine** — `codemap apply` executes explicit + recipe/agent diff rows with confirmation gates. +- **No telemetry upload, no remote-repo clone-and-index** — local checkout is + the source of truth. + +Maintainer detail (plans, floors, perf triggers) lives in the repo’s +[`docs/roadmap.md`](https://github.com/stainless-code/codemap/blob/main/docs/roadmap.md). diff --git a/apps/docs/package.json b/apps/docs/package.json new file mode 100644 index 00000000..d5581289 --- /dev/null +++ b/apps/docs/package.json @@ -0,0 +1,16 @@ +{ + "name": "@stainless-code/codemap-docs", + "private": true, + "type": "module", + "scripts": { + "audit": "blume audit --fail-on error --skip canonical_bad_target,non_canonical_in_sitemap,indexable_page_not_in_sitemap,BLUME_AUDIT_LINK_TO_BROKEN", + "build": "blume build", + "check": "blume check", + "dev": "blume dev", + "preview": "blume preview", + "validate": "bun scripts/validate.ts" + }, + "dependencies": { + "blume": "1.1.2" + } +} diff --git a/apps/docs/pages/404.astro b/apps/docs/pages/404.astro new file mode 100644 index 00000000..71b6108e --- /dev/null +++ b/apps/docs/pages/404.astro @@ -0,0 +1,81 @@ +--- +import PageLayout from "blume/components/layout/PageLayout.astro"; +import { withBase } from "blume/components/islands/base-path.ts"; +import { contentHref } from "blume/components/content/base-href.ts"; +import data from "blume:data"; +import { CURATED_POPULAR } from "../components/curated-popular"; + +export const prerender = true; + +const { config } = data; +const site = { description: config.description, title: config.title }; + +const popular = CURATED_POPULAR.map(({ route, label }) => ({ + href: contentHref(route), + label, +})); +--- + + + + diff --git a/apps/docs/pages/_home/Batteries.astro b/apps/docs/pages/_home/Batteries.astro new file mode 100644 index 00000000..57bde24c --- /dev/null +++ b/apps/docs/pages/_home/Batteries.astro @@ -0,0 +1,54 @@ +--- +import Card from "blume/components/content/Card.astro"; +import CardGroup from "blume/components/content/CardGroup.astro"; +import { contentHref } from "blume/components/content/base-href.ts"; +--- + +
+
+

+ Batteries included. +

+

+ Recipes, MCP, CI, and agent scaffolding — same index, adopt what you need. +

+
+ +
+ + + Bundled recipes for symbol lookup, impact, dead code, and CI formats. + + + Same recipes as the CLI — tools and resources on the live index. + + + Run recipes in CI with SARIF, annotations, and badge exit codes. + + + `agents init` writes version-matched pointers; package updates refresh + served skill/rule content. + + +
+
diff --git a/apps/docs/pages/_home/FinalCta.astro b/apps/docs/pages/_home/FinalCta.astro new file mode 100644 index 00000000..1f918e08 --- /dev/null +++ b/apps/docs/pages/_home/FinalCta.astro @@ -0,0 +1,43 @@ +--- +import { contentHref } from "blume/components/content/base-href.ts"; +import InstallBox from "./InstallBox.astro"; + +const primaryButton = + "inline-flex items-center gap-2 rounded-full bg-foreground px-5 py-2.5 font-medium text-background text-sm transition-opacity hover:opacity-90"; +const secondaryButton = + "inline-flex items-center gap-2 rounded-full border border-border px-5 py-2.5 font-medium text-foreground text-sm transition-colors hover:border-foreground"; +--- + +
+

+ Start querying your codebase. +

+

+ Dev dependency or one-shot via bunx / npx / yarn dlx / pnx — index once, + then query with SQL or a recipe. +

+
+ +
diff --git a/apps/docs/pages/_home/Hero.astro b/apps/docs/pages/_home/Hero.astro new file mode 100644 index 00000000..005f83bc --- /dev/null +++ b/apps/docs/pages/_home/Hero.astro @@ -0,0 +1,72 @@ +--- +import CodeBlock from "blume/components/content/CodeBlock.astro"; +import { contentHref } from "blume/components/content/base-href.ts"; +import InstallBox from "./InstallBox.astro"; +import { cliSnippet } from "./source-snippets.ts"; +--- + +
+

+ Stop scanning for one symbol. + Query your codebase. +

+ +

+ Local codebase intelligence: a SQLite index of symbols, imports, and calls — + SQL and recipes for agents, not another grep pass. +

+ + {/* Blume CodeBlock fills the column — shrink-wrap like InstallBox. */} +
+ +
+ +
+ + +
diff --git a/apps/docs/pages/_home/HowItWorks.astro b/apps/docs/pages/_home/HowItWorks.astro new file mode 100644 index 00000000..d6ee38cc --- /dev/null +++ b/apps/docs/pages/_home/HowItWorks.astro @@ -0,0 +1,49 @@ +--- +import { contentHref } from "blume/components/content/base-href.ts"; + +const steps = [ + { + title: "Index", + body: "One local SQLite map of structure", + }, + { + title: "Query", + body: "SQL or bundled recipe", + }, + { + title: "Join", + body: "Compose tables in one predicate", + }, +]; +--- + +
+
+

+ How it works. +

+
+ +
+ { + steps.map((step, i) => ( +
+

+ {String(i + 1).padStart(2, "0")} +

+

{step.title}

+

{step.body}

+
+ )) + } +
+ + +
diff --git a/apps/docs/pages/_home/InstallBox.astro b/apps/docs/pages/_home/InstallBox.astro new file mode 100644 index 00000000..32557512 --- /dev/null +++ b/apps/docs/pages/_home/InstallBox.astro @@ -0,0 +1,31 @@ +--- +import CodeBlock from "blume/components/content/CodeBlock.astro"; +import Icon from "blume/components/Icon.astro"; + +const installCommand = "bunx @stainless-code/codemap"; +--- + +
+ + {/* Strip CodeBlock chrome — chip owns the frame; keep Shiki tokens. */} +
+ +
+ +
diff --git a/apps/docs/pages/_home/UseCases.astro b/apps/docs/pages/_home/UseCases.astro new file mode 100644 index 00000000..f5b42ad3 --- /dev/null +++ b/apps/docs/pages/_home/UseCases.astro @@ -0,0 +1,59 @@ +--- +import { contentHref } from "blume/components/content/base-href.ts"; + +const cases = [ + { + question: "Where is createCodemap defined?", + recipe: "find-symbol-definitions", + }, + { + question: "Which tests does this change touch?", + recipe: "affected-tests", + }, + { + question: "What depends on this file?", + recipe: "fan-in", + }, +]; +--- + +
+
+

+ Ask structure, not grep. +

+

+ Common agent questions map to one bundled recipe — CLI, MCP, or HTTP. +

+
+ +
+ { + cases.map((item) => ( + + + {item.question} + + + {item.recipe} + + → + + + + )) + } +
+ + +
diff --git a/apps/docs/pages/_home/source-snippets.ts b/apps/docs/pages/_home/source-snippets.ts new file mode 100644 index 00000000..884943ea --- /dev/null +++ b/apps/docs/pages/_home/source-snippets.ts @@ -0,0 +1,12 @@ +export interface CliSnippet { + id: string; + lang: string; + code: string; +} + +/** Single hero CLI example — no live demo islands. */ +export const cliSnippet: CliSnippet = { + id: "find-symbol-definitions", + lang: "bash", + code: "codemap query --recipe find-symbol-definitions --params name=createCodemap", +}; diff --git a/apps/docs/pages/index.astro b/apps/docs/pages/index.astro new file mode 100644 index 00000000..e6200c37 --- /dev/null +++ b/apps/docs/pages/index.astro @@ -0,0 +1,49 @@ +--- +import PageLayout from "blume/components/layout/PageLayout.astro"; +import data from "blume:data"; +import Batteries from "./_home/Batteries.astro"; +import FinalCta from "./_home/FinalCta.astro"; +import Hero from "./_home/Hero.astro"; +import HowItWorks from "./_home/HowItWorks.astro"; +import UseCases from "./_home/UseCases.astro"; +import Footer from "../components/blume/Footer.astro"; + +const { config } = data; +const pageTitle = `${config.title} — Query your codebase.`; + +const copyScript = `(()=>{const CHECK='';document.addEventListener("click",async(e)=>{const b=e.target.closest("[data-blume-copy-install]");if(!b){return;}try{await navigator.clipboard.writeText(b.dataset.command);}catch{return;}const o=b.innerHTML;b.innerHTML=CHECK;setTimeout(()=>{b.innerHTML=o;},1500);});})();`; +--- + + +
+ + + + + +
+