From d6f04beb831a0a16e9eeec3c2c1eb9a3def59db1 Mon Sep 17 00:00:00 2001 From: Sutu Sebastian Date: Mon, 6 Jul 2026 20:54:18 +0300 Subject: [PATCH 1/6] adopt persist repo practices: release, CI, .agents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Release: npm trusted publishing (OIDC, no NPM_TOKEN) + Sigstore provenance. CI: least-priv perms, SHA-pinned checkout + persist-credentials:false, check-pack job, audit blocks on high/critical, dependabot. Tooling: check:pack (attw+publint), :changes scripts, coverage threshold, AGENTS.md stub. .agents: adopt persist thin-rule + skill-decomposition format — slim 5 rules, split 4 monolith skills, add 10 new skills, merge preserve/concise into authoring-discipline, add architecture-priming. --- .agents/rules/agents-first-convention.md | 6 + .agents/rules/agents-tier-system.md | 93 +---- .agents/rules/architecture-priming.md | 26 ++ .agents/rules/authoring-discipline.md | 25 ++ .agents/rules/concise-comments.md | 58 --- .agents/rules/docs-governance.md | 56 +-- .agents/rules/preserve-comments.md | 22 -- .agents/rules/tracer-bullets.md | 68 +--- .agents/rules/verify-after-each-step.md | 47 +-- .agents/skills/agents-tier-system/SKILL.md | 66 ++++ .agents/skills/ask-agents/SKILL.md | 47 +++ .agents/skills/authoring-discipline/PROSE.md | 29 ++ .agents/skills/authoring-discipline/SKILL.md | 13 + .agents/skills/docs-governance/LIFECYCLE.md | 227 ++++++++++++ .agents/skills/docs-governance/SKILL.md | 235 +----------- .agents/skills/docs-lifecycle-sweep/SKILL.md | 76 +--- .../skills/docs-lifecycle-sweep/WORKFLOW.md | 59 +++ .../skills/domain-modeling/GLOSSARY-ENTRY.md | 44 +++ .../skills/domain-modeling/GLOSSARY-SCAN.md | 71 ++++ .agents/skills/domain-modeling/SKILL.md | 67 ++++ .agents/skills/grill-me/SKILL.md | 9 +- .agents/skills/grill-with-docs/ARTIFACTS.md | 109 ++++++ .agents/skills/grill-with-docs/SKILL.md | 9 + .agents/skills/grilling/SKILL.md | 49 +++ .agents/skills/harden-pr/SKILL.md | 278 +------------- .agents/skills/harden-pr/WORKFLOW.md | 279 ++++++++++++++ .../REFERENCE.md | 174 +++++++++ .agents/skills/pr-comment-fact-check/SKILL.md | 163 +------- .../skills/pr-comment-fact-check/WORKFLOW.md | 147 ++++++++ .agents/skills/tdd/PATTERNS.md | 90 +++++ .agents/skills/tdd/SKILL.md | 55 +++ .agents/skills/tracer-bullets/SKILL.md | 59 +++ .../skills/verify-after-each-step/SKILL.md | 52 +++ .agents/skills/write-a-skill/SKILL.md | 145 ++------ .agents/skills/writing-agents-config/SKILL.md | 80 ++++ .../skills/writing-great-skills/GLOSSARY.md | 181 +++++++++ .agents/skills/writing-great-skills/SKILL.md | 82 +++++ .changeset/README.md | 2 +- .cursor/rules/architecture-priming.mdc | 1 + .cursor/rules/authoring-discipline.mdc | 1 + .cursor/rules/concise-comments.mdc | 1 - .cursor/rules/preserve-comments.mdc | 1 - .cursor/skills/agents-tier-system | 1 + .cursor/skills/ask-agents | 1 + .cursor/skills/authoring-discipline | 1 + .cursor/skills/domain-modeling | 1 + .cursor/skills/grill-with-docs | 1 + .cursor/skills/grilling | 1 + .cursor/skills/tdd | 1 + .cursor/skills/tracer-bullets | 1 + .cursor/skills/verify-after-each-step | 1 + .cursor/skills/writing-agents-config | 1 + .cursor/skills/writing-great-skills | 1 + .github/dependabot.yml | 22 ++ .github/workflows/ci.yml | 89 ++++- .github/workflows/release.yml | 35 +- AGENTS.md | 21 ++ bun.lock | 348 +++++++++++++----- docs/packaging.md | 10 +- package.json | 32 +- scripts/run-on-changed-files.ts | 36 ++ src/package-scripts.test.ts | 5 +- tsconfig.json | 9 +- 63 files changed, 2632 insertions(+), 1288 deletions(-) create mode 100644 .agents/rules/architecture-priming.md create mode 100644 .agents/rules/authoring-discipline.md delete mode 100644 .agents/rules/concise-comments.md delete mode 100644 .agents/rules/preserve-comments.md create mode 100644 .agents/skills/agents-tier-system/SKILL.md create mode 100644 .agents/skills/ask-agents/SKILL.md create mode 100644 .agents/skills/authoring-discipline/PROSE.md create mode 100644 .agents/skills/authoring-discipline/SKILL.md create mode 100644 .agents/skills/docs-governance/LIFECYCLE.md create mode 100644 .agents/skills/docs-lifecycle-sweep/WORKFLOW.md create mode 100644 .agents/skills/domain-modeling/GLOSSARY-ENTRY.md create mode 100644 .agents/skills/domain-modeling/GLOSSARY-SCAN.md create mode 100644 .agents/skills/domain-modeling/SKILL.md create mode 100644 .agents/skills/grill-with-docs/ARTIFACTS.md create mode 100644 .agents/skills/grill-with-docs/SKILL.md create mode 100644 .agents/skills/grilling/SKILL.md create mode 100644 .agents/skills/harden-pr/WORKFLOW.md create mode 100644 .agents/skills/improve-codebase-architecture/REFERENCE.md create mode 100644 .agents/skills/pr-comment-fact-check/WORKFLOW.md create mode 100644 .agents/skills/tdd/PATTERNS.md create mode 100644 .agents/skills/tdd/SKILL.md create mode 100644 .agents/skills/tracer-bullets/SKILL.md create mode 100644 .agents/skills/verify-after-each-step/SKILL.md create mode 100644 .agents/skills/writing-agents-config/SKILL.md create mode 100644 .agents/skills/writing-great-skills/GLOSSARY.md create mode 100644 .agents/skills/writing-great-skills/SKILL.md create mode 120000 .cursor/rules/architecture-priming.mdc create mode 120000 .cursor/rules/authoring-discipline.mdc delete mode 120000 .cursor/rules/concise-comments.mdc delete mode 120000 .cursor/rules/preserve-comments.mdc create mode 120000 .cursor/skills/agents-tier-system create mode 120000 .cursor/skills/ask-agents create mode 120000 .cursor/skills/authoring-discipline create mode 120000 .cursor/skills/domain-modeling create mode 120000 .cursor/skills/grill-with-docs create mode 120000 .cursor/skills/grilling create mode 120000 .cursor/skills/tdd create mode 120000 .cursor/skills/tracer-bullets create mode 120000 .cursor/skills/verify-after-each-step create mode 120000 .cursor/skills/writing-agents-config create mode 120000 .cursor/skills/writing-great-skills create mode 100644 .github/dependabot.yml create mode 100644 AGENTS.md create mode 100644 scripts/run-on-changed-files.ts diff --git a/.agents/rules/agents-first-convention.md b/.agents/rules/agents-first-convention.md index 9c08bbb7..5bd6ccdf 100644 --- a/.agents/rules/agents-first-convention.md +++ b/.agents/rules/agents-first-convention.md @@ -16,6 +16,8 @@ When creating **any** new rule or skill, follow this convention: ln -s ../../.agents/rules/.md .cursor/rules/.mdc ``` +**Naming:** Tier-2 priming rules that pair with a skill use `-priming.md` when the rule name would otherwise differ from the skill folder. When names already match, no suffix. + ## Skills (`SKILL.md` files) 1. Create the directory and file in `.agents/skills//SKILL.md` @@ -25,6 +27,8 @@ When creating **any** new rule or skill, follow this convention: ln -s ../../.agents/skills/ .cursor/skills/ ``` +**Never** name bulk reference files `AGENTS.md` inside skill folders — use `FULL-GUIDE.md` or topic siblings. + ## Why - `.agents/` is the **source of truth** — it is IDE-agnostic and works across different AI coding tools. @@ -35,3 +39,5 @@ When creating **any** new rule or skill, follow this convention: - Never place original rule/skill content directly in `.cursor/rules/` or `.cursor/skills/`. - Never create a rule or skill without both the `.agents/` file and the `.cursor/` symlink. + +Related: [`agents-tier-system.md`](./agents-tier-system.md) · [`AGENTS.md`](../../AGENTS.md). diff --git a/.agents/rules/agents-tier-system.md b/.agents/rules/agents-tier-system.md index 12a3c9b7..b7429752 100644 --- a/.agents/rules/agents-tier-system.md +++ b/.agents/rules/agents-tier-system.md @@ -8,90 +8,23 @@ globs: alwaysApply: false --- -# `.agents/` tier system +# `.agents/` tier system — priming -Cursor rules support three attachment modes. Each new rule must consciously pick one. +Three attachment modes: **always-on** (`alwaysApply: true`), **auto-attached** (`globs:`), **intent** (`description:` only). -| Mode | Frontmatter | Cost per turn | Use for | -| ----------------- | ----------------------------------------------------- | ------------------------------------------- | ----------------------------------------------------------------------------- | -| **Always-on** | `alwaysApply: true` | full rule body always loaded | cross-cutting **practices** — define how we work, not what we build | -| **Auto-attached** | `alwaysApply: false` + `globs:` | zero unless a matching file is in scope | technical **patterns** — what we write under `.agents/**`, `src/cli/**`, etc. | -| **Discoverable** | `alwaysApply: false` + `description:` only (no globs) | zero unless description matches user intent | intent-driven **workflows** — the user said "do X" | +**Tier 1 budget:** owner-set; currently ~10 always-on rules + `lessons.md` (≤250 lines total). The frontmatter audit is the source of truth — **no hardcoded Tier 1 name lists** in rule, skill, or README. Audit: -## Tiers in this repo +```bash +for f in .agents/rules/*.md .agents/lessons.md; do + awk '/^---$/{c++; next} c==1 && /^alwaysApply: true$/{found=1; exit} END{exit !found}' "$f" && echo "$f" +done +``` -### Tier 1 — Always-on practices (~10 rules max) - -Genuinely cross-cutting. Apply to every turn regardless of file: - -- `agents-first-convention` — `.agents/` source-of-truth + `.cursor/` symlinks discipline -- `codemap` — STOP-before-grep -- `concise-comments` — sweep your own new comments before reporting -- `concise-reporting` — extreme concision in agent reports -- `lessons` — read when relevant; lift durable ones into rules/skills -- `no-bypass-hooks` — never `--no-verify` on `git commit` -- `pr-comment-fact-check` — fires the fact-check skill on PR-comment intent triggers -- `preserve-comments` — never silently delete TODOs / commented-out code -- `tracer-bullets` — small end-to-end slices, not horizontal layers -- `consumer-surfaces` — consumer-facing text describes user-visible behavior only -- `verify-after-each-step` — run the project's checks per milestone, not at commit time - -### Tier 2 — Auto-attached technical rules (this rule's tier) - -Glob-attached. Each is a thin priming layer (~30–50 lines: top-N principles + `Reference` section pointing at the deep-dive skill). - -Skills get a paired Tier-2 rule when they have **always-on principles** that should fire whenever the relevant files are in scope (e.g. when codemap grows a TS-specific style rule, it would attach to `**/*.{ts,tsx}`). - -Today's Tier-2 rules: - -- `agents-tier-system` (this rule) — auto-attaches when authoring under `.agents/**` or `.cursor/**`. -- `docs-governance` — primes the docs framework when authoring under `docs/**` or `.agents/**` (paired with [`docs-governance` skill](../skills/docs-governance/SKILL.md)). -- `plan-pr-inspiration-discipline` — primes plan-PR / recipe authoring with the open-spec inspection list when authoring under `docs/plans/**` or `templates/recipes/**`. The canonical inspection-sources table lives in the rule body itself. - -### Tier 3 — Discoverable skills (no rule) - -Pure intent-triggered. The skill description is detailed enough that Cursor surfaces it on relevant phrases. No always-on cost. - -Skills stay rule-less when the work is **explicitly invoked** by the user, not pattern-triggered. Today: `audit-pr-architecture`, `codemap` (consumer pointer), `diagnose`, `docs-governance`, `docs-lifecycle-sweep`, `grill-me`, `harden-pr`, `improve-codebase-architecture`, `pr-comment-fact-check`, `write-a-skill`. (Skills like `gritql-codemods` and `ubiquitous-language` would also fit this tier if adopted.) - -## Authoring guidelines - -### Adding a new rule - -1. **Decide the tier** before writing. -2. **Tier 1 needs justification** — does it really apply to every turn? If it only applies in certain files / certain intents, demote to Tier 2 or Tier 3. -3. **Tier 2 globs** — write the broadest pattern that's still meaningfully scoped. `**/*.ts` is acceptable for TS-wide rules. Filename heuristics (`*recipe*.ts`) are brittle for content-driven concerns and should be a last resort. -4. **Tier 3 description** — write the description as if Cursor is grepping for trigger phrases. Include the verbs and nouns the user is likely to say ("rename", "delete", "convert", "consolidate") and the symbols / patterns the agent will see in code. -5. **Pair with a skill** — every Tier-1 / Tier-2 rule should link to a skill in its `Reference` section for the deep dive. The rule is priming; the skill is reference. -6. **Author the source under `.agents/rules/.md` and symlink from `.cursor/rules/.mdc`** per the [`agents-first-convention`](./agents-first-convention.md) rule. - -### Adding a new skill - -1. **Decide if it needs a rule.** If the skill has always-on principles (any `NEVER` / `ALWAYS` clauses, any "MUST be used when") — pair it with a Tier-1 or Tier-2 rule. -2. **If skill-only**, write the description with explicit trigger phrases. Cursor's discovery is description-match-based. -3. **Author under `.agents/skills//SKILL.md` and symlink from `.cursor/skills/`** per the [`agents-first-convention`](./agents-first-convention.md) rule. - -## Authoring discipline: durability - -Rules and skills are **more durable** than the artifacts they describe. They outlive specific files, specific commit hashes, specific code shapes. Authoring them as if they were short-lived is the most common way they go stale. - -Three concrete sub-rules: - -1. **Don't cite specific audit / plan / research filenames as canonical examples.** Audits and plans are mortal under [`docs-lifecycle-sweep`](../skills/docs-lifecycle-sweep/SKILL.md) (Tier C delete or Tier B slim). The first time the doc janitor retires a file your skill named, the skill's example rots. Use shape placeholders (`-.md`, `.md`) and describe the **shape** of what the next reader should look for ("the most recent audit under `docs/audits/`"), not which file does it today. **Reference docs (`README.md`, `architecture.md`, `glossary.md`, `roadmap.md`, `agents.md`) ARE durable** — citing them by name is fine; they live forever per their lifecycle type. -2. **Don't cite specific commit hashes or PR numbers as the only path to context.** Hashes and PR URLs are stable but opaque. If the context matters, summarise it inline. Hashes are good as **secondary** anchors ("the seed datapoint, commit ``") not primary ones. -3. **Don't cite specific source-code line numbers.** Same drift as above; lines move on every edit. Reference symbols by name. (Same hazard as [`docs/README.md` Rule 7](../../docs/README.md) — universal, not codemap-specific.) - -When in doubt: if the prose still reads correctly six months from now after every doc you didn't write got rewritten or deleted, the skill is durable. If it reads as a stale snapshot, slim the citations to placeholders. - -## Audit prompts - -When reviewing an existing rule: - -- **Is it Tier 1?** Check: does it apply on every turn? If it only applies to TS files, flip to Tier 2 with a glob. -- **Is it Tier 2?** Check: are the globs well-scoped? Could broader globs catch content-driven cases? Could narrower globs save context without losing coverage? -- **Is it skill-only?** Check: does the skill have any "always" / "never" clauses? If yes, it deserves a rule. +**When authoring:** pick tier before writing; pair fat rules with skills; symlinks per [`agents-first-convention`](./agents-first-convention.md). Default to intent-triggered skills and a thin always-on set. ## Reference -- File-layout convention: [`agents-first-convention.md`](./agents-first-convention.md). -- The docs-governance pair this tier system was first applied to in this repo: [`docs-governance.md` rule](./docs-governance.md) (Tier-2 priming) + [`docs-governance` skill](../skills/docs-governance/SKILL.md) (deep reference). +- Full assignments, checklist, pairing examples: [`agents-tier-system` skill](../skills/agents-tier-system/SKILL.md) +- Codemap deltas + size tiers: [`writing-agents-config`](../skills/writing-agents-config/SKILL.md) +- Router index: [`AGENTS.md`](../../AGENTS.md) +- Architecture priming: [`architecture-priming.md`](./architecture-priming.md) diff --git a/.agents/rules/architecture-priming.md b/.agents/rules/architecture-priming.md new file mode 100644 index 00000000..0ff2bd40 --- /dev/null +++ b/.agents/rules/architecture-priming.md @@ -0,0 +1,26 @@ +--- +description: STOP and run architecture skills before structurally significant changes (module moves, schema/boundary, new exports, agent template layering) +alwaysApply: true +--- + +# Architecture priming + +Most code changes are line-level — a parser fix, a CLI flag, a query recipe. They don't need architectural review. **A small minority of changes are structurally significant** and pay back compound interest if reviewed before they land. This rule fires the architecture skills on those signals only, not on every edit. + +## STOP if any of these apply + +- **≥5 files moved** between top-level `src/` modules (e.g. `src/cli/` → sibling folder) +- **New `src//` module** — a new top-level source subtree +- **Schema or boundary change** in `src/db.ts` (`SCHEMA_VERSION`, new tables/columns with cross-module impact) +- **New subpath export** in `package.json` `exports` +- **`templates/agent-content` vs `templates/agents` layering breach** — consumer-served content mixed with init-copied templates (see [`consumer-surfaces`](./consumer-surfaces.md)) + +For each signal: STOP and run [`improve-codebase-architecture`](../skills/improve-codebase-architecture/SKILL.md) before proceeding; on open PRs or post-merge, also [`audit-pr-architecture`](../skills/audit-pr-architecture/SKILL.md). + +## Otherwise, proceed normally + +Line-level changes **do not trigger this rule**. Use intent-triggered skills (`harden-pr`, `diagnose`, etc.). + +## Reference + +[`improve-codebase-architecture`](../skills/improve-codebase-architecture/SKILL.md) · [`audit-pr-architecture`](../skills/audit-pr-architecture/SKILL.md) · [`tracer-bullets`](./tracer-bullets.md) · [`docs/architecture.md`](../../docs/architecture.md) diff --git a/.agents/rules/authoring-discipline.md b/.agents/rules/authoring-discipline.md new file mode 100644 index 00000000..c8318db7 --- /dev/null +++ b/.agents/rules/authoring-discipline.md @@ -0,0 +1,25 @@ +--- +description: Authoring discipline for code comments, docs, and committed prose — preserve existing comments, keep new prose concise. +alwaysApply: true +--- + +# Authoring discipline (STOP) + +**Prose depth:** [`authoring-discipline/PROSE.md`](../skills/authoring-discipline/PROSE.md). **Doc lifecycle:** [`docs-governance`](../skills/docs-governance/SKILL.md). + +## Preserve existing source comments (non-negotiable) + +1. **Never remove comments** — preserve when editing; update if outdated, don't delete. +2. **Never remove TODO / FIXME / HACK** — ask user before removing completed TODOs. +3. **Never remove commented-out code** — ask before removal. +4. **StrReplace** — copy comments into `new_string`; move comments when restructuring. + +User-requested **doc audits** may slim redundant markdown; preservation above applies to **source** comments only. + +## New prose (defaults) + +- **Decision test:** could a teammate re-derive this in 30s? → cut it (details in [`PROSE.md`](../skills/authoring-discipline/PROSE.md)). +- **JSDoc as types (`.mjs`, `@ts-check`):** `@typedef`, `@param`, `@returns`, inline `@type` are the type system — keep them; apply the decision test only to prose in those blocks. +- **End-of-turn:** cut duplicate tables/narration; after doc slim → [`docs-governance`](../skills/docs-governance/SKILL.md) slimming audit. + +Related: [`concise-reporting`](./concise-reporting.md) · [`docs-lifecycle-sweep`](../skills/docs-lifecycle-sweep/SKILL.md). diff --git a/.agents/rules/concise-comments.md b/.agents/rules/concise-comments.md deleted file mode 100644 index 39116d8c..00000000 --- a/.agents/rules/concise-comments.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -description: Sweep your own new comments at the end of every change. Keep what code can't say; cut the rest. -alwaysApply: true ---- - -# Concise Comments - -After you finish a change — before reporting back — re-read the comments **you** authored in that turn. Keep only the ones that carry information the code itself cannot. - -## Decision test - -For every comment you wrote, ask: **"Could a teammate (human or AI) re-derive this from the code in under 30 seconds?"** - -- **Yes** → delete it. The code is the documentation. -- **No** → keep it, slim to one sentence if possible. - -## Keep - -- **Why**, not what — design intent, trade-offs, the rejected alternative. -- **Non-obvious constraints** — SQLite quirks, parser idiosyncrasies, race conditions, ordering requirements. -- **Cross-references** that save grep time — `mirrors X`, `see NOTE(foo)`, `tracked at docs/roadmap.md § Y`. -- **Domain → code translations** — schema-column ↔ JS-field aliases, BE / external-API field aliases. -- **Sentinels and magic values** — `null because oxc-resolver returns null on unresolved`, `0 because SQLite rejects undefined`. - -## Cut - -- Restating the function/variable name (`/** Site id. */ sid: number`). -- Restating the next line of code (`// Reset to page 1` above `setPage(1)`). -- Generic library practice (`// Memoise this` above `useMemo`). -- Section headers in short files (`// === Helpers ===`). -- Author / date stamps (git tracks this). -- Multi-line prose where one clause does the job. -- **Prose inside JSDoc** when `@param` / `@returns` / `@typedef` already carry the meaning — types stay; narrating them does not. - -## Exception: JSDoc as types (`.mjs`, `@ts-check`) - -Untyped JS has no `.ts` surface — **`@typedef`, `@param`, `@returns`, and inline `@type` are the type system; keep them.** Apply the decision test only to **prose** in those blocks (keep non-obvious _why_ like `bunx` vs `bun x`; cut restatements of param names or return shapes). - -## Reconcile with `preserve-comments` - -[`preserve-comments`](./preserve-comments.md) protects **existing** comments — never delete those without asking. - -This rule applies only to comments **you authored in the current turn**. You own them; they earn their keep, or you cut them before handing the work back. - -If you slim or delete a pre-existing comment, that requires explicit user confirmation per [`preserve-comments`](./preserve-comments.md) Rule 4 — this rule does not override that. - -## When to sweep - -- **Always before final report** — make it the last thing you do. -- **After every comment-touching edit during a long session** — don't accumulate noise across turns. -- **If you find yourself writing 3+ lines of prose for one decision** — stop, ask whether a one-liner with a code reference would do. - -## Length budget (rule of thumb) - -- **0 lines** — when the code is self-explanatory. -- **1 line** — default for kept comments. -- **2–3 lines** — only when context is genuinely irreducible (e.g. a parser-shape gotcha with two failure modes). -- **>3 lines** — extract to a `docs/` file and link to it. diff --git a/.agents/rules/docs-governance.md b/.agents/rules/docs-governance.md index 5d4cbd1a..d1f494ec 100644 --- a/.agents/rules/docs-governance.md +++ b/.agents/rules/docs-governance.md @@ -1,56 +1,18 @@ --- -description: Repo-wide docs framework primer. Use when authoring or editing any docs/, plans/, research/, or other doc-bearing surface in the repo. Defines surface tiers (repo-wide / per-tooling-area), the 5 lifecycle types, the existence test, anchor-preservation discipline, and the delete-and-lift plan lifecycle. Skill at `.agents/skills/docs-governance/SKILL.md` carries the full reference. -globs: "docs/**, .agents/**" +description: Docs governance primer — read docs-governance skill before authoring docs/**, README, or .agents/** docs. +globs: + - "docs/**" + - ".agents/**" + - ".cursor/**" alwaysApply: false --- -# Docs governance +# Docs governance (priming) -Before authoring or editing any doc in this repo, **read the [`docs-governance` skill](../skills/docs-governance/SKILL.md)** for the full reference. This rule is the priming layer. +Before authoring or editing any doc, **read the [`docs-governance` skill](../skills/docs-governance/SKILL.md)**. The canonical Rules (1–10) live in [`docs/README.md`](../../docs/README.md) — cite them by number; never restate them. Consumer-surface policy: [`.agents/rules/consumer-surfaces.md`](./consumer-surfaces.md) (Rule 10 sub-bullet). -## Surface tiers (which subset of governance applies) +Lifecycle types, surface tiers, existence test, anti-bloat, and cross-reference discipline live in the skill — not duplicated here. -| Tier | Substrate | Examples | -| ------------------------------- | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -| **B** — repo-wide cross-cutting | `docs/` at repo root | `docs/architecture.md`, `docs/glossary.md`, `docs/roadmap.md`, `docs/agents.md`, `docs/plans/`, `docs/research/`, future `docs/audits/` | -| **0** — per-tooling-area | `.agents/`, `.cursor/`, `scripts/`, `templates/agents/` | Governed by [`agents-first-convention`](./agents-first-convention.md) + [`agents-tier-system`](./agents-tier-system.md); no per-area README needed | - -(Tier C — per-feature governance — and Tier A — per-shared-component — don't apply yet; see [`docs-governance` § Doc-bearing surface tiers](../skills/docs-governance/SKILL.md#doc-bearing-surface-tiers) for when they would.) - -## Five lifecycle types (universal) - -| Type | Folder | Closing | -| ------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | -| **Reference** | root (`architecture.md`, `glossary.md`, etc.) | Lives forever; kept current | -| **Roadmap** | root (`roadmap.md`, single file) | Lives forever | -| **Plan** | `plans/.md` | **Delete + lift** when work ships (no "Slim & keep in plans/") | -| **Audit** | `audit.md` (single) OR `audits/.md` (multi) | Substrate variants — see skill | -| **Research** | `research/.md` OR `research/-YYYY-MM.md` | Adopted → lift + **delete** (unless inbound cites require slim stub) / Rejected → status header only / Open | - -## Top three disciplines - -1. **Anchor preservation** — slim READMEs keep cited rule numbers and section anchors. Grep before any slim: `rg "Rule [0-9]+" docs/` and `rg "(#[a-z-]+)?"`. -2. **Anti-bloat meta-rule** — don't add a rule until there's content that needs it. Same for ownership-table rows. -3. **Repo-level vs in-source** — repo-wide tool evaluations + adoption (oxlint, future plugins) live in `.agents/`, not as permanent `docs/research/` files. A `docs/research/` file may motivate the adoption, but the rule + skill earn the permanent home. Per-tool tracker notes (peer-tool comparisons, adoption-candidate logs) are an anti-pattern — peer-tool framing goes off-mission fast; positioning lives in [`docs/why-codemap.md`](../../docs/why-codemap.md), not in tracker files. - -## Existence test (apply on every doc-touching PR) - -A file earns its place if it meets at least one of: - -1. Source code cites it (JSDoc, error message, comment grep-anchor) -2. It documents durable policy unavailable elsewhere -3. It tracks open work (audit findings, in-flight plan, roadmap items, evaluation with unresolved items) -4. Inbound source cites require a slim stub — deletion would orphan a live citation (not "interesting history") - -If none → fold + delete. - -## Reference - -- Full reference: [`.agents/skills/docs-governance/SKILL.md`](../skills/docs-governance/SKILL.md) -- Doc janitor (operational sweep — apply the spec mechanically, classify Tier A / B / C, delete dead weight): [`.agents/skills/docs-lifecycle-sweep/SKILL.md`](../skills/docs-lifecycle-sweep/SKILL.md). Fire on intent ("clean up stale docs", "compact audits") or proactively after closing a Plan / Audit / Research file. -- Audit framework: [`.agents/skills/audit-pr-architecture/SKILL.md`](../skills/audit-pr-architecture/SKILL.md). Fire on intent ("audit this PR's architecture", "structural review of #N") or proactively when a PR moves ≥5 files between top-level `src/` modules. -- Canonical Rules: [`docs/README.md`](../../docs/README.md) — Rules 1–10 cited from across `docs/` and `.agents/`. Don't renumber without a coordinated re-grep + edit pass. -- File-layout: [`agents-first-convention`](./agents-first-convention.md) -- Rules vs skills tier system: [`agents-tier-system`](./agents-tier-system.md) +Janitor sweep: [`docs-lifecycle-sweep`](../skills/docs-lifecycle-sweep/SKILL.md). diff --git a/.agents/rules/preserve-comments.md b/.agents/rules/preserve-comments.md deleted file mode 100644 index cb4d84d5..00000000 --- a/.agents/rules/preserve-comments.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -description: Never remove comments, TODOs, or commented-out code without explicit confirmation -alwaysApply: true ---- - -# Preserve Comments, TODOs, and Commented Code - -## Rules - -1. **Never remove comments** — All existing comments must be preserved when editing code. If a comment becomes outdated due to your changes, update it rather than deleting it. - -2. **Never remove TODO / FIXME / HACK comments** — These are intentional markers left by developers. If a TODO is completed by your changes, ask the user before removing it. - -3. **Never remove commented-out code** — Commented-out code exists for a reason (debugging, future use, reference). Do not silently delete it. - -4. **Ask before removing** — If you believe a TODO, comment, or commented-out code block should be removed, explicitly ask the user for confirmation before doing so. - -## When editing code - -- Copy over all comments that exist in the original code block you are replacing. -- If restructuring code, move comments to their new logical location rather than dropping them. -- When using StrReplace, ensure the `old_string` and `new_string` both account for any comments in the affected region. diff --git a/.agents/rules/tracer-bullets.md b/.agents/rules/tracer-bullets.md index fbfe9e55..817f8465 100644 --- a/.agents/rules/tracer-bullets.md +++ b/.agents/rules/tracer-bullets.md @@ -3,68 +3,18 @@ description: Build features in small end-to-end slices, not big horizontal layer alwaysApply: true --- -# Tracer Bullets +# Tracer bullets -When building features, build a tiny end-to-end slice first, validate it works, then expand. - -## Why - -AI agents tend to produce complete solutions in one leap — all parsers, all schema, all docs — without ever testing whether the critical path works. This creates massive review burden and rework ("slop"). +Build a tiny end-to-end slice first, validate, then expand. AI agents tend to produce complete solutions in one leap without testing the critical path — massive review burden and rework ("slop"). ## Rules -1. **Start with one vertical slice** that touches all relevant layers for the simplest case -2. **Commit and validate** that slice before expanding — the pre-commit hook will run format, lint, typecheck, and tests on staged files (when AI/agent env vars trigger it) -3. **Lite-harden the slice** — run [`harden-pr`](../skills/harden-pr/SKILL.md) in **lite** mode (parallel reviewers → fix in-bounds → up to 2 passes). When the user has asked for commits: one `harden: …` commit before the next slice. Does not change feature intent — production polish only. -4. **Expand outward** from the working slice in subsequent commits -5. **Never build horizontal layers in isolation** (e.g. all DB helpers before any CLI wiring, or all docs before any working index path) - -## Feature layers in this project - -A typical vertical slice for Codemap touches these layers top-to-bottom: - -1. **CLI / orchestration** — `src/cli/` (`bootstrap.ts`, `main.ts`, lazy `cmd-*` chunks; entry `src/index.ts`) -2. **Workers / parsing** — `src/parse-worker.ts` / `parse-worker-node.ts`, `parse-worker-core.ts`, `src/parser.ts`, `src/css-parser.ts`, `src/adapters/` -3. **Persistence** — `src/db.ts` (schema, inserts, `SCHEMA_VERSION`) -4. **Config / runtime** — `src/config.ts`, `src/runtime.ts`, resolver -5. **Tests** — `src/*.test.ts` -6. **Docs** — `docs/*.md` when behavior is user-visible - -## Example 1: Support a new source extension - -Bad — building in layers: - -- Update every glob, parser, and docs in one giant change -- Hope CI and the index agree - -Good — tracer bullet: - -1. **`constants` + adapter** — `LANG_MAP` + builtin adapter extensions + `extractFileData` — commit, `bun run check`, small test parsing a one-line file -2. **Resolver** — `resolver` extensions if needed — commit, validate -3. **Docs** — `docs/architecture.md` table row — commit, validate - -## Example 2: Add a new SQLite column or table - -Bad — schema + all call sites + benchmarks in one unreviewable diff. - -Good — tracer bullet: - -1. **Schema + insert path** — `db.ts` + one write path exercised by a test or CLI run — commit, validate -2. **Readers / query UX** — expose in `query` or docs — commit, validate -3. **Benchmark / fixtures** — if numbers matter — separate commit - -## Example 3: New CLI flag - -Bad — flag parsing, help text, config, and tests all speculative. - -Good — tracer bullet: - -1. **Parse flag + minimal behavior** — e.g. `--dry-run` that only logs — commit, test -2. **Wire to real work** — connect to indexer — commit, validate -3. **Document** — README / `docs/architecture.md` — commit - -## Commit cadence +1. **One vertical slice** — touches all relevant layers for the simplest case (CLI + parser + db + test, etc.). +2. **Commit and validate** before expanding — pre-commit runs format, lint, typecheck, tests on staged files (when AI/agent env vars trigger it). +3. **Lite-harden the slice** — [`harden-pr`](../skills/harden-pr/SKILL.md) **lite** mode after each slice (fix in working tree; commit when the user asks). +4. **Expand outward** from the working slice. +5. **Never build horizontal layers in isolation** (all DB helpers before any CLI wiring, all docs before any working index path, etc.). -Each commit should represent a functional, describable milestone — not a placeholder. Every tracer bullet is a shippable slice that works end-to-end, even if the feature isn't complete yet. Small commits get validated by the pre-commit hook and are easier to review and revert. +Feature layers and worked examples: [`tracer-bullets` skill](../skills/tracer-bullets/SKILL.md). -Before opening a PR, run [`harden-pr`](../skills/harden-pr/SKILL.md) in **full** mode on `origin/main...HEAD` (or accept the offer when the plan checklist is complete). +Before opening a PR: [`harden-pr`](../skills/harden-pr/SKILL.md) **full** on `origin/main...HEAD`. diff --git a/.agents/rules/verify-after-each-step.md b/.agents/rules/verify-after-each-step.md index b19c48e1..e5d7a2e4 100644 --- a/.agents/rules/verify-after-each-step.md +++ b/.agents/rules/verify-after-each-step.md @@ -3,46 +3,21 @@ description: After each working milestone, verify changed files using the same c alwaysApply: true --- -# Verify Changed Files After Each Step +# Verify after each step -After completing a step, phase, or milestone, verify every file you touched using the project's existing checks. Don't wait for `git commit` — the pre-commit hook is a safety net, not a first line of defense. +After completing a step, verify every file you touched — don't wait for `git commit`. The pre-commit hook is a safety net, not a first line of defense. -## Why +## What counts as a step -AI agents tend to chain many edits across files and only discover breakage at commit time. By then the failing context is stale and the fix is harder. Running checks after each working milestone keeps the codebase green continuously. +Tracer-bullet slice, plan TODO, refactor, parser/CLI flag/schema change, bug fix, review comment. -## Discover Project Scripts - -1. **Read `package.json` `scripts`** at the start of a task to know available commands. -2. **Read `lint-staged.config.js`** (or equivalent) to know which checks apply to which file patterns. -3. Never assume script names — always verify they exist in `package.json` before running them. - -## Current Per-File Checks (from `lint-staged.config.js`) - -| File pattern | Checks | -| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `*.{js,jsx,ts,tsx,mjs,mts,cjs,cts}` | `bun run format:check`, `bun run lint` | -| `*.{css,json,md,mdc,html,yaml,yml}` | `bun run format:check` | -| `*.{ts,tsx}` | `bun run typecheck` with a temporary `tsconfig.lint-staged.json` that includes only **staged files under `src/`** (project-wide types still interconnect — use `bun run typecheck` if you need full-project certainty); **`bun test`** on co-located `*.test.{ts,tsx}` pairs when a staged `src/` source file is present but its test file is not | -| `*.test.ts` | `bun test` (on changed test files) | -| `*.test.tsx` | `bun test` (on changed test files) | -| `scripts/**/*.test.mjs` | `bun test` (on changed test files) | - -## What Counts as a Step - -A "step" is any self-contained unit of work where you've finished editing and are about to move on: +## Rules -- Completed a TODO / action item from a plan -- Finished a tracer-bullet slice (see tracer-bullets rule) -- Refactored or moved code across files -- Added or modified a parser, CLI flag, schema, or test -- Fixed a bug or addressed a review comment +1. **Verify after every step** — run checks matching touched file patterns before moving on. +2. **Fix before moving on** — never carry forward known failures. +3. **Use the right scope** — lint/format on specific files when possible; `bun run typecheck` when types may be affected; `bun test ` when a `src/` module changed. +4. **Run affected tests** — co-located `*.test.ts` / `*.test.tsx` pair when `src/` source changed; `scripts/**/*.test.mjs` when touched. -## Rules +**Full per-file check table** (lint-staged, Codemap re-index): [`verify-after-each-step`](../skills/verify-after-each-step/SKILL.md). -1. **Verify after every step** — Run the matching checks on every file you touched during that step before moving to the next one. -2. **Fix before moving on** — If any check fails, fix it immediately while context is fresh. Never carry forward known failures. -3. **Use the right scope** — Run `bun run lint` and `bun run format:check` on specific files when possible. Prefer `bun run typecheck` project-wide when types may depend on unstaged files. -4. **Run affected tests** — If you modified or created `*.test.ts` / `*.test.tsx` / `scripts/**/*.test.mjs` files, run `bun test ` on them; if you changed a `src/` source file with a co-located test, run that pair even when the test file itself is unstaged. -5. **Re-index before querying Codemap** — If you changed indexed source and plan to run SQL against the structural index next, run `bun src/index.ts --files ` with paths **relative to the indexed project root** (set `CODEMAP_TEST_BENCH` / `CODEMAP_ROOT` or `--root` so that root is correct — see [docs/benchmark.md § Indexing another project](../../docs/benchmark.md#indexing-another-project)). -6. **Don't duplicate the hook's job** — You don't need to re-verify at commit time; the pre-commit hook (`lint-staged`) handles that automatically when AI/agent env vars trigger it. Your job is to stay green _between_ commits. +Related: [`no-bypass-hooks`](./no-bypass-hooks.md) · [`tracer-bullets`](./tracer-bullets.md) · [`harden-pr`](../skills/harden-pr/SKILL.md). diff --git a/.agents/skills/agents-tier-system/SKILL.md b/.agents/skills/agents-tier-system/SKILL.md new file mode 100644 index 00000000..d0d51e44 --- /dev/null +++ b/.agents/skills/agents-tier-system/SKILL.md @@ -0,0 +1,66 @@ +--- +name: agents-tier-system +description: Full tier assignments, pairing conventions, and authoring checklist for .agents/ rules and skills. Use when creating or reviewing a rule or skill, deciding Tier 1 vs 2 vs 3, or auditing attachment cost. +--- + +# `.agents/` tier system — full reference + +Always-on priming: [`.agents/rules/agents-tier-system.md`](../../rules/agents-tier-system.md). Entry points: [`AGENTS.md`](../../../AGENTS.md), [`agents-first-convention`](../../rules/agents-first-convention.md), [`writing-agents-config`](../writing-agents-config/SKILL.md). + +## Discover on disk (do not maintain partial catalogs here) + +| Tier | How to list | +| ---------- | ------------------------------------------------------------------------------------------------------ | +| **Tier 1** | Frontmatter audit in [`agents-tier-system` rule](../../rules/agents-tier-system.md) — budget set there | +| **Tier 2** | `ls .agents/rules/*.md` + `globs:` in frontmatter | +| **Tier 3** | `alwaysApply: false`, no `globs:` — intent via `description` | +| **Skills** | `ls .agents/skills` — runtime discovery via descriptions | + +**Pairing examples in this repo:** `consumer-surfaces` (Tier 1, always-on); `docs-governance` (Tier 2 globs) ↔ `docs-governance` + `docs-lifecycle-sweep`; `architecture-priming` ↔ `improve-codebase-architecture` + `audit-pr-architecture`; `agents-tier-system` rule + skill; `authoring-discipline` rule + `PROSE.md`; `verify-after-each-step` rule + skill; `codemap` (skill-only); `harden-pr` (skill-only). + +**Caution:** avoid stacking broad globs without thin priming bodies. + +## Authoring guidelines + +### Adding a new rule + +1. **Decide the tier** before writing. +2. **Tier 1 needs justification** — every turn? If file/intent scoped, demote to Tier 2 or Tier 3. +3. **Tier 2 globs** — broadest meaningful scope; pair with skill when applicable. +4. **Source + symlink** per [`agents-first-convention`](../../rules/agents-first-convention.md). + +### Adding a new skill + +1. **Needs a rule?** Hard `NEVER`/`ALWAYS` + file-scoped work → Tier 2 priming rule. +2. **Skill-only** — explicit trigger phrases in description. +3. **User-only orchestrator** — `disable-model-invocation: true` + delegate to model skill. +4. **Size** — [`writing-agents-config`](../writing-agents-config/SKILL.md) § SKILL.md size tiers. + +### Tier 1 audit command + +```bash +for f in .agents/rules/*.md .agents/lessons.md; do + awk '/^---$/{c++; next} c==1 && /^alwaysApply: true$/{found=1; exit} END{exit !found}' "$f" && echo "$f" +done +``` + +**Done when:** tier choice justified; pairing checklist satisfied; Tier-1 audit command run when adding always-on rules. + +## Authoring discipline: durability + +Rules and skills are **more durable** than the artifacts they describe. They outlive specific files, specific commit hashes, specific code shapes. Authoring them as if they were short-lived is the most common way they go stale. + +Three concrete sub-rules: + +1. **Don't cite specific audit / plan / research filenames as canonical examples.** Audits and plans are mortal under [`docs-lifecycle-sweep`](../docs-lifecycle-sweep/SKILL.md) (Tier C delete or Tier B slim). The first time the doc janitor retires a file your skill named, the skill's example rots. Use shape placeholders (`-.md`, `.md`) and describe the **shape** of what the next reader should look for ("the most recent audit under `docs/audits/`"), not which file does it today. **Reference docs (`README.md`, `architecture.md`, `glossary.md`, `roadmap.md`, `agents.md`) ARE durable** — citing them by name is fine; they live forever per their lifecycle type. +2. **Don't cite specific commit hashes or PR numbers as the only path to context.** Hashes and PR URLs are stable but opaque. If the context matters, summarise it inline. Hashes are good as **secondary** anchors ("the seed datapoint, commit ``") not primary ones. +3. **Don't cite specific source-code line numbers.** Same drift as above; lines move on every edit. Reference symbols by name. (Same hazard as [`docs/README.md` Rule 7](../../../docs/README.md) — universal, not codemap-specific.) + +When in doubt: if the prose still reads correctly six months from now after every doc you didn't write got rewritten or deleted, the skill is durable. If it reads as a stale snapshot, slim the citations to placeholders. + +## Reference + +- Skill authoring SSOT: [`writing-great-skills`](../writing-great-skills/SKILL.md) +- Codemap deltas: [`writing-agents-config`](../writing-agents-config/SKILL.md) +- File-layout: [`agents-first-convention.md`](../../rules/agents-first-convention.md) +- Tier-1 priming rule: [`.agents/rules/agents-tier-system.md`](../../rules/agents-tier-system.md) diff --git a/.agents/skills/ask-agents/SKILL.md b/.agents/skills/ask-agents/SKILL.md new file mode 100644 index 00000000..6d0f967f --- /dev/null +++ b/.agents/skills/ask-agents/SKILL.md @@ -0,0 +1,47 @@ +--- +name: ask-agents +description: Which user-only agent workflow to run — grilling, docs-aware grilling, or meta authoring help. +disable-model-invocation: true +--- + +# Ask agents (router) + +Zero context load — you pick the workflow. + +## The main flow: idea → ship + +1. **`/grill-with-docs`** — sharpen the idea; inline updates to `docs/` (architecture / roadmap / glossary / plans) as decisions land. No codebase yet? Use **`/grill-me`** (standalone below). +2. **Branch — multi-session build?** + - **Yes** → capture plan in **`docs/plans/.md`** → split into GitHub issues. Fresh session per issue. + - **No** → tracer bullets + **`tdd`** + workflow skills appropriate to this repo in the same window. +3. **`/harden-pr`** — lite after each tracer slice; full before PR ready. + +### Context hygiene + +Keep grilling + plan authoring in **one window** until issues are filed. Each implement session starts fresh from the plan/issue. If the window nears the smart zone, write a compact plan in `docs/plans/`. + +## Codebase health (not feature work) + +- **`/improve-codebase-architecture`** — surface deepening opportunities; pick one → back to main flow at grill-with-docs. +- **`/diagnose`** — hard bugs and perf regressions (model-invoked skill — not a router target). +- Periodic hygiene: **`/docs-lifecycle-sweep`** on `docs/` (model-invoked). + +## Crossing sessions + +- **`/compact`** — built-in: same session, summarized history — use only at phase breaks. +- **Fresh session** — start from `docs/plans/.md` or the GitHub issue. + +## Standalone + +| Invoke | When | +| -------------------------------------------------------------- | ----------------------------------------------- | +| [`grill-me`](../grill-me/SKILL.md) | Sharpen a plan with **no** codebase (stateless) | +| [`writing-great-skills`](../writing-great-skills/SKILL.md) | Skill vocabulary + principles | +| [`writing-agents-config`](../writing-agents-config/SKILL.md) | Codemap repo tier/pairing deltas | +| [`domain-modeling`](../domain-modeling/SKILL.md) | Ubiquitous language inline + batch glossary | +| [`tdd`](../tdd/SKILL.md) | RED→GREEN tracer-bullet TDD | +| [`verify-after-each-step`](../verify-after-each-step/SKILL.md) | Per-file checks after each milestone | +| [`diagnose`](../diagnose/SKILL.md) | Debug loop for hard bugs | +| [`write-a-skill`](../write-a-skill/SKILL.md) | Author a new skill in this repo | + +Meta: [`agents-tier-system`](../agents-tier-system/SKILL.md). diff --git a/.agents/skills/authoring-discipline/PROSE.md b/.agents/skills/authoring-discipline/PROSE.md new file mode 100644 index 00000000..498d377d --- /dev/null +++ b/.agents/skills/authoring-discipline/PROSE.md @@ -0,0 +1,29 @@ +# Authoring discipline — prose depth + +Companion to always-on [`.agents/rules/authoring-discipline.md`](../../rules/authoring-discipline.md). Doc lifecycle: [`docs-governance`](../docs-governance/SKILL.md), [`docs-lifecycle-sweep`](../docs-lifecycle-sweep/SKILL.md). + +## § Concise new prose (comments, JSDoc, docs) + +**Decision test:** Could a teammate re-derive this from the code in under 30 seconds? Yes → cut it. + +**Keep:** why (not what), non-obvious constraints, cross-cutting context, pointers when a relationship isn't obvious, sentinels/magic values, the rejected alternative, SQLite/parser quirks (`SCHEMA_VERSION` bumps, `oxc-resolver` returning null on unresolved paths, batch insert caps). + +**Cut:** file inventories, pasted signatures, restating the next line, generic library practice, duplicate facts across README/architecture/glossary, tallied counts of re-derivable items ("42 recipes", "158 tests") — the number goes stale the moment it changes and turns into errored info; the items (a table, a folder) carry the story, the number doesn't. + +**Comments/JSDoc:** 0 lines when self-explanatory; 1 line default; 2–3 only for irreducible gotchas; `>3 lines` → lift to `docs/` with one-line pointer. The shipped `.d.mts` should read well in hovers — `@param` / `@returns` / `@default` / `@example` (with real, resolving imports) carry the meaning when usage isn't obvious; types stay, narrating them does not. + +**Exception — JSDoc as types (`.mjs`, `@ts-check`):** Untyped JS has no `.ts` surface — **`@typedef`, `@param`, `@returns`, and inline `@type` are the type system; keep them.** Apply the decision test only to **prose** in those blocks (keep non-obvious _why_; cut restatements of param names or return shapes). + +**Historical traces** in committed prose — "indexed on …", "following up on …", changelog-edit residue, stale rosters — earn no ROI once the moment passes; write as if fresh, cut the trace. Source comments: the rule's "update if outdated" covers them. + +**Doc slimming:** full checklists in [`docs-governance`](../docs-governance/SKILL.md) (anchor preservation, existence test, anti-bloat). + +## End-of-turn sweep + +**When to sweep:** + +- **Always before the final report** — make it the last thing you do. +- **After every comment-touching edit during a long session** — don't accumulate noise across turns. +- **If you find yourself writing 3+ lines of prose for one decision** — stop, ask whether a one-liner with a code reference would do. + +Before completing a turn that touched code or docs: cut duplicated tables and narration. After a doc slim, confirm runtime invariants (schema version, recipe catalog contract, index freshness semantics) and public-API surface still have a home ([`docs-governance`](../docs-governance/SKILL.md) slimming audit). diff --git a/.agents/skills/authoring-discipline/SKILL.md b/.agents/skills/authoring-discipline/SKILL.md new file mode 100644 index 00000000..9458c335 --- /dev/null +++ b/.agents/skills/authoring-discipline/SKILL.md @@ -0,0 +1,13 @@ +--- +name: authoring-discipline +description: Prose depth for comments, JSDoc, and docs — concise comments, preserve existing source comments. +disable-model-invocation: true +--- + +# Authoring discipline — prose depth + +Always-on priming: [`.agents/rules/authoring-discipline.md`](../../rules/authoring-discipline.md). + +Full checklists and examples: [`PROSE.md`](./PROSE.md). + +Related: [`docs-governance`](../docs-governance/SKILL.md), [`docs-lifecycle-sweep`](../docs-lifecycle-sweep/SKILL.md), [`writing-great-skills`](../writing-great-skills/SKILL.md). diff --git a/.agents/skills/docs-governance/LIFECYCLE.md b/.agents/skills/docs-governance/LIFECYCLE.md new file mode 100644 index 00000000..dc5acf82 --- /dev/null +++ b/.agents/skills/docs-governance/LIFECYCLE.md @@ -0,0 +1,227 @@ +# Docs governance — repo-wide blueprint + +Every doc in this repo lives in one of **two surface tiers** (codemap is small enough that the per-feature and per-shared-component tiers used in larger codebases don't apply here — yet). Each tier inherits the same **shared spine** (lifecycle types, existence test, naming, anti-bloat discipline) and applies a **substrate subset** appropriate to its scope. The repo-root `docs/README.md` is the single canonical surface for the cited Rules — every other doc points at it; never restate the Rules. + +--- + +## Doc-bearing surface tiers + +| Tier | Substrate | Examples today | Governance shape | +| ------------------------------------ | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Tier B** — repo-wide cross-cutting | `docs/` at repo root | `docs/architecture.md`, `docs/glossary.md`, `docs/roadmap.md`, `docs/plans/`, `docs/research/`, `docs/agents.md`, `docs/benchmark.md`, `docs/golden-queries.md`, `docs/packaging.md`, `docs/why-codemap.md` | Single `docs/README.md` carrying the **canonical numbered Rules** + ownership table + lifecycle prescription; cross-cutting reference docs at the root; `plans/`, `research/`, and (when needed) `audits/` substrate folders | +| **Tier 0** — per-tooling-area | `.agents/`, `.cursor/`, `scripts/` | `.agents/rules/`, `.agents/skills/`, `.cursor/rules/` (symlinks), `.cursor/skills/` (symlinks), `templates/agents/` (bundled for `codemap agents init`) | Implicit governance via [`agents-first-convention`](../../rules/agents-first-convention.md) + [`agents-tier-system`](../../rules/agents-tier-system.md); no per-area `README.md` needed; the rules + skills are themselves the docs and earn their place per § 2 below | + +The same shared spine applies to both. The differences are what subset each tier needs. + +> **Why no Tier C / Tier A in codemap?** Tier C (per-feature governance) only kicks in when a codebase grows independently-evolving feature folders (`app/features//`). Tier A (per-shared-component) only kicks in when shared components accumulate enough rationale to need a `README.md` next to the source. Codemap has neither today — the source tree is `src/cli/`, `src/application/`, `src/adapters/`, `src/parser.ts`, `src/db.ts`, etc., all governed by the central `docs/` surface. If codemap ever grows a `src//` partition or a `src/components//` shared-component substrate worth documenting in-place, this skill grows the corresponding tier rows then — not before (per § 5 anti-bloat). + +--- + +## Shared spine (applies to every tier) + +### 1. Five lifecycle types + +Every doc fits one of these. New content folds into an existing type or earns a new top-level home — it does not spawn a new type. + +| Type | Folder | Lifecycle | +| ------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | +| **Reference** | root of the surface (`architecture.md`, `glossary.md`, `agents.md`, etc.) | Lives forever. Kept current per the per-tier rules below | +| **Roadmap** | root (`roadmap.md`, single file per surface) | Lives forever. Items move in (new findings) and out (per "When something ships") | +| **Plan** | `plans/.md` | Created when work commits. Closed per § Closing a plan below | +| **Audit** | `audit.md` (single substrate) OR `audits/.md` (multi substrate) | Created at audit time. Closed per § Closing an audit below | +| **Research** | `research/.md` OR `research/-YYYY-MM.md` for dated scans | Created when an evaluation begins. Closed per § Closing research below | + +Backlogs, frameworks, decisions, and ephemeral notes do not get their own top-level file. They fold into one of the five: + +- **Backlogs** of open items → a section in `roadmap.md` +- **Frameworks / playbooks** that emerged from an audit → stay in the audit while it's kept; lift into a reference doc (or `.agents/rules/` / `.agents/skills/` for project-wide policy) if the audit gets retired +- **Decisions of record** from a concluded research evaluation → lift into the relevant reference doc; the research file's job is the evaluation, not the decision + +### 2. Existence test (apply on every doc-touching PR) + +A file earns its place if it meets at least one of: + +1. **Source code cites it** (JSDoc, error message, comment grep-anchor, cited rule number, file path reference) +2. **It documents durable policy or framework** unavailable elsewhere +3. **It tracks open work** (open audit findings, in-flight plan, roadmap items, ongoing evaluation) +4. **Inbound source cites require a slim stub** — live citations by path/anchor would orphan on delete. (Not "interesting history" — if only git could reconstruct it, delete.) + +If none → fold any salvageable content into `roadmap.md` / `architecture.md` / the relevant reference doc, fix the cross-refs, delete the file. + +### 3. Naming conventions + +- **`plans/` files**: `.md` — the folder provides "plan" context; don't add a `-plan` suffix +- **`research/` files**: `.md` for ongoing tool evaluations; `-YYYY-MM.md` for dated competitive scans +- **`audits/` files**: `-.md` for dated targeted audits OR `.md` for ongoing topic audits +- **Top-level reference files**: descriptive domain name (e.g. `architecture.md`, `glossary.md`, `agents.md`) +- All files: kebab-case + +### 4. `.gitkeep` discipline + +Every potentially-empty docs subdirectory carries a `.gitkeep` so the directory is discoverable even when empty: + +```text +docs/ +├── plans/.gitkeep # required even when plans/ is empty +└── research/.gitkeep # required even when research/ is empty +``` + +Subdirectories without `.gitkeep` signal "this convention isn't expected here" — the absence is informative. (Codemap doesn't ship an `audits/` folder today; if the first audit lands, that's when `audits/.gitkeep` shows up alongside it.) + +### 5. Anti-bloat meta-rule + +**Don't add a rule until there's content that needs it.** Speculative governance rules accumulate noise without enforcement. Each rule must point at concrete content (a file, a pattern, a citation) it governs. + +Same applies to ownership-table rows — a row exists when the file or folder it describes exists. + +### 6. Repo-level vs in-source clarification + +**Codemap-wide tool evaluations + adoption** (e.g. oxlint, future plugins) belong directly in `.agents/rules/` + `.agents/skills/` — not in `docs/research/`. The artifact that earns a permanent home isn't the evaluation; it's the rule + skill. + +A `docs/research/` file may **motivate** adoption of a repo-level tool, but the _adoption itself_ is repo-level — the rule lands under `.agents/rules/`, not as a permanent doc under `docs/research/`. The research note is **deleted** after lift (per [`docs/README.md` Rule 8](../../../docs/README.md)). **Per-tool tracker notes are an anti-pattern** — peer-tool framing goes off-mission fast; positioning lives in [`docs/why-codemap.md`](../../../docs/why-codemap.md), not in tracker files. + +### 7. Cross-reference preservation discipline + +Before slimming or moving any doc with rules or named sections cited from source code or other docs: + +```bash +# Grep every reference to the doc + its anchors +rg "(#[a-z-]+)?" . +rg "Rule [0-9]+" +rg "@see.*" src/ scripts/ +``` + +Then: + +- **Preserve cited rule numbers** — if `Rule 6` is referenced from source, keep `Rule 6` in `docs/README.md`. Renumbering breaks grep-anchors silently. +- **Preserve cited section anchors** — if `#closing-a-plan` is referenced, keep the `## Closing a plan` heading in the slim README so the anchor still resolves. +- **If renumbering is unavoidable**, update every citation in the same commit. +- **Re-grep after slim** to confirm no broken references. +- **Don't maintain enumerated cross-reference indexes inline.** A line like _"Cited from `audit.md`, `audits/.md`, `testing.md`"_ is a hand-maintained index that drifts on every slim. The grep command IS the index — cite the command (`rg "Rule [0-9]+" `) and let it re-derive on demand. Same logic as inventory counts ([`docs/README.md` Rule 6](../../../docs/README.md)): hand-maintained snapshots of mechanical facts always rot. + +This is the most important migration discipline. Anchor breakage is silent and degrades over time. + +### 8. Provenance pattern (optional today) + +If a future tier (per-feature, per-component) opens up, every per-surface README should cite this skill in its opening section: + +```md +> **Governance:** This README follows the [docs-governance skill](../../../.agents/skills/docs-governance/SKILL.md). Below: -specific scope, ownership extensions, and deliberate omissions. +``` + +Slim per-surface README content = scope statement + ownership table for **surface-specific** files only + surface-specific rules (with same numbers as before if any are cited from source) + deliberate-omissions section + provenance line. Everything else (lifecycle types, existence test, closing states, naming, anti-bloat) stays in this skill. + +Today, codemap has only the repo-root `docs/README.md` (Tier B). It doesn't strictly need a provenance line because it _is_ the canonical surface — but it should still link to this skill from its "Document Lifecycle" section for the deeper reference. (Today it does so implicitly via the rule it cites; promoting that to a direct skill link is fine.) + +--- + +## Lifecycle prescriptions per type + +### Closing an audit + +Codemap doesn't ship an `audits/` folder today. When the first audit lands, choose substrate per: + +| Substrate | When to use | Closing | +| ---------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Single-file `audit.md`** | One rolling audit doc | When all open items resolve: lift deferred items to `roadmap.md`; **delete** if re-derivable test passes; else **slim** to cited findings + durable policy only. `"Last verified"` headers apply to **open** audits only — not closed stubs | +| **Multi-file `audits/.md`** | Multiple targeted audit passes worth keeping side-by-side | Per audit: **No source cites AND no unique policy** → digest deferred items into `roadmap.md` (or absorb into a reference doc), then **delete** the audit file (no tombstones in living docs). **Has source cites OR unique policy** → **slim** to the cited findings + the durable policy; add a `Status: Closed` header; file stays in `audits/`. Recovery pointers belong in the absorbing plan's provenance block or git history — not a maintained index | + +**The re-derivable test (positive framing of "no source cites AND no unique policy").** Before keeping a closed audit, ask: _would a fresh audit run today re-derive every finding from current code (codemap query, static-analysis tooling, grep, schema)?_ If yes and nothing in source points back to this file by name, the audit's only remaining job is historical archaeology — `git log --follow` does that better than a stale snapshot. **Delete it.** Three things an audit can carry that the codebase cannot infer, and that earn a slim+keep: + +1. **Decisions of record** with rejected alternatives ("we kept X at root because Y; the Z alternative was considered and rejected because…"). Code shows the result, not the rejection rationale. +2. **Source-back-references** — `NOTE(...)` markers, JSDocs, or test names that cite the audit by file. Deletion would orphan them. +3. **Reusable methodology / playbook** that doesn't already live in a skill (the SQL queries, the verification recipe). If it does live in a skill, lift any deltas and delete. + +If none of the three apply: digest deferred items to `roadmap.md`, lift any orphan-able knowledge, then delete. No tombstones. + +**Promote single → multi when the second targeted audit lands.** Don't preemptively split. + +### Closing a plan + +The _one_ lifecycle, no "Slim & keep in plans/" option: + +- **Default — delete + lift.** When work ships, the plan's durable bits move to where they earn a permanent home; the plan file dies. Lift destinations: + - **Caller-facing convention** → `architecture.md` (or a topic-split sibling under `architecture/.md` if `architecture.md` ever needs splitting) + - **New domain term** → `glossary.md` entry + - **Slim-but-coherent durable policy with source cites** → lift into `.agents/rules/` / `.agents/skills/` or a **live** reference section — not a closed stub in `audits/` unless source already cites that audit path + - **Project-wide policy** → `.agents/rules/` / `.agents/skills/` + - **Decision-of-record from external evaluation** → already covered by § Closing research +- **In-flight or deferred** → stays in `plans/` with no status header (open is the default). +- **No "Slim & keep in plans/" state.** A shipped doc that's worth keeping for rejected-alternatives / sequencing-rationale / API-shape-negotiation is no longer a plan; it earned a permanent home elsewhere. Categories should be defined by what the doc is now, not by where it started. + +### Closing research + +A research file's job is the evaluation. When the evaluation concludes, follow the canonical [`docs/README.md` Rule 8](../../../docs/README.md) lifecycle: + +- **Adopted** → lift the decision-of-record into the relevant reference doc (`architecture.md`, `glossary.md`, etc.) or — for repo-level tools — into `.agents/rules/` + `.agents/skills/`. **Delete** the research file once nothing cites it by path. **Do not** leave "What shipped" inventory tables, analytical-history sections, or `git log` / `git show` recovery instructions in living docs — git history is the archive. **Slim + keep** only when inbound source cites would orphan (same bar as audits). **Exception:** § 6 anti-pattern files (per-tool trackers; peer-tool framing) get **deleted**, not slimmed — the framing was off-mission, not just stale, and a slim appendix would re-anchor the wrong mental model. +- **Rejected** → add a `Status: Rejected (date) — ` header at the top. Keep the file. The rejection rationale is exactly what saves the next agent from re-litigating it. +- **Open / Ongoing** → stays in `research/` with no status header (open is the default). Ongoing tool trackers (e.g. `research/.md`) are explicitly long-lived but **only when they aren't peer-tool trackers** — see § 6. + +--- + +## Per-surface subset prescriptions + +### Tier B — repo-wide cross-cutting (the canonical surface today) + +Mandatory: `docs/README.md` — the canonical Rules + ownership table + lifecycle prescription. + +When present, the repo-root `docs/README.md` documents: + +- The cross-cutting reference docs at the root (e.g. `architecture.md`, `glossary.md`, `agents.md`) +- The `plans/`, `research/`, and (if/when) `audits/` substrate folders (folder-level convention; don't enumerate files) +- The numbered Rules — cited from source code and other docs; their numbers are stable per § 7 +- A reference back to this skill for the deep dive +- No "feature-specific" rules — repo-wide concerns only + +### Tier 0 — per-tooling-area + +`.agents/`, `.cursor/`, `scripts/`, `templates/agents/` — no per-area `README.md` needed (with the exception of `templates/agents/README.md`, which exists because the bundled templates ship to npm consumers and the README explains the consumer-vs-maintainer distinction). Governance lives in the rules + skills themselves: + +- File-layout discipline → [`agents-first-convention`](../../rules/agents-first-convention.md) (`.agents/` is source of truth; `.cursor/` is symlinks) +- Tier system for rules → [`agents-tier-system`](../../rules/agents-tier-system.md) + +These rules are themselves docs; they're governed by their own existence test (do they earn their place per § 2?). + +--- + +## Numbering convention for slim per-surface READMEs + +If a future tier brings additional READMEs, they may keep a numbered Rules section as a quick-reference. Numbers are **per-surface stable** (not aligned across surfaces) — `docs/README.md`'s Rule 6 may differ from a future surface's Rule 6. + +**Anchor preservation discipline (per § 7):** + +- If a rule is cited from source code or other docs, the slim README keeps the same number. Substance shrinks to a one-liner: `**Rule 6 — No inventory counts.** See [skill § anti-bloat](path)`. +- Rule numbering may compact (delete a rule that's now in the skill exclusively) only if no citation references its number. +- Any renumbering happens in the same commit as the citation updates. + +For `docs/README.md` today: Rules **1–10** are cited from across `docs/` and `.agents/`. Don't renumber without a coordinated re-grep + edit pass. + +--- + +## Extension discipline + +A per-surface README extends this skill rather than restating it. Concretely: + +- **DO** add surface-specific ownership rows for files that don't fit the universal pattern. +- **DO** add surface-specific rules with concrete examples (e.g. codemap's "no inventory counts in narrative — counts of files / symbols / recipes drift on every PR"). +- **DO** add a deliberate-omissions section (what the surface _deliberately doesn't carry_ and why). +- **DON'T** restate the 5 lifecycle types (skill carries them). +- **DON'T** restate the existence test (skill carries it). +- **DON'T** restate the closing-state lifecycles (skill carries them). +- **DON'T** restate naming conventions (skill carries them). + +If you find yourself copying sections from this skill into a per-surface README, stop — link to the skill section instead. + +--- + +## Consumer surfaces (templates/agent-content layers) + +Shipped agent templates under `templates/agent-content/**` follow the same consumer-vs-maintainer split as [`consumer-surfaces`](../../rules/consumer-surfaces.md) Rule 10: + +| Layer | Audience | What belongs | +| ------------------- | ------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- | +| **Served live** | npm consumers via `codemap skill` / `codemap rule`, MCP `codemap://skill` / `codemap://rule`, HTTP resources | User-visible commands, recipes, query patterns — what to run and what it returns | +| **Bundled copy** | `templates/agents/**` copied by `codemap agents init` | Project-local agent wiring the consumer installs | +| **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. diff --git a/.agents/skills/docs-governance/SKILL.md b/.agents/skills/docs-governance/SKILL.md index 2bda695b..3480bf72 100644 --- a/.agents/skills/docs-governance/SKILL.md +++ b/.agents/skills/docs-governance/SKILL.md @@ -3,229 +3,28 @@ name: docs-governance description: Repo-wide docs framework — what `docs/`, `docs/plans/`, `docs/research/`, `.agents/`, or any other doc-bearing surface in this repo looks like, what lifecycle each doc follows, and how to keep cross-references intact when slimming or moving content. Use when authoring or editing any `docs/**`, `docs/plans/**`, `docs/research/**`, `.agents/rules/**`, `.agents/skills/**`, or any new doc-bearing folder. Defines the lifecycle types (Reference / Roadmap / Plan / Audit / Research), the existence test every doc must pass, the closing-state lifecycles (delete + lift; never "Slim & keep in plans/"), the substrate variants (single `audit.md` vs `audits/.md`; conditional `glossary.md`), the surface tiers (repo-wide / per-tooling-area), and the cross-reference preservation discipline (grep before slim; preserve rule numbers cited from source). The Tier-2 priming layer at `.agents/rules/docs-governance.md` cites this skill and extends with codemap-specific bits only. --- -# Docs governance — repo-wide blueprint +# Docs governance -Read [`.agents/rules/docs-governance.md`](../../rules/docs-governance.md) first for the priming rule and quick reference. This file is the canonical blueprint. +Repo-wide docs framework for codemap. Every doc in this repo lives in one of **two surface tiers** (codemap is small enough that the per-feature and per-shared-component tiers used in larger codebases don't apply here — yet). **Full blueprint:** [LIFECYCLE.md](./LIFECYCLE.md). -Every doc in this repo lives in one of **two surface tiers** (codemap is small enough that the per-feature and per-shared-component tiers used in larger codebases don't apply here — yet). Each tier inherits the same **shared spine** (lifecycle types, existence test, naming, anti-bloat discipline) and applies a **substrate subset** appropriate to its scope. The repo-root `docs/README.md` is the single canonical surface for the cited Rules — every other doc points at it; never restate the Rules. +The repo-root `docs/README.md` is the single canonical surface for the cited Rules — every other doc points at it; never restate the Rules. Consumer-surface policy: [`.agents/rules/consumer-surfaces.md`](../../rules/consumer-surfaces.md) (Rule 10 sub-bullet). ---- - -## Doc-bearing surface tiers - -| Tier | Substrate | Examples today | Governance shape | -| ------------------------------------ | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Tier B** — repo-wide cross-cutting | `docs/` at repo root | `docs/architecture.md`, `docs/glossary.md`, `docs/roadmap.md`, `docs/plans/`, `docs/research/`, `docs/agents.md`, `docs/benchmark.md`, `docs/golden-queries.md`, `docs/packaging.md`, `docs/why-codemap.md` | Single `docs/README.md` carrying the **canonical numbered Rules** + ownership table + lifecycle prescription; cross-cutting reference docs at the root; `plans/`, `research/`, and (when needed) `audits/` substrate folders | -| **Tier 0** — per-tooling-area | `.agents/`, `.cursor/`, `scripts/` | `.agents/rules/`, `.agents/skills/`, `.cursor/rules/` (symlinks), `.cursor/skills/` (symlinks), `templates/agents/` (bundled for `codemap agents init`) | Implicit governance via [`agents-first-convention`](../../rules/agents-first-convention.md) + [`agents-tier-system`](../../rules/agents-tier-system.md); no per-area `README.md` needed; the rules + skills are themselves the docs and earn their place per § 2 below | - -The same shared spine applies to both. The differences are what subset each tier needs. - -> **Why no Tier C / Tier A in codemap?** Tier C (per-feature governance) only kicks in when a codebase grows independently-evolving feature folders (`app/features//`). Tier A (per-shared-component) only kicks in when shared components accumulate enough rationale to need a `README.md` next to the source. Codemap has neither today — the source tree is `src/cli/`, `src/application/`, `src/adapters/`, `src/parser.ts`, `src/db.ts`, etc., all governed by the central `docs/` surface. If codemap ever grows a `src//` partition or a `src/components//` shared-component substrate worth documenting in-place, this skill grows the corresponding tier rows then — not before (per § 5 anti-bloat). - ---- - -## Shared spine (applies to every tier) - -### 1. Five lifecycle types - -Every doc fits one of these. New content folds into an existing type or earns a new top-level home — it does not spawn a new type. - -| Type | Folder | Lifecycle | -| ------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | -| **Reference** | root of the surface (`architecture.md`, `glossary.md`, `agents.md`, etc.) | Lives forever. Kept current per the per-tier rules below | -| **Roadmap** | root (`roadmap.md`, single file per surface) | Lives forever. Items move in (new findings) and out (per "When something ships") | -| **Plan** | `plans/.md` | Created when work commits. Closed per § Closing a plan below | -| **Audit** | `audit.md` (single substrate) OR `audits/.md` (multi substrate) | Created at audit time. Closed per § Closing an audit below | -| **Research** | `research/.md` OR `research/-YYYY-MM.md` for dated scans | Created when an evaluation begins. Closed per § Closing research below | - -Backlogs, frameworks, decisions, and ephemeral notes do not get their own top-level file. They fold into one of the five: - -- **Backlogs** of open items → a section in `roadmap.md` -- **Frameworks / playbooks** that emerged from an audit → stay in the audit while it's kept; lift into a reference doc (or `.agents/rules/` / `.agents/skills/` for project-wide policy) if the audit gets retired -- **Decisions of record** from a concluded research evaluation → lift into the relevant reference doc; the research file's job is the evaluation, not the decision - -### 2. Existence test (apply on every doc-touching PR) - -A file earns its place if it meets at least one of: - -1. **Source code cites it** (JSDoc, error message, comment grep-anchor, cited rule number, file path reference) -2. **It documents durable policy or framework** unavailable elsewhere -3. **It tracks open work** (open audit findings, in-flight plan, roadmap items, ongoing evaluation) -4. **Inbound source cites require a slim stub** — live citations by path/anchor would orphan on delete. (Not "interesting history" — if only git could reconstruct it, delete.) - -If none → fold any salvageable content into `roadmap.md` / `architecture.md` / the relevant reference doc, fix the cross-refs, delete the file. - -### 3. Naming conventions - -- **`plans/` files**: `.md` — the folder provides "plan" context; don't add a `-plan` suffix -- **`research/` files**: `.md` for ongoing tool evaluations; `-YYYY-MM.md` for dated competitive scans -- **`audits/` files**: `-.md` for dated targeted audits OR `.md` for ongoing topic audits -- **Top-level reference files**: descriptive domain name (e.g. `architecture.md`, `glossary.md`, `agents.md`) -- All files: kebab-case - -### 4. `.gitkeep` discipline - -Every potentially-empty docs subdirectory carries a `.gitkeep` so the directory is discoverable even when empty: +## Quick rules -```text -docs/ -├── plans/.gitkeep # required even when plans/ is empty -└── research/.gitkeep # required even when research/ is empty -``` - -Subdirectories without `.gitkeep` signal "this convention isn't expected here" — the absence is informative. (Codemap doesn't ship an `audits/` folder today; if the first audit lands, that's when `audits/.gitkeep` shows up alongside it.) - -### 5. Anti-bloat meta-rule - -**Don't add a rule until there's content that needs it.** Speculative governance rules accumulate noise without enforcement. Each rule must point at concrete content (a file, a pattern, a citation) it governs. - -Same applies to ownership-table rows — a row exists when the file or folder it describes exists. - -### 6. Repo-level vs in-source clarification - -**Codemap-wide tool evaluations + adoption** (e.g. oxlint, future plugins) belong directly in `.agents/rules/` + `.agents/skills/` — not in `docs/research/`. The artifact that earns a permanent home isn't the evaluation; it's the rule + skill. - -A `docs/research/` file may **motivate** adoption of a repo-level tool, but the _adoption itself_ is repo-level — the rule lands under `.agents/rules/`, not as a permanent doc under `docs/research/`. The research note is **deleted** after lift (per [`docs/README.md` Rule 8](../../../docs/README.md)). **Per-tool tracker notes are an anti-pattern** — peer-tool framing goes off-mission fast; positioning lives in [`docs/why-codemap.md`](../../../docs/why-codemap.md), not in tracker files. - -### 7. Cross-reference preservation discipline - -Before slimming or moving any doc with rules or named sections cited from source code or other docs: - -```bash -# Grep every reference to the doc + its anchors -rg "(#[a-z-]+)?" . -rg "Rule [0-9]+" -rg "@see.*" src/ scripts/ -``` - -Then: - -- **Preserve cited rule numbers** — if `Rule 6` is referenced from source, keep `Rule 6` in `docs/README.md`. Renumbering breaks grep-anchors silently. -- **Preserve cited section anchors** — if `#closing-a-plan` is referenced, keep the `## Closing a plan` heading in the slim README so the anchor still resolves. -- **If renumbering is unavoidable**, update every citation in the same commit. -- **Re-grep after slim** to confirm no broken references. -- **Don't maintain enumerated cross-reference indexes inline.** A line like _"Cited from `audit.md`, `audits/.md`, `testing.md`"_ is a hand-maintained index that drifts on every slim. The grep command IS the index — cite the command (`rg "Rule [0-9]+" `) and let it re-derive on demand. Same logic as inventory counts ([`docs/README.md` Rule 6](../../../docs/README.md)): hand-maintained snapshots of mechanical facts always rot. - -This is the most important migration discipline. Anchor breakage is silent and degrades over time. - -### 8. Provenance pattern (optional today) - -If a future tier (per-feature, per-component) opens up, every per-surface README should cite this skill in its opening section: - -```md -> **Governance:** This README follows the [docs-governance skill](../../../.agents/skills/docs-governance/SKILL.md). Below: -specific scope, ownership extensions, and deliberate omissions. -``` - -Slim per-surface README content = scope statement + ownership table for **surface-specific** files only + surface-specific rules (with same numbers as before if any are cited from source) + deliberate-omissions section + provenance line. Everything else (lifecycle types, existence test, closing states, naming, anti-bloat) stays in this skill. - -Today, codemap has only the repo-root `docs/README.md` (Tier B). It doesn't strictly need a provenance line because it _is_ the canonical surface — but it should still link to this skill from its "Document Lifecycle" section for the deeper reference. (Today it does so implicitly via the rule it cites; promoting that to a direct skill link is fine.) - ---- - -## Lifecycle prescriptions per type - -### Closing an audit - -Codemap doesn't ship an `audits/` folder today. When the first audit lands, choose substrate per: - -| Substrate | When to use | Closing | -| ---------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Single-file `audit.md`** | One rolling audit doc | When all open items resolve: lift deferred items to `roadmap.md`; **delete** if re-derivable test passes; else **slim** to cited findings + durable policy only. `"Last verified"` headers apply to **open** audits only — not closed stubs | -| **Multi-file `audits/.md`** | Multiple targeted audit passes worth keeping side-by-side | Per audit: **No source cites AND no unique policy** → digest deferred items into `roadmap.md` (or absorb into a reference doc), then **delete** the audit file (no tombstones in living docs). **Has source cites OR unique policy** → **slim** to the cited findings + the durable policy; add a `Status: Closed` header; file stays in `audits/`. Recovery pointers belong in the absorbing plan's provenance block or git history — not a maintained index | - -**The re-derivable test (positive framing of "no source cites AND no unique policy").** Before keeping a closed audit, ask: _would a fresh audit run today re-derive every finding from current code (codemap query, static-analysis tooling, grep, schema)?_ If yes and nothing in source points back to this file by name, the audit's only remaining job is historical archaeology — `git log --follow` does that better than a stale snapshot. **Delete it.** Three things an audit can carry that the codebase cannot infer, and that earn a slim+keep: - -1. **Decisions of record** with rejected alternatives ("we kept X at root because Y; the Z alternative was considered and rejected because…"). Code shows the result, not the rejection rationale. -2. **Source-back-references** — `NOTE(...)` markers, JSDocs, or test names that cite the audit by file. Deletion would orphan them. -3. **Reusable methodology / playbook** that doesn't already live in a skill (the SQL queries, the verification recipe). If it does live in a skill, lift any deltas and delete. - -If none of the three apply: digest deferred items to `roadmap.md`, lift any orphan-able knowledge, then delete. No tombstones. - -**Promote single → multi when the second targeted audit lands.** Don't preemptively split. - -### Closing a plan - -The _one_ lifecycle, no "Slim & keep in plans/" option: - -- **Default — delete + lift.** When work ships, the plan's durable bits move to where they earn a permanent home; the plan file dies. Lift destinations: - - **Caller-facing convention** → `architecture.md` (or a topic-split sibling under `architecture/.md` if `architecture.md` ever needs splitting) - - **New domain term** → `glossary.md` entry - - **Slim-but-coherent durable policy with source cites** → lift into `.agents/rules/` / `.agents/skills/` or a **live** reference section — not a closed stub in `audits/` unless source already cites that audit path - - **Project-wide policy** → `.agents/rules/` / `.agents/skills/` - - **Decision-of-record from external evaluation** → already covered by § Closing research -- **In-flight or deferred** → stays in `plans/` with no status header (open is the default). -- **No "Slim & keep in plans/" state.** A shipped doc that's worth keeping for rejected-alternatives / sequencing-rationale / API-shape-negotiation is no longer a plan; it earned a permanent home elsewhere. Categories should be defined by what the doc is now, not by where it started. - -### Closing research - -A research file's job is the evaluation. When the evaluation concludes, follow the canonical [`docs/README.md` Rule 8](../../../docs/README.md) lifecycle: - -- **Adopted** → lift the decision-of-record into the relevant reference doc (`architecture.md`, `glossary.md`, etc.) or — for repo-level tools — into `.agents/rules/` + `.agents/skills/`. **Delete** the research file once nothing cites it by path. **Do not** leave "What shipped" inventory tables, analytical-history sections, or `git log` / `git show` recovery instructions in living docs — git history is the archive. **Slim + keep** only when inbound source cites would orphan (same bar as audits). **Exception:** § 6 anti-pattern files (per-tool trackers; peer-tool framing) get **deleted**, not slimmed — the framing was off-mission, not just stale, and a slim appendix would re-anchor the wrong mental model. -- **Rejected** → add a `Status: Rejected (date) — ` header at the top. Keep the file. The rejection rationale is exactly what saves the next agent from re-litigating it. -- **Open / Ongoing** → stays in `research/` with no status header (open is the default). Ongoing tool trackers (e.g. `research/.md`) are explicitly long-lived but **only when they aren't peer-tool trackers** — see § 6. - ---- - -## Per-surface subset prescriptions - -### Tier B — repo-wide cross-cutting (the canonical surface today) - -Mandatory: `docs/README.md` — the canonical Rules + ownership table + lifecycle prescription. - -When present, the repo-root `docs/README.md` documents: - -- The cross-cutting reference docs at the root (e.g. `architecture.md`, `glossary.md`, `agents.md`) -- The `plans/`, `research/`, and (if/when) `audits/` substrate folders (folder-level convention; don't enumerate files) -- The numbered Rules — cited from source code and other docs; their numbers are stable per § 7 -- A reference back to this skill for the deep dive -- No "feature-specific" rules — repo-wide concerns only - -### Tier 0 — per-tooling-area - -`.agents/`, `.cursor/`, `scripts/`, `templates/agents/` — no per-area `README.md` needed (with the exception of `templates/agents/README.md`, which exists because the bundled templates ship to npm consumers and the README explains the consumer-vs-maintainer distinction). Governance lives in the rules + skills themselves: - -- File-layout discipline → [`agents-first-convention`](../../rules/agents-first-convention.md) (`.agents/` is source of truth; `.cursor/` is symlinks) -- Tier system for rules → [`agents-tier-system`](../../rules/agents-tier-system.md) - -These rules are themselves docs; they're governed by their own existence test (do they earn their place per § 2?). - ---- - -## Numbering convention for slim per-surface READMEs - -If a future tier brings additional READMEs, they may keep a numbered Rules section as a quick-reference. Numbers are **per-surface stable** (not aligned across surfaces) — `docs/README.md`'s Rule 6 may differ from a future surface's Rule 6. - -**Anchor preservation discipline (per § 7):** - -- If a rule is cited from source code or other docs, the slim README keeps the same number. Substance shrinks to a one-liner: `**Rule 6 — No inventory counts.** See [skill § anti-bloat](path)`. -- Rule numbering may compact (delete a rule that's now in the skill exclusively) only if no citation references its number. -- Any renumbering happens in the same commit as the citation updates. - -For `docs/README.md` today: Rules **1–9** are cited from across `docs/` and `.agents/`. Don't renumber without a coordinated re-grep + edit pass. - ---- - -## Extension discipline - -A per-surface README extends this skill rather than restating it. Concretely: - -- **DO** add surface-specific ownership rows for files that don't fit the universal pattern. -- **DO** add surface-specific rules with concrete examples (e.g. codemap's "no inventory counts in narrative — counts of files / symbols / recipes drift on every PR"). -- **DO** add a deliberate-omissions section (what the surface _deliberately doesn't carry_ and why). -- **DON'T** restate the 5 lifecycle types (skill carries them). -- **DON'T** restate the existence test (skill carries it). -- **DON'T** restate the closing-state lifecycles (skill carries them). -- **DON'T** restate naming conventions (skill carries them). - -If you find yourself copying sections from this skill into a per-surface README, stop — link to the skill section instead. - ---- +1. **Five lifecycle types** — Reference (`architecture.md`, `glossary.md`, `agents.md`, …), Roadmap (`roadmap.md`), Plan (`plans/.md`), Audit (`audit.md` or `audits/.md`), Research (`research/.md` or `research/-YYYY-MM.md`). New content folds into one of these; no new top-level types. +2. **Existence test** — a doc earns its place if source cites it, it carries durable policy unavailable elsewhere, it tracks open work, or inbound cites require a slim stub. Otherwise fold + delete. +3. **Plans are deleted + lifted when work ships** — durable bits move to `architecture.md` / `glossary.md` / `roadmap.md` / a rule or skill; the plan file dies. No "slim & keep in plans/" state. +4. **`.gitkeep`** in each potentially-empty lifecycle folder (`plans/`, `research/`, and `audits/` when it exists) so it stays discoverable when empty. +5. **Anti-bloat** — don't add a rule until there's content that needs it. Same for ownership-table rows in `docs/README.md`. +6. **Repo-level vs in-source** — codemap-wide tool evaluations + adoption (oxlint, future plugins) live in `.agents/rules/` + `.agents/skills/`, not as permanent `docs/research/` files. Per-tool tracker notes are an anti-pattern — positioning lives in [`docs/why-codemap.md`](../../../docs/why-codemap.md). +7. **Cross-reference preservation** — grep before slim; preserve cited rule numbers and section anchors. See [LIFECYCLE.md § 7](./LIFECYCLE.md#7-cross-reference-preservation-discipline). +8. **Provenance** — `docs/README.md` Rules **1–10** are cited from across `docs/` and `.agents/`. Don't renumber without a coordinated re-grep + edit pass. ## Reference -- [`docs-lifecycle-sweep`](../docs-lifecycle-sweep/SKILL.md) — operationalises this spec on demand: walks any doc surface, applies the existence test + closing prescriptions, classifies each file Tier A (keep verbatim) / Tier B (slim + keep) / Tier C (delete + lift), surfaces evidence + cross-reference impact, executes on user approval. Use whenever you'd otherwise need to read this whole spec and apply it by hand to a folder of accumulated docs. -- [`audit-pr-architecture`](../audit-pr-architecture/SKILL.md) — writes audit docs per § Closing an audit substrate variants. Closure step calls `docs-lifecycle-sweep` on the surrounding `audits/` folder. -- [`docs-governance` rule](../../rules/docs-governance.md) — the Tier-2 priming layer; cites this skill on any doc-touching edit. +- [`docs-lifecycle-sweep`](../docs-lifecycle-sweep/SKILL.md) — the doc janitor; walks doc surfaces and produces a per-file action plan. +- [`audit-pr-architecture`](../audit-pr-architecture/SKILL.md) — writes audit docs per LIFECYCLE closing prescriptions; closure step calls `docs-lifecycle-sweep` on the surrounding `audits/` folder. +- [`docs-governance` rule](../../rules/docs-governance.md) — Tier-2 priming on doc edits. - [`agents-first-convention`](../../rules/agents-first-convention.md) — file-layout discipline (`.agents/` source of truth, `.cursor/` symlinks). -- [`agents-tier-system`](../../rules/agents-tier-system.md) — rules vs skills, when each tier applies. -- [`docs/README.md`](../../../docs/README.md) — the canonical Rules + ownership table this skill describes the framework around. +- [`agents-tier-system`](../../rules/agents-tier-system.md) — rules vs skills tier system. +- [`docs/README.md`](../../../docs/README.md) — canonical Rules + ownership table this skill describes the framework around. diff --git a/.agents/skills/docs-lifecycle-sweep/SKILL.md b/.agents/skills/docs-lifecycle-sweep/SKILL.md index 64b278fc..8cb82a4d 100644 --- a/.agents/skills/docs-lifecycle-sweep/SKILL.md +++ b/.agents/skills/docs-lifecycle-sweep/SKILL.md @@ -9,6 +9,8 @@ description: Operationalises the docs-governance lifecycle on demand — produce The promise: at the end of a sweep, every remaining file passes the existence test, every closed plan is lifted, every closed audit is either kept-with-justification or deleted-with-knowledge-lifted, every cross-reference still resolves, and there is **no dead weight**. +**Procedure:** [WORKFLOW.md](./WORKFLOW.md) — enumerate → existence test → classify → report → execute on approval. + ## When to fire User intent (any phrase is enough): @@ -36,86 +38,34 @@ The two surface tiers codemap has today: | **B** — repo-wide | `docs/` | All 5 lifecycle types: `architecture.md`, `roadmap.md`, `glossary.md`, `agents.md`, etc. + `plans/`, `research/`, future `audits/` | | **0** — per-tooling-area | `.agents/`, `.cursor/`, `scripts/`, `templates/agents/` | Each rule + skill — apply existence test; check Tier 1 always-on cost still earns its keep | -(Tier C / Tier A from `docs-governance` don't apply yet — see [`docs-governance` § Doc-bearing surface tiers](../docs-governance/SKILL.md#doc-bearing-surface-tiers).) +(Tier C / Tier A from `docs-governance` don't apply yet — see [`docs-governance` LIFECYCLE § Doc-bearing surface tiers](../docs-governance/LIFECYCLE.md#doc-bearing-surface-tiers).) Default: the user names a surface (e.g. "sweep `docs/research/`"). If they say "sweep docs" without scope, ask. -## The 5-step procedure - -### 1. Enumerate the surface - -```bash -find docs -name '*.md' -type f # Tier B -find .agents/rules .agents/skills -name '*.md' -type f # Tier 0 (source-of-truth rules + skills) -find templates/agents -name '*.md' -type f # Tier 0 (bundled npm templates — separate authoring surface) -``` - -`.cursor/` is intentionally excluded — it's symlinks back to `.agents/` per [`agents-first-convention`](../../rules/agents-first-convention.md), so sweeping it would double-count. `scripts/` is .ts only (no docs to sweep). If either grows tracked `.md` files in the future, add them here. - -Map each file to one of the 5 lifecycle types per [docs-governance § 1](../docs-governance/SKILL.md#1-five-lifecycle-types). If a file fits no type, that itself is a finding (rogue doc — fold + delete). - -### 2. Apply the existence test - -Per [docs-governance § 2](../docs-governance/SKILL.md#2-existence-test-apply-on-every-doc-touching-pr), each file earns its place if it meets ≥1 of: source cite / durable policy / open work / inbound cites require slim stub. - -For each file, run the cite-check evidence command: - -```bash -rg -n "(\.md)?(#[a-z0-9-]+)?" \ - --glob '!docs/**' --glob '!.agents/**' --glob '!.cursor/**' . - -rg -n "Rule [0-9]+" # cited rule numbers -rg -n "NOTE\(" src/ scripts/ # NOTE markers if used -``` - -If the file is an audit, also check the [docs-governance § Closing an audit re-derivable test](../docs-governance/SKILL.md#closing-an-audit) keep-criteria (decisions of record / source-back-references / reusable methodology). - -### 3. Classify each file - -| Tier | Verdict | Action | -| --------------------- | --------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **A — Keep verbatim** | Cited from source by rule number / section anchor; OR Reference / Roadmap that lives forever per its lifecycle | No-op (open audits may carry a "Last verified" date — refresh only while findings are open) | -| **B — Slim + keep** | Closed but ≥1 audit keep-criteria applies; OR has cited content that's stable | Slim to cited / durable bits + verification recipe + status header; preserve cited rule numbers per [§ 7](../docs-governance/SKILL.md#7-cross-reference-preservation-discipline) | -| **C — Delete + lift** | Closed AND no source cites AND all findings shipped/lifted; OR superseded; OR fails the existence test outright | Lift any orphan-able knowledge into the natural reference doc / skill; fix inbound cross-refs; **delete the file** (no tombstones, no pointer rows, no recovery instructions in living docs) | - -### 4. Surface the classification report (BEFORE any edits) - -Present the user with a per-file table — file shape / lifecycle type / tier verdict / evidence / proposed action. Use **shape placeholders** (``, ``) when illustrating the template. - -The report includes the **executable diff preview** for every Tier B (slim) and Tier C (delete + lift). Cross-reference impact is shown: every inbound link to a Tier C file gets a "this link will need rewiring" line. - -### 5. Execute on user approval - -In dependency order (delete + lift before slimming so cross-refs are correct): - -1. **Lift** orphan-able knowledge to its destination. -2. **Update** every inbound cross-reference (in-place edits). -3. **Delete** the source file (Tier C) or apply the slim diff (Tier B). -4. **Update cross-references** — fix inbound links to deleted paths; `architecture.md` for newly-promoted reference content; `docs/README.md § File Ownership` table for added/removed top-level docs (per [`docs/README.md` Rule 4](../../../docs/README.md)). Do not add tombstone rows for deleted audit paths. -5. **Re-grep** to confirm zero broken cross-references: `rg ""` returns 0 hits outside the deletion commit message. - -After execution, the surface is **clean** by definition. - -## Output substrate (the sweep report itself) - -A sweep report is **transient** by design — it lives on the PR / chat where the sweep ran, not in `docs/`. The findings + chosen actions land as commit messages + cross-link updates; the report itself is not a doc to keep. +## Classification tiers -Default: don't write a meta-doc about the cleanup. Durable closure anchors are the shipping PR / commit — not a maintained list of deleted paths. +| Tier | Verdict | Action | +| --------------------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **A — Keep verbatim** | Cited from source by rule number / section anchor; OR Reference / Roadmap that lives forever per its lifecycle | No-op (open audits may carry a "Last verified" date — refresh only while findings are open) | +| **B — Slim + keep** | Closed but ≥1 audit keep-criteria applies; OR has cited content that's stable | Slim to cited / durable bits + verification recipe + status header; preserve cited rule numbers per [LIFECYCLE § 7](../docs-governance/LIFECYCLE.md#7-cross-reference-preservation-discipline) | +| **C — Delete + lift** | Closed AND no source cites AND all findings shipped/lifted; OR superseded; OR fails the existence test outright | Lift any orphan-able knowledge into the natural reference doc / skill; fix inbound cross-refs; **delete the file** (no tombstones, no pointer rows, no recovery instructions in living docs) | ## Anti-patterns - ❌ **Deleting without surfacing the classification first.** The user owns the call. The skill produces evidence; it does not unilaterally decide. -- ❌ **Slimming without grepping for cited rule numbers / section anchors.** Anchor breakage is silent and degrades over time. [docs-governance § 7](../docs-governance/SKILL.md#7-cross-reference-preservation-discipline) is non-negotiable. +- ❌ **Slimming without grepping for cited rule numbers / section anchors.** Anchor breakage is silent and degrades over time. [docs-governance LIFECYCLE § 7](../docs-governance/LIFECYCLE.md#7-cross-reference-preservation-discipline) is non-negotiable. - ❌ **Leaving tombstones.** A "this audit was closed and deleted, see commit X" pointer file IS the dead weight the sweep is supposed to eliminate. Trust `git log --follow`. - ❌ **Lifting trivia.** Not every closed audit has knowledge worth lifting. If findings are 100% mechanical and the result is visible in source, **lift nothing, delete the file.** - ❌ **Reformatting "while we're here."** A sweep edits structure (delete / slim / lift / pointer-update). Cosmetic re-flowing is a separate PR. - ❌ **Sweeping Tier 1 rules without checking the always-on cost ledger.** A Tier 1 rule that no longer earns its always-on cost should demote to Tier 2 / Tier 3 (per [`agents-tier-system`](../../rules/agents-tier-system.md)), not get deleted outright. - ❌ **Leaving enumerated cross-reference indexes inline after a slim.** A line like _"Cited from `audit.md`, `audits/.md`, `testing.md`"_ is a hand-maintained index that drifts on every slim. The grep command IS the index — cite the command (`rg "" `). -- ❌ **Citing specific audit / plan / research filenames as canonical examples.** Skills are durable; the docs they describe are mortal under this very lifecycle. Use shape placeholders. Same hazard for rules — see [`agents-tier-system` § Authoring discipline: durability](../../rules/agents-tier-system.md#authoring-discipline-durability). +- ❌ **Citing specific audit / plan / research filenames as canonical examples.** Skills are durable; the docs they describe are mortal under this very lifecycle. Use shape placeholders. Same hazard for rules — see [`agents-tier-system` § Authoring discipline: durability](../agents-tier-system/SKILL.md#authoring-discipline-durability). ## Reference - [`docs-governance`](../docs-governance/SKILL.md) — the spec this skill operationalises. +- [`docs-governance` LIFECYCLE](../docs-governance/LIFECYCLE.md) — lifecycle types, existence test, closing prescriptions, cross-reference discipline. - [`docs-governance` rule](../../rules/docs-governance.md) — Tier-2 priming on every doc-touching edit. - [`audit-pr-architecture`](../audit-pr-architecture/SKILL.md) — natural caller; closes audits and triggers a sweep on the surrounding `audits/` folder. +- [WORKFLOW.md](./WORKFLOW.md) — 5-step procedure + output substrate. - [`agents-tier-system`](../../rules/agents-tier-system.md) — applies when sweeping Tier 0 (`.agents/rules/`, `.agents/skills/`). diff --git a/.agents/skills/docs-lifecycle-sweep/WORKFLOW.md b/.agents/skills/docs-lifecycle-sweep/WORKFLOW.md new file mode 100644 index 00000000..d6e2bb91 --- /dev/null +++ b/.agents/skills/docs-lifecycle-sweep/WORKFLOW.md @@ -0,0 +1,59 @@ +# Docs lifecycle sweep — procedure + +## The 5-step procedure + +### 1. Enumerate the surface + +```bash +find docs -name '*.md' -type f # Tier B +find .agents/rules .agents/skills -name '*.md' -type f # Tier 0 (source-of-truth rules + skills) +find templates/agents -name '*.md' -type f # Tier 0 (bundled npm templates — separate authoring surface) +``` + +`.cursor/` is intentionally excluded — it's symlinks back to `.agents/` per [`agents-first-convention`](../../rules/agents-first-convention.md), so sweeping it would double-count. `scripts/` is .ts only (no docs to sweep). If either grows tracked `.md` files in the future, add them here. + +Map each file to one of the 5 lifecycle types per [docs-governance LIFECYCLE § 1](../docs-governance/LIFECYCLE.md#1-five-lifecycle-types). If a file fits no type, that itself is a finding (rogue doc — fold + delete). + +### 2. Apply the existence test + +Per [docs-governance LIFECYCLE § 2](../docs-governance/LIFECYCLE.md#2-existence-test-apply-on-every-doc-touching-pr), each file earns its place if it meets ≥1 of: source cite / durable policy / open work / inbound cites require slim stub. + +For each file, run the cite-check evidence command: + +```bash +rg -n "(\.md)?(#[a-z0-9-]+)?" \ + --glob '!docs/**' --glob '!.agents/**' --glob '!.cursor/**' . + +rg -n "Rule [0-9]+" # cited rule numbers +rg -n "NOTE\(" src/ scripts/ # NOTE markers if used +``` + +If the file is an audit, also check the [docs-governance LIFECYCLE § Closing an audit re-derivable test](../docs-governance/LIFECYCLE.md#closing-an-audit) keep-criteria (decisions of record / source-back-references / reusable methodology). + +### 3. Classify each file + +Apply the tier definitions from [SKILL.md § Classification tiers](./SKILL.md#classification-tiers). + +### 4. Surface the classification report (BEFORE any edits) + +Present the user with a per-file table — file shape / lifecycle type / tier verdict / evidence / proposed action. Use **shape placeholders** (``, ``) when illustrating the template. + +The report includes the **executable diff preview** for every Tier B (slim) and Tier C (delete + lift). Cross-reference impact is shown: every inbound link to a Tier C file gets a "this link will need rewiring" line. + +### 5. Execute on user approval + +In dependency order (delete + lift before slimming so cross-refs are correct): + +1. **Lift** orphan-able knowledge to its destination. +2. **Update** every inbound cross-reference (in-place edits). +3. **Delete** the source file (Tier C) or apply the slim diff (Tier B). +4. **Update cross-references** — fix inbound links to deleted paths; `architecture.md` for newly-promoted reference content; `docs/README.md § File Ownership` table for added/removed top-level docs (per [`docs/README.md` Rule 4](../../../docs/README.md)). Do not add tombstone rows for deleted audit paths. +5. **Re-grep** to confirm zero broken cross-references: `rg ""` returns 0 hits outside the deletion commit message. + +After execution, the surface is **clean** by definition. + +## Output substrate (the sweep report itself) + +A sweep report is **transient** by design — it lives on the PR / chat where the sweep ran, not in `docs/`. The findings + chosen actions land as commit messages + cross-link updates; the report itself is not a doc to keep. + +Default: don't write a meta-doc about the cleanup. Durable closure anchors are the shipping PR / commit — not a maintained list of deleted paths. diff --git a/.agents/skills/domain-modeling/GLOSSARY-ENTRY.md b/.agents/skills/domain-modeling/GLOSSARY-ENTRY.md new file mode 100644 index 00000000..575c37ac --- /dev/null +++ b/.agents/skills/domain-modeling/GLOSSARY-ENTRY.md @@ -0,0 +1,44 @@ +# Glossary entry format + +Canonical ubiquitous language for `@stainless-code/codemap`. Lives in [`docs/glossary.md`](../../../docs/glossary.md) — single repo-wide file (Tier B). Add an entry when a term is resolved during grilling or implementation. + +## Structure + +```md +# Glossary + +> Single canonical glossary for terms used across `src/` and `docs/`. +> When in doubt, this file wins. Update on the same PR that introduces a new term. + +## + +| Term | Definition | Aliases / avoid | +| ---------- | ------------------------------------------------------------- | -------------------- | +| **** | One-sentence definition. Define what it IS, not what it does. | comma-separated list | +``` + +## Rules + +- **Be opinionated.** Pick one canonical term; list alternatives under "Aliases / avoid". +- **Keep definitions tight.** One sentence — what it IS, not what it does. +- **Domain terms only.** General programming concepts don't belong. +- **Group under subheadings** when natural clusters emerge (`## Index`, `## Recipes`, `## Schema`, `## Adapters`). +- **Flag ambiguities** in a § Flagged ambiguities section — "In this repo, X always means …" +- **Cite, don't paste** — link source files by path (no line numbers). + +## Where vocabulary lives + +| Scope | File | +| ------------------ | ------------------------------------------------------------------------------------------------------- | +| Repo-wide domain | `docs/glossary.md` (single) | +| Architecture nouns | `improve-codebase-architecture/LANGUAGE.md` (`module`, `seam`, `adapter`) — distinct from this glossary | + +## Decisions (not in the glossary) + +| Kind | Location | +| ------------------- | ------------------------------------- | +| Current structural | `docs/architecture.md` | +| Closed / historical | `docs/audits/-.md` | +| In-flight | `docs/plans/.md` | + +See [`docs-governance`](../docs-governance/SKILL.md) — no `docs/adr/` in this repo. diff --git a/.agents/skills/domain-modeling/GLOSSARY-SCAN.md b/.agents/skills/domain-modeling/GLOSSARY-SCAN.md new file mode 100644 index 00000000..6ff06d26 --- /dev/null +++ b/.agents/skills/domain-modeling/GLOSSARY-SCAN.md @@ -0,0 +1,71 @@ +# Batch glossary scan + +Full terminology extraction to [`docs/glossary.md`](../../../docs/glossary.md). For **inline** term pinning during grilling or implementation, use the main [`domain-modeling`](./SKILL.md) session flow — not this file. + +## Process + +1. **Scan the slice** for domain-relevant nouns, verbs, and concepts. Look at: the index pipeline (`src/parser.ts`, `src/db.ts`, adapters); schema columns and SQLite tables; recipe catalog (`templates/recipes/`); CLI/MCP surfaces (`codemap query`, `codemap apply`); config keys; option names (`--recipe`, `--baseline`, `format`, `group_by`); adapter / language-map names; JSDoc that hints at semantics. +2. **Identify problems**: + - Same word used for different concepts (ambiguity — e.g. "query" for both a cataloged recipe and ad-hoc SQL). + - Different words used for the same concept (synonyms — e.g. "index" vs "database" vs "DB"). + - Vague or overloaded terms (e.g. "file" for both a `FileRow` TS shape and the `files` table). + - A schema column or recipe id bleeding into prose without a domain explanation. +3. **Propose a canonical glossary** with opinionated term choices. +4. **Write to `docs/glossary.md`** following the format in [GLOSSARY-ENTRY.md](./GLOSSARY-ENTRY.md). Link from [`docs/README.md`](../../../docs/README.md) and [`docs/architecture.md`](../../../docs/architecture.md) § Reference. +5. **Output a summary** inline in the conversation. + +## Output format + +Write the glossary file per [GLOSSARY-ENTRY.md](./GLOSSARY-ENTRY.md). **Group naturally** — by index layer, recipe surface, or schema concern. Don't force groupings if one table is cohesive enough. + +```md +# Glossary + +> Single canonical glossary for terms used across `src/` and `docs/`. +> When in doubt, this file wins. Update on the same PR that introduces a new term. + +## Index + +| Term | Definition | Aliases / avoid | + +## Recipes + +| Term | Definition | Aliases / avoid | + +## Flagged ambiguities + +- "" was used to mean both **** and ****. Recommendation: ... +``` + +### Groupings (illustrative) + +- **Index**: structural index, `.codemap/index.db`, reindex, commit drift, pending sync. +- **Schema**: schema column, `SCHEMA_VERSION`, SQLite table vs TS shape (`FileRow` vs `files` table). +- **Recipes**: recipe (cataloged SQL), query (any SQL), `query_recipe`, golden scenario. +- **Graph**: hub (fan-in), barrel (re-exports), fan-in vs fan-out, impact direction. +- **Parsing**: language adapter, adapter extension, parse worker, extractFileData. +- **Surfaces**: CLI, MCP tool, HTTP resource, `templates/agent-content` (served live) vs `templates/agents` (copied by init). + +## Rules + +- **Be opinionated.** When multiple words exist for the same concept, pick the best one and list the others as "aliases / avoid." +- **Flag conflicts explicitly** in § Flagged ambiguities. +- **Skip generic programming concepts** unless they have domain meaning here. +- **Skip module / class / file names** unless the name itself is the domain term (e.g. `FileRow` — the name IS the TS shape). +- **Keep definitions tight** — one sentence. Define what it IS. +- **Cite, don't paste** — link source files by path (no line numbers). + +## Re-running + +When invoked again on a previously-glossarised repo: + +1. Read the existing `docs/glossary.md`. +2. Incorporate new terms surfaced by recent PRs. +3. Update definitions if understanding has evolved. +4. Re-flag any new ambiguities. + +## Project conventions + +- **File location**: `docs/glossary.md` (single, repo-root). +- **Link from**: `docs/README.md` and `docs/architecture.md` § Reference. +- **Distinct from architecture vocabulary**: `improve-codebase-architecture/LANGUAGE.md` covers architecture nouns (`module`, `seam`, `adapter`); this glossary covers index/recipe/schema domain nouns. diff --git a/.agents/skills/domain-modeling/SKILL.md b/.agents/skills/domain-modeling/SKILL.md new file mode 100644 index 00000000..70a3b430 --- /dev/null +++ b/.agents/skills/domain-modeling/SKILL.md @@ -0,0 +1,67 @@ +--- +name: domain-modeling +description: Build and sharpen the project's domain terminology inline or via a batch glossary scan. Use when pinning down ubiquitous language, recording a domain decision, grill-with-docs crystallises a term, or refreshing docs/glossary.md. +--- + +# Domain Modeling + +Actively build and sharpen the project's domain model as you design. Reading [`docs/glossary.md`](../../../docs/glossary.md) for vocabulary is a one-line habit any skill can do — **this skill is for when you're changing the model**, not just consuming it. + +Codemap deltas for this repo: + +- **No repo-root `docs/adr/`** — current decisions live in [`docs/architecture.md`](../../../docs/architecture.md); closed history in `docs/audits/.md`; in-flight in `docs/plans/.md`. See [`docs-governance`](../docs-governance/SKILL.md). +- **Single canonical glossary** — [`docs/glossary.md`](../../../docs/glossary.md) at the repo root (Tier B: one repo-wide surface, no per-feature subtrees). See [`grill-with-docs/ARTIFACTS.md`](../grill-with-docs/ARTIFACTS.md). + +## File structure + +``` +/ +├── docs/ +│ ├── glossary.md ← canonical ubiquitous language (single) +│ ├── architecture.md ← current structural decisions +│ ├── audits/.md ← closed decisions +│ └── plans/.md ← in-flight decisions +``` + +Create files lazily — only when you have something to write. + +## During the session (inline) + +### Challenge against the glossary + +When the user uses a term that conflicts with [`docs/glossary.md`](../../../docs/glossary.md), call it out immediately. + +### Sharpen fuzzy language + +When the user uses vague or overloaded terms (e.g. "query" for both a cataloged recipe and ad-hoc SQL, or "file" for both a `FileRow` TS shape and the `files` SQLite table), propose a precise canonical term. + +### Discuss concrete scenarios + +Stress-test domain relationships with specific edge-case scenarios (homonym symbols across files, recipe vs ad-hoc query drift, hub vs barrel ranking, fan-in vs fan-out impact direction). + +### Cross-reference with code + +When the user states how something works, check whether the code agrees (`src/db.ts`, `src/parser.ts`, recipe loader, adapter layer). Surface contradictions — use `codemap query` for structural facts before `Read`/`Grep`. + +### Update vocabulary inline + +When a term is resolved, update [`docs/glossary.md`](../../../docs/glossary.md) **right there** — don't batch. Use [GLOSSARY-ENTRY.md](./GLOSSARY-ENTRY.md). + +`docs/glossary.md` is **glossary only** — no implementation details, not a spec or scratch pad. + +### Offer decision docs sparingly + +Only when the decision is hard to reverse, surprising without context, and the result of a real trade-off. Route to `architecture.md`, `plans/`, or `audits/` per docs-governance — not ADRs at repo root. + +## Batch glossary scan + +When the user asks to extract or refresh the full glossary (not one term at a time), follow [GLOSSARY-SCAN.md](./GLOSSARY-SCAN.md). + +**Done when:** resolved terms are in [`docs/glossary.md`](../../../docs/glossary.md); contradictions with code surfaced or filed as follow-up. + +## Reference + +- Format: [GLOSSARY-ENTRY.md](./GLOSSARY-ENTRY.md) +- Batch scan: [GLOSSARY-SCAN.md](./GLOSSARY-SCAN.md) +- Docs lifecycle: [`docs-governance`](../docs-governance/SKILL.md) +- Grilling + inline updates: [`grill-with-docs/ARTIFACTS.md`](../grill-with-docs/ARTIFACTS.md) diff --git a/.agents/skills/grill-me/SKILL.md b/.agents/skills/grill-me/SKILL.md index 3345f3cc..d4162337 100644 --- a/.agents/skills/grill-me/SKILL.md +++ b/.agents/skills/grill-me/SKILL.md @@ -1,12 +1,11 @@ --- name: grill-me description: Interview the user relentlessly about a plan or design until reaching shared understanding, resolving each branch of the decision tree. Use when user wants to stress-test a plan, get grilled on their design, or mentions "grill me". +disable-model-invocation: true --- -Interview me relentlessly about every aspect of this plan until we reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer. - -Ask the questions one at a time, waiting for feedback before continuing. - -If a question can be answered by exploring the codebase, explore the codebase instead. In this repo, that means querying [`codemap`](../codemap/SKILL.md) (the structural index) before reaching for `Grep` or `Read` — see the [`codemap` rule](../../rules/codemap.md). +Run a [`grilling`](../grilling/SKILL.md) session. Structural exploration uses [`codemap query`](../codemap/SKILL.md) per the [`codemap` rule](../../rules/codemap.md) — not `Grep`. When agreement crystallises on a question that affects an in-flight `docs/plans/.md`, write the answer into the plan inline as you go — don't batch them up. The plan doc is the durable record; the chat transcript is not. + +For plan + inline repo docs (glossary, architecture lifts): [`grill-with-docs`](../grill-with-docs/SKILL.md). diff --git a/.agents/skills/grill-with-docs/ARTIFACTS.md b/.agents/skills/grill-with-docs/ARTIFACTS.md new file mode 100644 index 00000000..8e08e41f --- /dev/null +++ b/.agents/skills/grill-with-docs/ARTIFACTS.md @@ -0,0 +1,109 @@ +# Grill-with-docs — artifacts and session rules + +Companion to the user-invoked [`grill-with-docs`](./SKILL.md) wrapper. Run [`grilling`](../grilling/SKILL.md) first; follow [`docs-governance`](../docs-governance/SKILL.md) for paths. + +## Doc-governance shape this skill writes into + +This repo is **Tier B only** — one repo-wide `docs/` surface, no per-feature subtrees. Mapping from a generic `CONTEXT.md` + `docs/adr/` template to ours: + +| Generic template concept | This repo's equivalent | +| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `CONTEXT.md` (canonical vocabulary) | [`docs/glossary.md`](../../../docs/glossary.md) (repo-root, single) | +| `docs/adr/-.md` (decisions) | **No ADRs.** Current decisions live in [`docs/architecture.md`](../../../docs/architecture.md); closed historical decisions in `docs/audits/-.md`; in-flight in `docs/plans/.md`. See § Where decisions go below. | +| `CONTEXT-MAP.md` (multi-context repo) | n/a — single repo-wide context; cross-cutting linkage lives in `docs/architecture.md` | + +No feature `docs/` to bootstrap — there's one surface. If `docs/glossary.md` doesn't exist yet, create it the first time a term crystallises (per [`domain-modeling`](../domain-modeling/SKILL.md)). + +## Process + +### 1. Pre-flight — load the existing language and decisions + +Before asking the first question, read (or `codemap query` for structural facts, then `Read` for prose): + +- **[`docs/glossary.md`](../../../docs/glossary.md)** — what does the project already call the things in this conversation? +- **[`docs/architecture.md`](../../../docs/architecture.md)** — has a similar decision already shipped? What constraints does it impose on this one? +- **`docs/audits/.md`** — has the team already considered (and rejected) a similar shape? Don't re-litigate without evidence. +- **[`docs/roadmap.md`](../../../docs/roadmap.md)** — is this thread already on the backlog? Cite the existing entry. +- **`docs/plans/.md`** — is there an open plan that overlaps? + +Skip whichever files don't exist. Don't bootstrap a doc just to read it. + +### 2. Run the grilling loop + +Follow the [`grilling`](../grilling/SKILL.md) rules (one question at a time, recommend, explore, push back, dependency-walk). When a term or boundary crystallises, invoke [`domain-modeling`](../domain-modeling/SKILL.md) inline — update [`docs/glossary.md`](../../../docs/glossary.md) per the mapping table above. + +On top, fire these triggers as they come up: + +#### 2a. Challenge against the glossary + +When the user uses a term that **conflicts with `docs/glossary.md`**, call it out immediately: + +> `docs/glossary.md` defines **recipe** as cataloged SQL loaded from `templates/recipes/.{sql,md}`. You just said "the query" for ad-hoc SQL in the CLI — that's a **query**, not a recipe. Do you mean a new recipe id or free-form SQL? + +If the term is **missing from `docs/glossary.md`** but is genuinely domain-bearing (a new noun / verb the user is introducing — e.g. a new schema column or MCP tool), flag it for a same-PR glossary entry — don't wait for the work to ship. + +#### 2b. Sharpen fuzzy language + +When the user uses overloaded or vague terms, propose a precise canonical term and (if applicable) add the alias to `docs/glossary.md`'s "Aliases / avoid" column: + +> You're saying "the file table" — do you mean the **`files` SQLite table** (on-disk rows in `.codemap/index.db`) or the **`FileRow` TS shape** returned by insert helpers in `src/db.ts`? `docs/glossary.md` keeps those distinct; let's pick one for this plan. + +#### 2c. Stress-test with concrete scenarios + +When domain relationships are being discussed, invent specific scenarios that probe edge cases: + +> If a homonym symbol exists in two files and the new recipe scopes by `name` only, does `codemap apply rename-preview` union both definitions or require `define_in`? What does fan-in look like when one file is a barrel and the other is a hub? + +The point is to force the user to be precise about boundaries between concepts. + +#### 2d. Cross-reference with code + +When the user states how something works, check whether the code agrees. Use `codemap query` / [`codemap`](../codemap/SKILL.md) for structural facts before `Read`. If you find a contradiction, surface it: + +> You said recipe params are always string-keyed. But `query_recipe` accepts typed JSON in the MCP layer — does your plan preserve that contract for HTTP too? + +If the user is wrong, the answer changes. If the code is wrong, you've found a bug — surface it as a separate concern. + +### 3. Write decisions back into the docs inline + +Don't batch up doc edits for the end. Capture them as they happen: + +| Decision shape | Where it lands | +| ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **A new term is resolved** (or an existing one sharpened) | Update [`docs/glossary.md`](../../../docs/glossary.md) on the same PR. | +| **A current architectural decision is locked in** (e.g. "new adapter earns a factory only when it needs real language mapping") | Capture in the **plan file** (`docs/plans/.md`) while in-flight. When the plan ships, lift the rationale into [`docs/architecture.md`](../../../docs/architecture.md) per [`docs-governance` § Closing a plan](../docs-governance/SKILL.md). Don't write to `architecture.md` directly while the plan is still open. | +| **A historical decision needs to be recorded** (rejected alternative, surprising trade-off) | Two paths: (1) part of an in-flight plan → record it in the plan's § Open questions; the lift moment carries it to `architecture.md` or `audits/`. (2) Standalone → append to `docs/audits/-.md` (create the dated file if substantial enough). | +| **A future-work item surfaces** | One line in [`docs/roadmap.md`](../../../docs/roadmap.md) under the appropriate section. | +| **An ambiguity stays unresolved** | Flag it in `docs/glossary.md`'s § Flagged ambiguities section (don't quietly resolve). Don't bury the ambiguity in the plan body alone — the glossary is where readers look for term meaning. | + +### 4. Where decisions go (the no-ADR convention) + +This repo deliberately doesn't carry `docs/adr/` — that surface is doubled by `docs/architecture.md` (current shipping decisions) + `docs/audits/` (closed historical record). **Skip the ADR offer entirely**. Instead: + +- **"Want me to record this so future architecture reviews don't re-suggest it?"** → for in-flight work, add it to the plan's § Open questions (with the chosen branch); for shipped work, add it to `docs/architecture.md` § `` with the rationale; for closed-and-rejected alternatives, the entry goes in `docs/audits/.md`. +- **Hard-to-reverse architectural shape** (e.g. "new recipe id ships bundled + documented in glossary") → Plan § Open question + `architecture.md` at lift time. +- **Surprising deviations** (e.g. "golden scenarios stay Tier A in CI — external corpus is Tier B only") → If this is the _durable rationale_, it belongs in `architecture.md` and is cited from maintainer docs. Don't duplicate. + +If the user explicitly asks "should we file an ADR for this?", the answer is "no — this repo's `architecture.md` + `audits/` are the equivalent. Want me to add the entry there?" + +### 5. Stop conditions + +Same as [`grilling`](../grilling/SKILL.md): stop when a competent contributor could open the PR from the resulting plan. **Plus**: + +- [`docs/glossary.md`](../../../docs/glossary.md) is updated with every new term resolved during the session. +- Open questions in the plan have either an answer or an explicit "deferred — needs ``" with a named blocker. +- The plan file's § References section links back to the relevant `architecture.md` / `audits/.md` sections that informed the decisions. + +## Checklist (run before declaring done) + +- [ ] Read `docs/glossary.md`, `docs/architecture.md`, `docs/audits/` before the first question (or noted "n/a — none exist yet" and created the missing reference doc as part of the session) +- [ ] Every new domain term resolved during the session is in `docs/glossary.md` on the same PR +- [ ] Every locked-in design decision is captured in the plan file (or `architecture.md` if standalone) +- [ ] Every rejected alternative the future explorer needs is captured (plan § Open questions or `audits/`, never lost) +- [ ] Every future-work item surfaced is one line in `roadmap.md` +- [ ] No ADR file was created (we don't use that pattern — see § 4) +- [ ] No `glossary.md` term was quietly re-defined; ambiguities went into § Flagged ambiguities + +## Reference + +- [`domain-modeling`](../domain-modeling/SKILL.md) · [`improve-codebase-architecture`](../improve-codebase-architecture/SKILL.md) · [`docs-lifecycle-sweep`](../docs-lifecycle-sweep/SKILL.md) diff --git a/.agents/skills/grill-with-docs/SKILL.md b/.agents/skills/grill-with-docs/SKILL.md new file mode 100644 index 00000000..05bfc75c --- /dev/null +++ b/.agents/skills/grill-with-docs/SKILL.md @@ -0,0 +1,9 @@ +--- +name: grill-with-docs +description: Grill a plan or design and update repo docs as decisions crystallise. Invokes grilling + domain-modeling inline; user-invoked only. +disable-model-invocation: true +--- + +Run a [`grilling`](../grilling/SKILL.md) session. When terms crystallise, invoke [`domain-modeling`](../domain-modeling/SKILL.md) inline. Write docs per [`docs-governance`](../docs-governance/SKILL.md). + +Artifact table, glossary challenges, inline doc routing, and checklist: [`ARTIFACTS.md`](./ARTIFACTS.md). diff --git a/.agents/skills/grilling/SKILL.md b/.agents/skills/grilling/SKILL.md new file mode 100644 index 00000000..846c1a6a --- /dev/null +++ b/.agents/skills/grilling/SKILL.md @@ -0,0 +1,49 @@ +--- +name: grilling +description: Relentlessly grill plans until shared understanding. Use when stress-testing a design or another skill delegates grilling. +--- + +# Grilling + +Interview relentlessly about every aspect of a plan until shared understanding. Walk down each branch of the decision tree, resolving dependencies between decisions one-by-one. **For each question, provide a recommended answer.** Ask one question at a time. + +## Rules + +1. **One question at a time.** Wait for the user's answer before posing the next. Multi-question batches collapse the decision tree into a wall of text. +2. **Always recommend.** Every question carries your strongest read on the answer + a one-line "why". The user wants a sparring partner, not a menu. +3. **Explore before asking.** If the answer lives in source, use [`codemap query`](../codemap/SKILL.md) for structural facts, then `Read` / `Glob` **before** asking. Questions that the codebase already answers waste turns and signal weak prep. +4. **Walk dependencies, not breadth.** Resolve one branch fully before moving sideways. If Q3's answer makes Q5 moot, kill Q5; if Q3 forks into two new sub-questions, ask the sub-questions before returning to Q4. +5. **Push back on weak answers.** If the user's answer leaves the design ambiguous or contradicts something earlier, surface the conflict and re-pose. Don't accept "we'll see" — that's a Q for next time, not closure. +6. **Stop when the design is operational.** "Operational" means a competent contributor could open a PR from the resulting plan without further design questions. Not before, not after. + +## Interaction shape + +```text +Agent: . My read: . Why: <1-line reason>. +User: +Agent: . My read: … +User: … +Agent: That closes the design tree for me. Want me to ? +``` + +Don't number the questions in chat — the conversation IS the order. Number them only when the user asks for a recap or a written summary. + +## Codebase-exploration shortcuts + +Reach for these before asking the human: + +| Question shape | Tool | +| ----------------------------------------------- | ------------------------------------------------------------------ | +| "Where is X defined?" / "Who imports X?" | [`codemap query`](../codemap/SKILL.md) · `Glob` (file paths) | +| "What does file X export?" | `codemap query --recipe find-symbol-definitions` · `Read` the file | +| "What's the blast radius of X?" | `codemap impact` / `query_recipe fan-in` | +| "What conventions apply to this layer?" | `Read` the relevant rule under `.agents/rules/` | +| "How does the existing similar module do this?" | `codemap query` for the pattern, then `Read` | + +## Anti-patterns + +- ❌ **Question dumps.** "I have 7 questions about this — (1) …, (2) …, (3) …" — the user can't keep state across 7 branches in one read. +- ❌ **Open-ended without a recommendation.** "What do you think about X?" — you're the senior here; lead. +- ❌ **Asking questions the codebase already answers.** "Does this module write to the `symbols` table?" — `codemap query` first. +- ❌ **Refusing to push back when the user says "I dunno".** "Don't know" is a signal to recommend harder, not to drop the branch. +- ❌ **Ending the session early.** If the next contributor would still ask "but what about X?", you stopped too soon. diff --git a/.agents/skills/harden-pr/SKILL.md b/.agents/skills/harden-pr/SKILL.md index c53fe4a0..6af5cc8a 100644 --- a/.agents/skills/harden-pr/SKILL.md +++ b/.agents/skills/harden-pr/SKILL.md @@ -18,280 +18,4 @@ Local loop: parallel reviewer subagents → merge findings → fix in-bounds → **Invoking this skill (`/harden-pr`, `harden-pr lite`, `harden-pr full`, `harden-pr quick`, `harden-pr reconcile`) is a run-to-completion command.** The agent executes the full loop before ending the turn. -Sister skills: [`audit-pr-architecture`](../audit-pr-architecture/SKILL.md) (extended structural reviewer). **Ledger:** [LEDGER.md](./LEDGER.md) (rejections + deferred — one file). Mention **`babysit`** only in the final report (full mode) — never mid-loop. - -## Run-to-completion (read first) - -**NEVER** stop between passes to ask: - -- whether to commit -- whether to run babysit -- whether to continue to the next pass -- whether to spawn another reviewer - -**ONLY** allowed mid-loop question: intent anchor step 3 when plan doc and commit range both fail to state what must not change. - -Otherwise: resolve anchor → run all passes → fix → verify → next pass → finish → report. - -| Phase | Behavior | -| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| **During loop** | Autonomous. `Task`-batch reviewers in parallel (§ Spawning subagents), merge JSON findings, fix in-bounds, re-run checks, advance pass counter. | -| **After loop** | Single concise report: mode, passes run, production-bar status (met / gaps), fixes made, checks status, deferred nits (if any). | -| **Commit** | If there are uncommitted fixes: one `harden: …` commit **without asking** — skill invocation authorizes it. If no fixes: skip commit. | -| **Babysit** | Full mode only. One line at end of report: "For GitHub/CI, run `/babysit`." Do not ask. | - -## Modes - -| Mode | When | Scope | Max passes | -| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | ---------- | -| **Lite** | After each tracer-bullet slice commit ([`tracer-bullets`](../../rules/tracer-bullets.md) cadence) | Files in the slice diff | 2 | -| **Quick** | Cheap uncertainty pass ("quick harden") | Last commit or slice diff | 1 | -| **Full** | User intent ("full harden", "PR done", "production-ready pass") **or** offer when an in-flight `docs/plans/.md` checklist is complete | `origin/main...HEAD` | 3 | -| **Reconcile** | `/harden-pr reconcile` — process [LEDGER.md § Deferred](./LEDGER.md#deferred), then run **full** if branch still open | `origin/main...HEAD` | 3 | - -Default to **lite** when invoked immediately after a slice commit. Default to **full** when the user signals branch completion. **Quick** = core 3 reviewers only (no extended roster). - -## Production bar (what "pristine" means) - -Reviewers optimize for this bar on in-scope files. **Full** mode applies it to the entire `origin/main...HEAD` diff; **lite** to the slice diff. - -| Area | Pristine = | -| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Correctness** | No known bugs or unhandled edge cases in changed paths; behavior matches intent anchor | -| **Tests** | Changed behavior covered; affected tests pass | -| **Checks** | Format, lint, typecheck clean on touched files ([`verify-after-each-step`](../../rules/verify-after-each-step.md)) | -| **Docs** | User-visible changes reflected in docs, changesets, help text — no drift; **shipped `docs/plans/.md` deleted + lifted** in the same PR ([`docs-governance`](../docs-governance/SKILL.md) § Closing a plan) | -| **Surfaces** | No maintainer leaks into consumer surfaces ([`consumer-surfaces`](../../rules/consumer-surfaces.md)) | -| **Structure** | No boundary violations or barrel bypasses in the diff | -| **Hygiene** | No dead code, TODO slop, or sloppy naming in touched files; errors actionable | -| **Ship shape** | A reviewer could merge without "fix before ship" notes (except deferred out-of-scope nits) | - -If a finding moves the bar toward pristine and stays in-bounds → **fix it**, including nits in touched files. - -## Intent anchor (every reviewer prompt includes this) - -Resolve in order; stop at the first hit: - -1. **Plan doc** — in-flight `docs/plans/.md`: goal + non-goals -2. **Commit range** — `git log --oneline origin/main...HEAD` + `git diff --name-status origin/main...HEAD` -3. **User anchor** — ask once: "What must not change?" (1–2 sentences). **Only step that may interrupt the loop.** - -Reviewers treat the anchor as contract. Findings that would violate it → **report, do not apply**. - -Record `HEAD` at loop start (`git rev-parse HEAD`) in the final report. If `HEAD` changes mid-loop from unrelated work, re-resolve the anchor before the next pass. - -## Vet step (parent, after merge — before fix) - -Subagents over-report. After merge + dedupe: - -1. Read [LEDGER.md § Rejections](./LEDGER.md#rejections) — drop findings matching a rejection entry. -2. For each remaining finding: **re-read** `file` at `line` (or the cited region). Drop if the claim is false or by-design. -3. New by-design drops → append one bullet to **§ Rejections** in [LEDGER.md](./LEDGER.md). -4. Sort survivors by leverage: `severity` first, then `confidence` desc, then `effort` asc (`S` before `L`). - -**Anti-pattern:** applying a fix without re-reading the cited location. - -## Reconcile mode - -Run-to-completion like other modes: - -1. Read [LEDGER.md § Deferred](./LEDGER.md#deferred). Re-vet each row (same vet step). Fix in-bounds items; remove fixed lines. -2. Run **full** harden on `origin/main...HEAD` (same loop as full mode). -3. On cap: append still-deferred items to **§ Deferred** in [LEDGER.md](./LEDGER.md). Report what was reconciled vs still open. - -## In-bounds vs out-of-bounds - -**Fix:** bugs, missing tests, docs/changeset drift, lint/type/format, error-handling gaps, edge cases, **behavior-preserving refactors in touched files**, in-scope nits (naming, comment hygiene, cheap lint fixes). - -**Report only:** redesign, semantic API changes, nits outside the diff, refactors unrelated to a flagged issue. - -**Do not defer complements:** agent-surface parity (rule/skill/MCP), glossary/architecture/golden-queries contracts, script/golden tests for acceptance criteria, and cross-links named in the plan ship in the **same PR** — not "optional v2" or post-merge unless the plan **Out of scope** section explicitly excludes them. - -## Spawning subagents (non-negotiable) - -The parent agent **MUST NOT** perform reviewer duties inline. Every pass **starts** with a parallel `Task` batch; grep/read/diff by the parent is setup only, **not** a substitute for reviewers. - -| Rule | Requirement | -| --------------- | -------------------------------------------------------------------------------------------------------------------- | -| **Tool** | Cursor **`Task`** tool only (`subagent_type`: `generalPurpose` for most reviewers; `explore` for Structure lite) | -| **Batching** | One parent message → **all** applicable reviewers for that pass **in parallel** (single turn, multiple `Task` calls) | -| **Readonly** | `readonly: true` on every reviewer `Task` — reviewers report; parent fixes | -| **Pass credit** | A pass counts only after parent merges subagent JSON and acts on actionable findings | - -**Anti-pattern (invalid harden):** parent reads the diff, runs tests, fixes nits, and reports — without spawning the roster below. - -### Finding schema (every reviewer returns this) - -Each reviewer returns **only** a JSON array (no prose wrapper). Parent parses arrays from all reviewers, then merges. - -```json -{ - "finding": "One-sentence claim about a gap vs production bar", - "severity": "blocker | major | minor | nit | info", - "file": "repo-relative/path or \"multiple\"", - "line": 42, - "confidence": "high | medium | low", - "effort": "S | M | L", - "fixable_in_bounds": true, - "production_bar": "Tests | Docs | Structure | …" -} -``` - -Use `line: null` when the gap is file-level (e.g. missing test file). - -**Severity → action** - -| Severity | Parent action | -| -------------------------- | ------------------------------------------------------------------- | -| `blocker` / `major` | Fix in pass 1; must fix or defer with plan Out of scope before done | -| `minor` / `nit` | Fix when in touched files; pass 2+ if pass 1 was crowded | -| `info` | Log only unless zero-cost fix in diff | -| `fixable_in_bounds: false` | Final report deferred list — do not apply | - -**Merge + dedupe (parent, after each batch)** - -1. Concatenate all reviewer arrays. -2. Drop `info` unless it blocks ship shape. -3. Dedupe: same `file` + same root cause → keep highest severity, merge `finding` text. -4. Sort actionable: `blocker` → `major` → `minor` → `nit`; within tier → `confidence` desc → `effort` asc. -5. **Vet** (§ Vet step). -6. If vetted list is empty → pass succeeds; skip fix phase. - -**Example merged queue (pass 1)** - -```json -[ - { - "finding": "CLI --help documents summary counts but not per-row attribution on --base JSON rows.", - "severity": "major", - "file": "src/cli/cmd-audit.ts", - "line": 120, - "confidence": "high", - "effort": "S", - "fixable_in_bounds": true, - "production_bar": "Docs" - }, - { - "finding": "Skill shard leaks requiredColumns when describing attribution.", - "severity": "major", - "file": "templates/agent-content/skill/10-recipes-context.md", - "line": null, - "confidence": "high", - "effort": "M", - "fixable_in_bounds": true, - "production_bar": "Surfaces" - }, - { - "finding": "No e2e test for attribution: inherited on deprecated delta.", - "severity": "nit", - "file": "src/application/audit-worktree.test.ts", - "line": null, - "confidence": "medium", - "effort": "S", - "fixable_in_bounds": true, - "production_bar": "Tests" - } -] -``` - -### Reviewer prompt template (copy per `Task`) - -Fill `{ROLE}`, `{REPO}`, `{INTENT_ANCHOR}`, `{SCOPE}`, `{EXTRA}`; set `subagent_type` and `readonly: true`. - -```text -You are the **{ROLE}** reviewer for `/harden-pr` on `{REPO}`. - -**Intent anchor (contract — do not suggest changes that violate):** -{INTENT_ANCHOR} - -**Scope:** {SCOPE} -(lite: slice diff files; full: `git diff --name-status origin/main...HEAD`) - -**Production bar:** See harden-pr skill § Production bar — optimize for {ROLE} rows. - -**Task:** {EXTRA} - -**Return ONLY** a JSON array of findings: -[{ "finding": "...", "severity": "blocker|major|minor|nit|info", "file": "...", "line": N|null, "confidence": "high|medium|low", "effort": "S|M|L", "fixable_in_bounds": true|false, "production_bar": "..." }] -If clean: [] - -Readonly — do not edit files. -``` - -**`{EXTRA}` by role** - -| Role | `{EXTRA}` | -| ------------------ | ------------------------------------------------------------------------------------------------------------------ | -| Correctness | Read changed source + tests; run affected `bun test `; bugs, edge cases, missing coverage | -| Ship-readiness | Grep inbound refs to deleted plan files; verify plan retired + lifted; changeset consumer-clean; cross-ref anchors | -| Structure (lite) | Read `docs/architecture.md` § Layering; check diff imports for boundary violations; optional codemap queries | -| Consumer surface | Read `consumer-surfaces` rule; parity across CLI help, MCP description, agent-content, README, changeset | -| Structure (full) | Run `audit-pr-architecture` skill read-only; report only fixable-in-bounds items | -| Schema / migration | `SCHEMA_VERSION`, migration paths, column contract drift | -| Security | auth, secrets, env, user-input paths in diff | -| Performance | hot paths, benchmarks, worker pools in diff | - -## Reviewer roster - -Spawn applicable reviewers **in parallel** via **`Task`** in **one batch per pass**. Each subagent returns the finding schema above. - -### Core (always — every pass) - -1. **Correctness** — gaps vs production bar; bugs, edge cases, missing tests in changed paths -2. **Ship-readiness** — gaps vs production bar; docs, changesets, consumer-surface leaks, error messages; **grep inbound refs → delete shipped plan file → lift to `golden-queries.md` / `architecture.md` / `roadmap.md`**; run [`verify-after-each-step`](../../rules/verify-after-each-step.md) checks on touched files -3. **Structure (lite)** — gaps vs production bar; boundary smells on the diff (imports across declared layers, barrel bypasses); query codemap per [`codemap`](../codemap/SKILL.md) - -### Extended (adaptive — spawn when diff triggers match) - -| Reviewer | Trigger | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| **Structure (full)** | ≥5 files moved between top-level `src/` modules, new `src//` folder, or user asked for structural review → run [`audit-pr-architecture`](../audit-pr-architecture/SKILL.md) read-only; apply only fixable in-bounds items, not audit-doc recommendations that change design | -| **Schema / migration** | `src/db.ts`, `SCHEMA_VERSION`, migration paths | -| **Consumer surface** | `templates/agent-content/**`, root `README.md`, CLI help/errors, `.changeset/*.md` bodies | -| **Security** | auth, secrets, env handling, user-input paths | -| **Performance** | hot paths, benchmarks, worker pools | - -Re-derive layer globs from `docs/architecture.md` § Layering — don't hardcode module lists that drift. - -## Loop - -Execute **without pausing for user input** until exit condition: - -``` -resolve intent anchor; stamp HEAD -pass = 1 -loop: - Task-batch all applicable reviewers (parallel, readonly) - parent: merge + dedupe JSON findings (§ Finding schema) - parent: vet findings (§ Vet step) - if none actionable → goto done - fix in-bounds (pass 1: all; passes 2+: blockers first, then in-scope nits) - per fix: run verification gate from verify-after-each-step on touched files - if clean and no new findings → goto done - if pass >= max_passes → goto capped - pass += 1 - goto loop -capped: - append deferred rows to LEDGER.md § Deferred - emit deferred-nits list (each nit must cite plan Out of scope or cross-PR blocker — not "optional") -done: - if uncommitted fixes → git commit -m "harden: …" - emit final report (include babysit one-liner if full mode; include anchor HEAD stamp) -``` - -**Pass cap behavior:** after cap, stop auto-fixing; list deferred nits. Do not block the next tracer slice. - -## Git - -Skill invocation **is** the commit authorization. After the loop: if fixes exist, create one `harden: …` commit immediately — do not ask first. If the working tree is clean, skip. - -## Quick invoke - -| Intent | Say | -| ---------------- | ------------------------------------------------------ | -| Post-slice | `/harden-pr lite` or `/harden-pr` after a slice commit | -| Cheap pass | `/harden-pr quick` | -| Branch done | `/harden-pr full` or "production-ready pass" | -| Deferred backlog | `/harden-pr reconcile` | - -Replaces the old copy-paste: _"spawn subagents → fix → loop until clean"_ — this skill **is** that loop. +Sister skills: [`audit-pr-architecture`](../audit-pr-architecture/SKILL.md) (extended structural reviewer). **Workflow** (modes, roster, loop, git): [WORKFLOW.md](./WORKFLOW.md). **Ledger:** [LEDGER.md](./LEDGER.md). Mention **`babysit`** only in the final report (full mode) — never mid-loop. diff --git a/.agents/skills/harden-pr/WORKFLOW.md b/.agents/skills/harden-pr/WORKFLOW.md new file mode 100644 index 00000000..e1e2c027 --- /dev/null +++ b/.agents/skills/harden-pr/WORKFLOW.md @@ -0,0 +1,279 @@ +# Harden PR — workflow + +**Goal:** pristine production state on in-scope paths — shippable, verified, documented — **without** changing PR intent or runtime behavior. + +## Run-to-completion (read first) + +**NEVER** stop between passes to ask: + +- whether to commit +- whether to run babysit +- whether to continue to the next pass +- whether to spawn another reviewer + +**ONLY** allowed mid-loop question: intent anchor step 3 when plan doc and commit range both fail to state what must not change. + +Otherwise: resolve anchor → run all passes → fix → verify → next pass → finish → report. + +| Phase | Behavior | +| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | +| **During loop** | Autonomous. `Task`-batch reviewers in parallel (§ Spawning subagents), merge JSON findings, fix in-bounds, re-run checks, advance pass counter. | +| **After loop** | Single concise report: mode, passes run, production-bar status (met / gaps), fixes made, checks status, deferred nits (if any). | +| **Commit** | If there are uncommitted fixes: one `harden: …` commit **without asking** — skill invocation authorizes it. If no fixes: skip commit. | +| **Babysit** | Full mode only. One line at end of report: "For GitHub/CI, run `/babysit`." Do not ask. | + +## Modes + +| Mode | When | Scope | Max passes | +| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | ---------- | +| **Lite** | After each tracer-bullet slice commit ([`tracer-bullets`](../../rules/tracer-bullets.md) cadence) | Files in the slice diff | 2 | +| **Quick** | Cheap uncertainty pass ("quick harden") | Last commit or slice diff | 1 | +| **Full** | User intent ("full harden", "PR done", "production-ready pass") **or** offer when an in-flight `docs/plans/.md` checklist is complete | `origin/main...HEAD` | 3 | +| **Reconcile** | `/harden-pr reconcile` — process [LEDGER.md § Deferred](./LEDGER.md#deferred), then run **full** if branch still open | `origin/main...HEAD` | 3 | + +Default to **lite** when invoked immediately after a slice commit. Default to **full** when the user signals branch completion. **Quick** = core 3 reviewers only (no extended roster). + +## Production bar (what "pristine" means) + +Reviewers optimize for this bar on in-scope files. **Full** mode applies it to the entire `origin/main...HEAD` diff; **lite** to the slice diff. + +| Area | Pristine = | +| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Correctness** | No known bugs or unhandled edge cases in changed paths; behavior matches intent anchor | +| **Tests** | Changed behavior covered; affected tests pass | +| **Checks** | Format, lint, typecheck clean on touched files ([`verify-after-each-step`](../../rules/verify-after-each-step.md)) | +| **Docs** | User-visible changes reflected in docs, changesets, help text — no drift; **shipped `docs/plans/.md` deleted + lifted** in the same PR ([`docs-governance`](../docs-governance/SKILL.md) § Closing a plan) | +| **Surfaces** | No maintainer leaks into consumer surfaces ([`consumer-surfaces`](../../rules/consumer-surfaces.md)) | +| **Structure** | No boundary violations or barrel bypasses in the diff | +| **Hygiene** | No dead code, TODO slop, or sloppy naming in touched files; errors actionable | +| **Ship shape** | A reviewer could merge without "fix before ship" notes (except deferred out-of-scope nits) | + +If a finding moves the bar toward pristine and stays in-bounds → **fix it**, including nits in touched files. + +## Intent anchor (every reviewer prompt includes this) + +Resolve in order; stop at the first hit: + +1. **Plan doc** — in-flight `docs/plans/.md`: goal + non-goals +2. **Commit range** — `git log --oneline origin/main...HEAD` + `git diff --name-status origin/main...HEAD` +3. **User anchor** — ask once: "What must not change?" (1–2 sentences). **Only step that may interrupt the loop.** + +Reviewers treat the anchor as contract. Findings that would violate it → **report, do not apply**. + +Record `HEAD` at loop start (`git rev-parse HEAD`) in the final report. If `HEAD` changes mid-loop from unrelated work, re-resolve the anchor before the next pass. + +## Vet step (parent, after merge — before fix) + +Subagents over-report. After merge + dedupe: + +1. Read [LEDGER.md § Rejections](./LEDGER.md#rejections) — drop findings matching a rejection entry. +2. For each remaining finding: **re-read** `file` at `line` (or the cited region). Drop if the claim is false or by-design. +3. New by-design drops → append one bullet to **§ Rejections** in [LEDGER.md](./LEDGER.md). +4. Sort survivors by leverage: `severity` first, then `confidence` desc, then `effort` asc (`S` before `L`). + +**Anti-pattern:** applying a fix without re-reading the cited location. + +## Reconcile mode + +Run-to-completion like other modes: + +1. Read [LEDGER.md § Deferred](./LEDGER.md#deferred). Re-vet each row (same vet step). Fix in-bounds items; remove fixed lines. +2. Run **full** harden on `origin/main...HEAD` (same loop as full mode). +3. On cap: append still-deferred items to **§ Deferred** in [LEDGER.md](./LEDGER.md). Report what was reconciled vs still open. + +## In-bounds vs out-of-bounds + +**Fix:** bugs, missing tests, docs/changeset drift, lint/type/format, error-handling gaps, edge cases, **behavior-preserving refactors in touched files**, in-scope nits (naming, comment hygiene, cheap lint fixes). + +**Report only:** redesign, semantic API changes, nits outside the diff, refactors unrelated to a flagged issue. + +**Do not defer complements:** agent-surface parity (rule/skill/MCP), glossary/architecture/golden-queries contracts, script/golden tests for acceptance criteria, and cross-links named in the plan ship in the **same PR** — not "optional v2" or post-merge unless the plan **Out of scope** section explicitly excludes them. + +## Spawning subagents (non-negotiable) + +The parent agent **MUST NOT** perform reviewer duties inline. Every pass **starts** with a parallel `Task` batch; grep/read/diff by the parent is setup only, **not** a substitute for reviewers. + +| Rule | Requirement | +| --------------- | -------------------------------------------------------------------------------------------------------------------- | +| **Tool** | Cursor **`Task`** tool only (`subagent_type`: `generalPurpose` for most reviewers; `explore` for Structure lite) | +| **Batching** | One parent message → **all** applicable reviewers for that pass **in parallel** (single turn, multiple `Task` calls) | +| **Readonly** | `readonly: true` on every reviewer `Task` — reviewers report; parent fixes | +| **Pass credit** | A pass counts only after parent merges subagent JSON and acts on actionable findings | + +**Anti-pattern (invalid harden):** parent reads the diff, runs tests, fixes nits, and reports — without spawning the roster below. + +### Finding schema (every reviewer returns this) + +Each reviewer returns **only** a JSON array (no prose wrapper). Parent parses arrays from all reviewers, then merges. + +```json +{ + "finding": "One-sentence claim about a gap vs production bar", + "severity": "blocker | major | minor | nit | info", + "file": "repo-relative/path or \"multiple\"", + "line": 42, + "confidence": "high | medium | low", + "effort": "S | M | L", + "fixable_in_bounds": true, + "production_bar": "Tests | Docs | Structure | …" +} +``` + +Use `line: null` when the gap is file-level (e.g. missing test file). + +**Severity → action** + +| Severity | Parent action | +| -------------------------- | ------------------------------------------------------------------- | +| `blocker` / `major` | Fix in pass 1; must fix or defer with plan Out of scope before done | +| `minor` / `nit` | Fix when in touched files; pass 2+ if pass 1 was crowded | +| `info` | Log only unless zero-cost fix in diff | +| `fixable_in_bounds: false` | Final report deferred list — do not apply | + +**Merge + dedupe (parent, after each batch)** + +1. Concatenate all reviewer arrays. +2. Drop `info` unless it blocks ship shape. +3. Dedupe: same `file` + same root cause → keep highest severity, merge `finding` text. +4. Sort actionable: `blocker` → `major` → `minor` → `nit`; within tier → `confidence` desc → `effort` asc. +5. **Vet** (§ Vet step). +6. If vetted list is empty → pass succeeds; skip fix phase. + +**Example merged queue (pass 1)** + +```json +[ + { + "finding": "CLI --help documents summary counts but not per-row attribution on --base JSON rows.", + "severity": "major", + "file": "src/cli/cmd-audit.ts", + "line": 120, + "confidence": "high", + "effort": "S", + "fixable_in_bounds": true, + "production_bar": "Docs" + }, + { + "finding": "Skill shard leaks requiredColumns when describing attribution.", + "severity": "major", + "file": "templates/agent-content/skill/10-recipes-context.md", + "line": null, + "confidence": "high", + "effort": "M", + "fixable_in_bounds": true, + "production_bar": "Surfaces" + }, + { + "finding": "No e2e test for attribution: inherited on deprecated delta.", + "severity": "nit", + "file": "src/application/audit-worktree.test.ts", + "line": null, + "confidence": "medium", + "effort": "S", + "fixable_in_bounds": true, + "production_bar": "Tests" + } +] +``` + +### Reviewer prompt template (copy per `Task`) + +Fill `{ROLE}`, `{REPO}`, `{INTENT_ANCHOR}`, `{SCOPE}`, `{EXTRA}`; set `subagent_type` and `readonly: true`. + +```text +You are the **{ROLE}** reviewer for `/harden-pr` on `{REPO}`. + +**Intent anchor (contract — do not suggest changes that violate):** +{INTENT_ANCHOR} + +**Scope:** {SCOPE} +(lite: slice diff files; full: `git diff --name-status origin/main...HEAD`) + +**Production bar:** See harden-pr WORKFLOW.md § Production bar — optimize for {ROLE} rows. + +**Task:** {EXTRA} + +**Return ONLY** a JSON array of findings: +[{ "finding": "...", "severity": "blocker|major|minor|nit|info", "file": "...", "line": N|null, "confidence": "high|medium|low", "effort": "S|M|L", "fixable_in_bounds": true|false, "production_bar": "..." }] +If clean: [] + +Readonly — do not edit files. +``` + +**`{EXTRA}` by role** + +| Role | `{EXTRA}` | +| ------------------ | ------------------------------------------------------------------------------------------------------------------ | +| Correctness | Read changed source + tests; run affected `bun test `; bugs, edge cases, missing coverage | +| Ship-readiness | Grep inbound refs to deleted plan files; verify plan retired + lifted; changeset consumer-clean; cross-ref anchors | +| Structure (lite) | Read `docs/architecture.md` § Layering; check diff imports for boundary violations; optional codemap queries | +| Consumer surface | Read `consumer-surfaces` rule; parity across CLI help, MCP description, agent-content, README, changeset | +| Structure (full) | Run `audit-pr-architecture` skill read-only; report only fixable-in-bounds items | +| Schema / migration | `SCHEMA_VERSION`, migration paths, column contract drift | +| Security | auth, secrets, env, user-input paths in diff | +| Performance | hot paths, benchmarks, worker pools in diff | + +## Reviewer roster + +Spawn applicable reviewers **in parallel** via **`Task`** in **one batch per pass**. Each subagent returns the finding schema above. + +### Core (always — every pass) + +1. **Correctness** — gaps vs production bar; bugs, edge cases, missing tests in changed paths +2. **Ship-readiness** — gaps vs production bar; docs, changesets, consumer-surface leaks, error messages; **grep inbound refs → delete shipped plan file → lift to `golden-queries.md` / `architecture.md` / `roadmap.md`**; run [`verify-after-each-step`](../../rules/verify-after-each-step.md) checks on touched files +3. **Structure (lite)** — gaps vs production bar; boundary smells on the diff (imports across declared layers, barrel bypasses); query codemap per [`codemap`](../codemap/SKILL.md) + +### Extended (adaptive — spawn when diff triggers match) + +| Reviewer | Trigger | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **Structure (full)** | ≥5 files moved between top-level `src/` modules, new `src//` folder, or user asked for structural review → run [`audit-pr-architecture`](../audit-pr-architecture/SKILL.md) read-only; apply only fixable in-bounds items, not audit-doc recommendations that change design | +| **Schema / migration** | `src/db.ts`, `SCHEMA_VERSION`, migration paths | +| **Consumer surface** | `templates/agent-content/**`, root `README.md`, CLI help/errors, `.changeset/*.md` bodies | +| **Security** | auth, secrets, env handling, user-input paths | +| **Performance** | hot paths, benchmarks, worker pools | + +Re-derive layer globs from `docs/architecture.md` § Layering — don't hardcode module lists that drift. + +## Loop + +Execute **without pausing for user input** until exit condition: + +``` +resolve intent anchor; stamp HEAD +pass = 1 +loop: + Task-batch all applicable reviewers (parallel, readonly) + parent: merge + dedupe JSON findings (§ Finding schema) + parent: vet findings (§ Vet step) + if none actionable → goto done + fix in-bounds (pass 1: all; passes 2+: blockers first, then in-scope nits) + per fix: run verification gate from verify-after-each-step on touched files + if clean and no new findings → goto done + if pass >= max_passes → goto capped + pass += 1 + goto loop +capped: + append deferred rows to LEDGER.md § Deferred + emit deferred-nits list (each nit must cite plan Out of scope or cross-PR blocker — not "optional") +done: + if uncommitted fixes → git commit -m "harden: …" + emit final report (include babysit one-liner if full mode; include anchor HEAD stamp) +``` + +**Pass cap behavior:** after cap, stop auto-fixing; list deferred nits. Do not block the next tracer slice. + +## Git + +Skill invocation **is** the commit authorization. After the loop: if fixes exist, create one `harden: …` commit immediately — do not ask first. If the working tree is clean, skip. + +## Quick invoke + +| Intent | Say | +| ---------------- | ------------------------------------------------------ | +| Post-slice | `/harden-pr lite` or `/harden-pr` after a slice commit | +| Cheap pass | `/harden-pr quick` | +| Branch done | `/harden-pr full` or "production-ready pass" | +| Deferred backlog | `/harden-pr reconcile` | + +Replaces the old copy-paste: _"spawn subagents → fix → loop until clean"_ — this skill **is** that loop. diff --git a/.agents/skills/improve-codebase-architecture/REFERENCE.md b/.agents/skills/improve-codebase-architecture/REFERENCE.md new file mode 100644 index 00000000..b1708750 --- /dev/null +++ b/.agents/skills/improve-codebase-architecture/REFERENCE.md @@ -0,0 +1,174 @@ +# Reference + +> **See also [LANGUAGE.md](./LANGUAGE.md)** for the vocabulary every recommendation uses (module, interface, depth, seam, adapter, leverage, locality, deletion test). Read it before applying the dependency categories below — the categories assume the vocabulary. +> +> Domain terms live in [`docs/glossary.md`](../../../docs/glossary.md); canonical layering in [`docs/architecture.md`](../../../docs/architecture.md). Don't re-litigate either without marking the conflict explicitly. + +## Dependency Categories + +When assessing a candidate for deepening, classify its dependencies: + +### 1. In-process + +Pure computation, in-memory state, no I/O. Always deepenable — merge the modules and test directly. + +> **Examples in this repo.** Most of `src/application/query-engine.ts` and `search-query-parser.ts` (SQL composition, field parsing). `src/application/output-budget.ts` (adaptive snippet caps). `batchInsert()` and schema helpers in `src/db.ts` (pure tuple batching over in-memory rows). `src/parser.ts` symbol extraction (oxc AST → structured rows — the AST walk itself is in-process once the parse result is in hand). + +### 2. Local-substitutable + +Dependencies that have local test stand-ins. Deepenable if the test substitute exists. The deepened module is tested with the local stand-in running in the test suite. + +> **Examples in this repo.** In-memory SQLite (`:memory:` or temp-file DB) doubles for `.codemap/index.db` in `bun:test` — most engine tests exercise `query-engine`, `show-engine`, and `impact-engine` without a full project tree. Fixture trees under `fixtures/` double for real repos during index tests. Worker pool tests can use a single-threaded parse path or stub worker messages without spawning real `worker_threads`. `templates/recipes/` fixture SQL doubles for live recipe catalog rows when testing `recipes-loader.ts`. + +### 3. Remote but owned (Ports & Adapters) + +Your own services across a transport boundary (MCP stdio, HTTP, a future cloud sync). Define a port (interface) at the module boundary. The deep module owns the logic; the transport is injected. Tests use an in-memory adapter. Production uses the real adapter. + +Recommendation shape: "Define a handler port on `application/tool-handlers.ts` (already the seam), implement an in-memory test harness and the MCP/HTTP transport adapters for production, so query/audit/context logic stays one deep module even though agents reach it over JSON-RPC." + +> **Examples in this repo.** `application/query-engine.ts` + `application/tool-handlers.ts` are transport-agnostic; `application/mcp-server.ts` and `application/http-server.ts` are adapters. Deepening the handler layer keeps CLI, MCP, and HTTP aligned without triplicating orchestration. Async index over a future remote worker would satisfy the same `LanguageAdapter` / `ParsedFile` port at the parse seam. + +### 4. True external (Mock) + +Third-party services you don't control (`oxc-parser`, `lightningcss`, `better-sqlite3` / `bun:sqlite`, `chokidar`, `tinyglobby`). Mock at the boundary. The deepened module takes the external dependency as an injected port, and tests provide a mock / stand-in. + +> **Examples in this repo.** `oxc-parser` (`src/parser.ts` is the adapter; tests use fixture source strings or stubbed parse results). `lightningcss` (`src/css-parser.ts`). Runtime-specific SQLite drivers (`src/sqlite-db.ts` — Bun vs Node split). `chokidar` in `application/watcher.ts` (inject a fake filesystem event source in unit tests). Resolver (`src/resolver.ts` via `oxc-resolver`) when tests need deterministic import edges without a real `tsconfig`. + +## Seam discipline + +(Distilled from the principles in [LANGUAGE.md § Principles](./LANGUAGE.md#principles).) + +- **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a port unless at least two adapters are justified. Concrete example: **`LanguageAdapter`** with TS (`parser.ts`), CSS (`css-parser.ts`), and text (`markers.ts`) adapters IS a real seam — a single mega-parser pretending all extensions share one AST would invent a hypothetical seam to remove a real one. **`application/` vs `cli/`** is another real seam: programmatic API + lazy CLI chunks are two entry adapters over the same engines. +- **Internal seams vs external seams.** A deep module can have internal seams (private to its implementation, used by its own tests) as well as the external seam at its interface. Don't expose internal seams through the interface just because tests use them. Concrete example: `run-index.ts` composes glob collection, worker pool, resolver pass, and bulk insert internally; callers see `runCodemapIndex` / `Codemap.index`, not each sub-step. +- **Replace, don't layer.** Once tests live at the new external seam, the per-internal-seam unit tests on the parts you just deepened become waste — delete them in the same commit as the deepening. + +## Testing Strategy + +The core principle: **replace, don't layer.** + +- Old unit tests on shallow modules are waste once boundary tests exist — delete them. +- Write new tests at the deepened module's interface boundary. +- Tests assert on observable outcomes through the public interface, not internal state. +- Tests should survive internal refactors — they describe behaviour, not implementation. + +For boundary-enforcement candidates (rather than module-deepening), the equivalent is an **architectural regression test** at the enforced seam: import-graph scan, static source gate, or a recipe-backed assertion kept alongside the config that enforces it. Enumerate import sites with [`codemap query`](../codemap/SKILL.md) — not `Grep` — before proposing a rule. + +## Boundary enforcement + +Codemap enforces architecture at two complementary layers: + +### Index-backed boundaries (`boundaries` config) + +Users declare `boundaries: [{name, from_glob, to_glob, action?}]` in `/config.{ts,js,json}`. Every index pass reconciles `boundary_rules` in `src/db.ts`; the bundled **`boundary-violations`** recipe joins `dependencies` × `boundary_rules` and surfaces forbidden import edges. Plans that propose a new seam should include the exact config block **and** a `codemap query --recipe boundary-violations` dry-run expectation. + +Canonical layering to respect (see [`docs/architecture.md` § Layering](../../../docs/architecture.md#layering)): + +- **`application/` engines never import `cli/`** — transport-agnostic core. +- **Parsers / adapters feed `db.ts`; engines read the index** — don't let CLI flags leak into `query-engine`. +- **`templates/agent-content/**`(live-served) vs`templates/agents/**` (init-copied)** — consumer-surface split per [`.agents/rules/consumer-surfaces.md`](../../rules/consumer-surfaces.md). + +When a candidate needs post-merge structural review, fire [`audit-pr-architecture`](../audit-pr-architecture/SKILL.md) on the PR range. + +### oxlint (style + import hygiene) + +This repo runs **oxlint** (repo-root `.oxlintrc.json`) for general lint — not as the primary architectural boundary system. Use **`import/no-cycle`** and **`eslint/no-restricted-imports`** when a plan needs directional import bans codified in source (e.g. blocking `application/` → `cli/` value imports). Nested configs must **`extends`** the parent — oxlint does not auto-merge (same caveats as persist's REFERENCE). + +Example leaf for an application-layer gate: + +```json +{ + "$schema": "../../node_modules/oxlint/configuration_schema.json", + "extends": ["../.oxlintrc.json"], + "files": ["src/application/**"], + "rules": { + "no-restricted-imports": [ + "error", + { + "patterns": [ + { + "group": ["**/cli/**"], + "message": "application/ is transport-agnostic — call engines, not CLI chunks." + } + ] + } + ] + } +} +``` + +Prefer **`boundary-violations`** for cross-folder import policy that should appear in CI/SARIF alongside other recipes; prefer **oxlint** for compile-time gates on known bad import shapes. + +## Plan Template + +Plan files live at `docs/plans/.md`. Use this template: + +```md +# + +> Plan owner: . Status: **Draft / In progress / Landed**. Link from `docs/roadmap.md`. + +## Problem + +Describe the architectural friction: + +- Which modules are shallow / which seam is currently unenforced. +- What integration risk exists in the seams between them. +- Why this makes the codebase harder to navigate, modify, or test. +- (If applicable) the inline `NOTE(...)` markers in source that point here. + +## Proposed Interface (or Boundary) + +The chosen design from Step 5–6 of the skill (or [INTERFACE-DESIGN.md](./INTERFACE-DESIGN.md)): + +- Interface signature (types, methods, params), or the post-refactor `src/` shape + the boundary config / lint rule that enforces it. +- Usage example showing how callers use it. +- What complexity / which import classes it hides / forbids. + +## Dependency Strategy + +Which category from `REFERENCE.md` applies and how dependencies are handled: + +- **In-process**: merged directly. +- **Local-substitutable**: tested with [specific stand-in] (in-memory SQLite, fixture tree, stub worker messages). +- **Ports & adapters**: port definition, production adapter, test adapter. +- **Mock**: mock boundary for external services (`oxc-parser`, `lightningcss`, runtime SQLite driver, `chokidar`). + +## Migration + +- **Import sites to update**: enumerate via `codemap query` / `query_recipe fan-in` — don't guess. +- **Backwards-compatible re-exports** (if any) and the deprecation window (changeset entry). +- **Order of operations**: the smallest landing-safe slices ([tracer bullets](../../rules/tracer-bullets.md)). + +## Testing Strategy + +- **New boundary tests to write**: describe the behaviours to verify at the interface. +- **Architectural regression test** (if a boundary candidate): gate test or recipe assertion to add. +- **Old tests to delete**: list shallow-module tests that become redundant after the refactor. +- **Test environment needs**: which fixture tree, in-memory DB, or transport stub. + +## Glossary impact + +- Terms in [`docs/glossary.md`](../../../docs/glossary.md) that get renamed, added, or have their canonical name changed by this plan. Update glossary on the same PR. If the term is genuinely domain-bearing and there's no glossary entry yet, recommend [`domain-modeling`](../domain-modeling/SKILL.md) first. + +## Inspiration / specs + +- Open-spec sources consulted (LSP, SQLite, oxc, MCP, Lightning CSS) per [plan-pr-inspiration-discipline](../../rules/plan-pr-inspiration-discipline.md) — cite primitives, not peer-tool implementations. + +## Out of scope + +- Things that look related but explicitly aren't part of this plan (so reviewers don't expect them). + +## Open questions + +- Anything the plan author needs a maintainer / domain expert to answer before / during execution. +``` + +## Project-specific conventions + +- **File naming**: don't add a `-plan` suffix — the `plans/` folder provides context. `docs/plans/.md`. +- **Roadmap link format**: `[](./plans/<file>.md)` under the appropriate section in `docs/roadmap.md`. +- **Boundary candidates** should propose the exact `boundaries` config block and/or `.oxlintrc.json` override in the same plan — see [Boundary enforcement](#boundary-enforcement) above. +- **Consumer-surface changes**: when the candidate touches `package.json` `exports`, bundled agent templates (`templates/agent-content/**`, `templates/agents/**`), CLI help, or root `README.md`, the plan must include the migration path for every consumer-reachable import (and a changeset entry). Enumerate via `package.json` `exports` + [`codemap query`](../codemap/SKILL.md) — don't guess. +- **Pure dead-code removal is not a plan candidate.** Those go directly into `docs/roadmap.md`. This skill is for plans that need design discussion. +- **Glossary cross-reference**: when the proposal renames or introduces a domain term, link to (and on the same PR, update) [`docs/glossary.md`](../../../docs/glossary.md). If there's no entry yet and the term is genuinely domain-bearing, recommend [`domain-modeling`](../domain-modeling/SKILL.md) first. +- **Ship discipline**: decisions of record lift into [`docs/architecture.md`](../../../docs/architecture.md) on merge; delete the plan file per [docs-governance](../docs-governance/SKILL.md) — no "slim & keep in plans/". diff --git a/.agents/skills/pr-comment-fact-check/SKILL.md b/.agents/skills/pr-comment-fact-check/SKILL.md index f4b73865..c883d0e8 100644 --- a/.agents/skills/pr-comment-fact-check/SKILL.md +++ b/.agents/skills/pr-comment-fact-check/SKILL.md @@ -5,155 +5,30 @@ description: Triage and fact-check PR review comments against the actual codebas # PR comment fact-check -When a PR has reviewer comments (human or bot), don't apply suggestions reflexively. Each comment is a **claim about the code** that may be: - -| Verdict | What it means | Default action | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------- | -| ✅ Correct | The code does/says what the reviewer claims; their suggestion improves it. | Apply or ack. | -| ⚠️ Partially correct | Premise right, conclusion wrong (or vice versa). | Reply with the nuance; apply the salvageable part. | -| ❌ Incorrect (hallucination) | The code doesn't do what the reviewer claims, OR the reviewer cites a "best practice" that contradicts our actual rules / TS + library versions. | Push back with evidence. Don't silently change correct code to match a wrong critique. | -| 🕒 Outdated | The code already changed since the comment was posted. | Resolve with a one-line note pointing at the fix commit. | -| 💭 Style preference | Not enforced by any lint rule or skill; subjective. | Apply if cheap, otherwise defer to author. | +When a PR has reviewer comments (human or bot), don't apply suggestions reflexively. Each comment is a **claim about the code** that may be wrong, partial, outdated, or stylistic. **The agent's job is to verify before acting.** Auto-applying suggestions from LLM reviewers (Bugbot, Copilot, Cursor's own bot, CodeRabbit) is the most common silent regression source — they confidently propose changes that contradict project conventions because they don't have the project context the human team has codified in skills/rules. -## Process - -### 1. Pull the comments - -```bash -# Top-level review comments + line comments -gh pr view <number> --json reviews,comments --jq '.reviews[].body, .comments[].body' | head -100 - -# Line-level inline comments (with file + line + position) -gh api "repos/{owner}/{repo}/pulls/<number>/comments" \ - --jq '.[] | { id, path, line, body: .body[0:200], user: .user.login, in_reply_to_id }' - -# Outstanding review threads only (unresolved) -gh api graphql -f query=' - query($owner:String!, $repo:String!, $pr:Int!) { - repository(owner:$owner, name:$repo) { - pullRequest(number:$pr) { - reviewThreads(first:100) { - nodes { - isResolved - comments(first:10) { - nodes { id, path, originalLine, body, author { login } } - } - } - } - } - } - }' -F owner=<owner> -F repo=<repo> -F pr=<number> \ - --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)' -``` - -The GraphQL form is the only way to get the **resolved/unresolved** state. The REST endpoints don't expose it. Filter out resolved threads — they don't need re-triaging. - -### 2. Group comments - -For each comment, capture: - -- file path + line number (the **anchor**) -- comment body (the **claim**) -- author (human reviewer? Bugbot? Copilot? Cursor bot? CodeRabbit?) -- thread context (is this a reply to an earlier comment? what was said?) - -Group comments touching the same file/line/concern into one thread for triage — usually a reviewer makes the same point in 3 places and you only need to verify it once. - -### 3. Fact-check each claim - -For every distinct claim, **verify against the actual code and the project's authoritative sources**: - -| Claim shape | How to verify | -| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| "This function does X" | `Read` the cited file and lines. Does it actually do X? Use [`codemap`](../codemap/SKILL.md) to confirm callers / signature. | -| "This is a memory leak / race / resource leak" | Trace the dependency graph. Use `codemap` to find related state subscriptions / open handles. Run the actual code mentally or write a quick test if borderline. | -| "We should use library/pattern Y here" | Check `.agents/rules/` and `.agents/skills/` — is Y endorsed? Contradicted? Silent? Library version match? | -| "This breaks convention Z" | Find Z in the rules/skills + `docs/`. If it doesn't exist in our docs, it's not "our" convention — it's the reviewer's preference. Mark style. | -| "This isn't tested" | `Glob` for `*.test.ts` neighbours. Check the test file's coverage, not just its existence. Many behaviours have golden-query coverage in `fixtures/golden/` instead of unit tests — verify before accepting. | -| "This duplicates X elsewhere" | Use `codemap` (`SELECT FROM symbols WHERE name LIKE …`) or `Grep` for the symbol/pattern. Is it actually duplicated, or just structurally similar? | -| "This violates type-safety" | Run `bun run typecheck`. If it passes, the claim is wrong unless the reviewer can show a runtime case. | -| "Performance issue" | Quantify if possible. Many "performance" comments are speculative — ask for a measurement before accepting. Run `bun run benchmark:query` if the claim is about query stdout cost. | - -### 4. Categorize and report - -Output a triage table grouped by verdict, not by file. Make it easy for the user to scan "what to fix vs what to push back on": - -```markdown -## ✅ Correct (N) — apply - -| # | File:line | Claim (1 line) | Action | -| --- | --------- | -------------- | --------------------- | -| 1 | x.ts:42 | … | Apply suggested diff. | - -## ❌ Incorrect / hallucinated (N) — push back - -| # | File:line | Claim | Why wrong | -| --- | --------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------- | -| 2 | parser.ts | "use a regex here instead of oxc" | Codemap is AST-backed by design; `docs/architecture.md` § Parsers documents the rejection of regex-based parsing. | - -## ⚠️ Partially correct (N) - -… - -## 🕒 Outdated (N) - -… - -## 💭 Style preference (N) - -… -``` - -Then propose **the actual reply** for each comment you'd push back on — don't just say "wrong", give the reviewer the receipts (file:line link, rule reference, codemap query result, doc anchor). - -### 5. Apply / reply / resolve - -Default behaviour per category — **resolve threads you have authority over; leave the ones that need reviewer concession**: - -| Verdict | Apply? | Reply? | Resolve thread? | -| --------------------------- | ------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| ✅ Correct | Yes | Optional ack ("applied in <sha>") | **Yes** — the bot was right, the fix is in, the thread has served its purpose. Leaving it open creates noise. | -| ⚠️ Partially correct | The salvageable part | Yes — explain the nuance | **Resolve only if the reviewer agrees** (or is a bot that won't push back). Otherwise leave open. | -| ❌ Incorrect / hallucinated | No | Yes — push back with evidence (file:line, rule reference, codemap query result) | **Leave unresolved** — the reviewer (human or bot) needs to see the receipts and concede. Auto-resolving a thread you reject is dismissive. | -| 🕒 Outdated | N/A | Optional — point at the fix commit | **Yes** | -| 💭 Style preference | If cheap; otherwise defer | Brief reply if you applied | **Yes if applied**, otherwise leave open for the author to weigh in | - -The "leave unresolved when the reviewer needs to concede" rule applies even to bot reviewers — bots can iterate and update their stance on the next review pass when they see the rebuttal. - -#### If branch protection requires conversation resolution to merge - -Codemap's `main` branch protection currently does **not** require conversation resolution (verified via `gh api repos/stainless-code/codemap/branches/main/protection` — `required_conversation_resolution.enabled: false`), so the default flow above is the live flow. - -If that ever changes (or for downstream forks where it's enabled), the "leave unresolved on hallucinated comments" guidance flips: - -1. Push back with the receipts (file:line, rule reference, codemap query result) — same as the default flow. -2. Push the rebuttal-with-evidence + wait one review-cycle for the reviewer to escalate or concede. -3. **Resolve the thread regardless** — the rebuttal lives in the thread body for the next reviewer pass; the merge gate cannot be held hostage to a bot's silence. - -When this exception applies, drop a one-line summary of contested rebuttals into the **PR description** so the next reviewer sees them without scrolling through resolved threads. - -### Commands +**Workflow:** [WORKFLOW.md](./WORKFLOW.md). -```bash -# Reply to a thread — write body to a temp file first (heredocs mangle backticks in markdown) -printf '%s' '<reply text>' > /tmp/pr-<number>-reply.md -gh api "repos/{owner}/{repo}/pulls/<number>/comments" \ - --field body=@/tmp/pr-<number>-reply.md \ - -F in_reply_to=<comment_id> +## Non-negotiables -# Resolve a thread (GraphQL only — REST endpoints don't support resolve) -gh api graphql -f query='mutation($id: ID!) { - resolveReviewThread(input:{threadId:$id}) { thread { isResolved } } -}' -F id=<thread_node_id> -``` +1. **Never auto-apply suggestions** — every comment is a claim that must be verified against the actual code (`Read`), structural facts ([`codemap`](../codemap/SKILL.md)), authoritative project conventions (`.agents/rules` + skills), and toolchain signals (`bun run typecheck`, `bun run check`). +2. **Never reply "fixed!" without verifying** — that's how subtle bugs land. Apply, run the project's checks, then reply. +3. **Never dismiss a comment without evidence** — push-back is fine; evidence-free push-back wastes the reviewer's time. +4. **Categorize before acting** — sort into ✅ correct / ❌ hallucinated / ⚠️ partial / 🕒 outdated / 💭 style. Action defaults per category below. -The thread node ID (`PRRT_…`) comes from the GraphQL `reviewThreads` query in step 1 — the REST `comments` endpoint only returns the comment ID (`databaseId`), which is what `in_reply_to` takes. +| Verdict | What it means | Default action | +| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- | +| ✅ Correct | The code does/says what the reviewer claims; their suggestion improves it. | Apply + **resolve thread**. | +| ⚠️ Partially correct | Premise right, conclusion wrong (or vice versa). | Apply salvageable part + reply explaining nuance; resolve only if reviewer agrees. | +| ❌ Incorrect (hallucination) | The code doesn't do what the reviewer claims, OR the reviewer cites a "best practice" that contradicts our actual rules / TS + library versions. | Push back with evidence; **leave unresolved** (merge-gate exception in WORKFLOW). | +| 🕒 Outdated | The code already changed since the comment was posted. | Point at fix commit + **resolve**. | +| 💭 Style preference | Not enforced by any lint rule or skill; subjective. | Apply if cheap + resolve; otherwise defer to author. | -## Common hallucination patterns to watch for +## Hallucination catalog (scrutinize harder) -These come up repeatedly with LLM reviewers and warrant extra scrutiny. The codemap-shape ones (1–4) come from the codemap thesis — what Codemap deliberately is and isn't (per [`docs/why-codemap.md` § When to reach for something else](../../../docs/why-codemap.md#when-to-reach-for-something-else) and [`docs/roadmap.md` § Non-goals](../../../docs/roadmap.md#non-goals-v1)). The shape-5+ ones are universal across TS projects: +Common LLM-reviewer patterns on this repo. The codemap-shape ones (1–4) come from the codemap thesis — what Codemap deliberately is and isn't (per [`docs/why-codemap.md` § When to reach for something else](../../../docs/why-codemap.md#when-to-reach-for-something-else) and [`docs/roadmap.md` § Non-goals](../../../docs/roadmap.md#non-goals-v1)). The shape-5+ ones are universal across TS projects: 1. **"Just regex this"** when the file is in `src/parser.ts`, `src/css-parser.ts`, or `src/adapters/` — codemap is AST-backed by design (oxc for TS, lightningcss for CSS). Suggesting a regex replacement undoes the architectural choice. Verify against [`docs/architecture.md` § Parsers](../../../docs/architecture.md#parsers) before accepting. 2. **"Add full-text search"** — explicitly a non-goal per [`docs/roadmap.md` § Non-goals (v1)](../../../docs/roadmap.md#non-goals-v1). Push back with that anchor. @@ -176,7 +51,7 @@ These come up repeatedly with LLM reviewers and warrant extra scrutiny. The code ## Reference - Codemap (structural verification): [`codemap`](../codemap/SKILL.md). -- `gh` CLI for PR comments: <https://cli.github.com/manual/gh_pr_view>, <https://cli.github.com/manual/gh_api>. -- GitHub GraphQL for resolved/unresolved state: <https://docs.github.com/en/graphql/reference/objects#pullrequestreviewthread>. -- [`docs/why-codemap.md`](../../../docs/why-codemap.md) and [`docs/roadmap.md` § Non-goals](../../../docs/roadmap.md#non-goals-v1) — the canonical anchors for "this is a non-goal" push-backs (hallucination patterns 2–3 above). +- [`verify-after-each-step`](../../rules/verify-after-each-step.md) — run after applying a fix. +- [`harden-pr`](../harden-pr/SKILL.md) — optional full pass on the branch once triage is complete. +- [`docs/why-codemap.md`](../../../docs/why-codemap.md) and [`docs/roadmap.md` § Non-goals](../../../docs/roadmap.md#non-goals-v1) — canonical anchors for "this is a non-goal" push-backs (hallucination patterns 2–3 above). - [`pr-comment-fact-check` rule](../../rules/pr-comment-fact-check.md) — Tier 1 priming layer that fires this skill on intent. diff --git a/.agents/skills/pr-comment-fact-check/WORKFLOW.md b/.agents/skills/pr-comment-fact-check/WORKFLOW.md new file mode 100644 index 00000000..4e31479b --- /dev/null +++ b/.agents/skills/pr-comment-fact-check/WORKFLOW.md @@ -0,0 +1,147 @@ +# PR comment fact-check — workflow + +## Process + +### 1. Pull the comments + +```bash +# Top-level review comments + line comments +gh pr view <number> --json reviews,comments --jq '.reviews[].body, .comments[].body' | head -100 + +# Line-level inline comments (with file + line + position) +gh api "repos/{owner}/{repo}/pulls/<number>/comments" \ + --jq '.[] | { id, path, line, body: .body[0:200], user: .user.login, in_reply_to_id }' + +# Outstanding review threads only (unresolved) +gh api graphql -f query=' + query($owner:String!, $repo:String!, $pr:Int!) { + repository(owner:$owner, name:$repo) { + pullRequest(number:$pr) { + reviewThreads(first:100) { + nodes { + isResolved + comments(first:10) { + nodes { id, path, originalLine, body, author { login } } + } + } + } + } + } + }' -F owner=<owner> -F repo=<repo> -F pr=<number> \ + --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)' +``` + +The GraphQL form is the only way to get the **resolved/unresolved** state. The REST endpoints don't expose it. Filter out resolved threads — they don't need re-triaging. + +**Done when:** all unresolved threads fetched; count logged. + +### 2. Group comments + +For each comment, capture: + +- file path + line number (the **anchor**) +- comment body (the **claim**) +- author (human reviewer? Bugbot? Copilot? Cursor bot? CodeRabbit?) +- thread context (is this a reply to an earlier comment? what was said?) + +Group comments touching the same file/line/concern into one thread for triage — usually a reviewer makes the same point in 3 places and you only need to verify it once. + +### 3. Fact-check each claim + +For every distinct claim, **verify against the actual code and the project's authoritative sources**: + +| Claim shape | How to verify | +| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| "This function does X" | `Read` the cited file and lines. Does it actually do X? Use [`codemap`](../codemap/SKILL.md) to confirm callers / signature. | +| "This is a memory leak / race / resource leak" | Trace the dependency graph. Use `codemap` to find related state subscriptions / open handles. Run the actual code mentally or write a quick test if borderline. | +| "We should use library/pattern Y here" | Check `.agents/rules/` and `.agents/skills/` — is Y endorsed? Contradicted? Silent? Library version match? | +| "This breaks convention Z" | Find Z in the rules/skills + `docs/`. If it doesn't exist in our docs, it's not "our" convention — it's the reviewer's preference. Mark style. | +| "This isn't tested" | `Glob` for `*.test.ts` neighbours. Check the test file's coverage, not just its existence. Many behaviours have golden-query coverage in `fixtures/golden/` instead of unit tests — verify before accepting. | +| "This duplicates X elsewhere" | Use `codemap` (`SELECT FROM symbols WHERE name LIKE …`) or `Grep` for the symbol/pattern. Is it actually duplicated, or just structurally similar? | +| "This violates type-safety" | Run `bun run typecheck`. If it passes, the claim is wrong unless the reviewer can show a runtime case. | +| "Performance issue" | Quantify if possible. Many "performance" comments are speculative — ask for a measurement before accepting. Run `bun run benchmark:query` if the claim is about query stdout cost. | + +**Done when:** every distinct claim has file:line (or tool) evidence and a verdict. + +### 4. Categorize and report + +Output a triage table grouped by verdict, not by file. Make it easy for the user to scan "what to fix vs what to push back on": + +```markdown +## ✅ Correct (N) — apply + +| # | File:line | Claim (1 line) | Action | +| --- | --------- | -------------- | --------------------- | +| 1 | x.ts:42 | … | Apply suggested diff. | + +## ❌ Incorrect / hallucinated (N) — push back + +| # | File:line | Claim | Why wrong | +| --- | --------- | --------------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| 2 | parser.ts | "use a regex here instead of oxc" | Codemap is AST-backed by design; `docs/architecture.md` § Parsers documents the rejection of regex-based parsing. | + +## ⚠️ Partially correct (N) + +… + +## 🕒 Outdated (N) + +… + +## 💭 Style preference (N) + +… +``` + +Then propose **the actual reply** for each comment you'd push back on — don't just say "wrong", give the reviewer the receipts (file:line link, rule reference, codemap query result, doc anchor). + +### 5. Apply / reply / resolve + +Default behaviour per category — **resolve threads you have authority over; leave the ones that need reviewer concession**: + +| Verdict | Apply? | Reply? | Resolve thread? | +| --------------------------- | ------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| ✅ Correct | Yes | Optional ack ("applied in <sha>") | **Yes** — the bot was right, the fix is in, the thread has served its purpose. Leaving it open creates noise. | +| ⚠️ Partially correct | The salvageable part | Yes — explain the nuance | **Resolve only if the reviewer agrees** (or is a bot that won't push back). Otherwise leave open. | +| ❌ Incorrect / hallucinated | No | Yes — push back with evidence (file:line, rule reference, codemap query result) | **Leave unresolved** — the reviewer (human or bot) needs to see the receipts and concede. Auto-resolving a thread you reject is dismissive. | +| 🕒 Outdated | N/A | Optional — point at the fix commit | **Yes** | +| 💭 Style preference | If cheap; otherwise defer | Brief reply if you applied | **Yes if applied**, otherwise leave open for the author to weigh in | + +The "leave unresolved when the reviewer needs to concede" rule applies even to bot reviewers — bots can iterate and update their stance on the next review pass when they see the rebuttal. + +#### If branch protection requires conversation resolution to merge + +Codemap's `main` branch protection currently does **not** require conversation resolution (verified via `gh api repos/stainless-code/codemap/branches/main/protection` — `required_conversation_resolution.enabled: false`), so the default flow above is the live flow. + +If that ever changes (or for downstream forks where it's enabled), the "leave unresolved on hallucinated comments" guidance flips: + +1. Push back with the receipts (file:line, rule reference, codemap query result) — same as the default flow. +2. Push the rebuttal-with-evidence + wait one review-cycle for the reviewer to escalate or concede. +3. **Resolve the thread regardless** — the rebuttal lives in the thread body for the next reviewer pass; the merge gate cannot be held hostage to a bot's silence. + +When this exception applies, drop a one-line summary of contested rebuttals into the **PR description** so the next reviewer sees them without scrolling through resolved threads. + +The exception applies to `❌ hallucinated` and `⚠️ partial — needs a call` rows. The other rows already resolve by default. + +**Done when:** triage table covers every unresolved thread; ✅/⚠️ rows applied or replied; resolve policy from table + merge-gate exception applied. + +### Commands + +```bash +# Reply to a thread — write body to a temp file first (heredocs mangle backticks in markdown) +printf '%s' '<reply text>' > /tmp/pr-<number>-reply.md +gh api "repos/{owner}/{repo}/pulls/<number>/comments" \ + --field body=@/tmp/pr-<number>-reply.md \ + -F in_reply_to=<comment_id> + +# Resolve a thread (GraphQL only — REST endpoints don't support resolve) +gh api graphql -f query='mutation($id: ID!) { + resolveReviewThread(input:{threadId:$id}) { thread { isResolved } } +}' -F id=<thread_node_id> +``` + +The thread node ID (`PRRT_…`) comes from the GraphQL `reviewThreads` query in step 1 — the REST `comments` endpoint only returns the comment ID (`databaseId`), which is what `in_reply_to` takes. + +### After applying + +Run [`verify-after-each-step`](../../rules/verify-after-each-step.md) checks on touched files. Optional: [`harden-pr`](../harden-pr/SKILL.md) full on the branch once triage is complete. diff --git a/.agents/skills/tdd/PATTERNS.md b/.agents/skills/tdd/PATTERNS.md new file mode 100644 index 00000000..b41cc8b2 --- /dev/null +++ b/.agents/skills/tdd/PATTERNS.md @@ -0,0 +1,90 @@ +# Good and bad tests (this repo) + +Loaded from [`tdd`](./SKILL.md). Multiple runners — pick by whether the behavior is unit logic, golden SQL output, or script harness (see [`docs/testing-coverage.md`](../../../docs/testing-coverage.md)). + +## Good tests + +Integration-style through the **public seams** (parser entry, DB insert path, CLI handler, recipe SQL output): + +```ts +import { describe, expect, it } from "bun:test"; +import Database from "better-sqlite3"; +import { insertFile, openDb } from "../db"; + +describe("insertFile", () => { + it("persists path and language for a new file row", () => { + const db = openDb(new Database(":memory:")); + insertFile(db, { path: "src/foo.ts", language: "typescript" }); + const row = db + .prepare("SELECT path, language FROM files WHERE path = ?") + .get("src/foo.ts"); + expect(row).toEqual({ path: "src/foo.ts", language: "typescript" }); + }); +}); +``` + +Characteristics: + +- Observable behavior callers care about (index rows, recipe output, CLI exit code, parse symbols) +- Public seam only — `extractFileData`, `batchInsert`, a `cmd-*` handler, golden scenario SQL +- Survives internal refactors of parsers/engines +- One logical assertion per test + +## Bad tests + +```ts +// BAD: mocks an internal helper of the parser +vi.mock("./internal-visitor", () => ({ walkSymbols: () => [] })); + +// BAD: asserts call order on a private batch scheduler +expect(internalBatchQueue.flush).toHaveBeenCalledBefore(insertSymbols); + +// BAD: reaches past the seam — reads the DB helper's internal cache +expect(db.__cache.get("files")).toEqual(rows); + +// BAD: golden test that snapshots the entire index.db binary +expect(fs.readFileSync("index.db")).toMatchSnapshot(); +``` + +Red flags: mocking own modules under `src/`, testing private helpers, call-count assertions, tests that break on a rename-only refactor, golden snapshots that aren't stable JSON contracts. + +## Mock boundaries + +Mock at the **parser or DB seam** only: + +- **OK to fake** — `:memory:` SQLite via `better-sqlite3`; a minimal fixture file string passed to `extractFileData`; resolver results stubbed at the adapter boundary. +- **Don't mock** — internals of `src/parser.ts` under test, real `batchInsert` when testing insert logic (use `:memory:` DB instead), golden runner internals when testing recipe SQL (exercise the real scenario file). + +```ts +// GOOD: fake the DB, exercise the real insert path +const db = openDb(new Database(":memory:")); +insertSymbols(db, symbolsFromFixture); +``` + +Designing for mockability: engines already accept `Database` and parsed AST inputs as arguments — no module-scope globals to wrestle with. Prefer `:memory:` DB over mocking `better-sqlite3` unless the bug only reproduces against on-disk WAL behavior. + +## Golden / recipe tests + +Test recipe **output shape**, not implementation: + +```ts +// GOOD: behavior through declared golden scenario +// scenarios.json expects row count + key columns for find-symbol-definitions + +// BAD: asserts on internal SQL string assembly in recipes-loader +expect(loader.__compiled.get("fan-in")).toContain("WITH RECURSIVE"); +``` + +Refresh goldens after intentional schema or fixture changes: `bun scripts/query-golden.ts --update`. + +## Script harness tests (`scripts/**/*.test.mjs`) + +Test what a maintainer script exposes (CLI args, file transforms), not Node internals: + +```js +// GOOD: behavior through public script output +expect(await runScript(["--dry-run"])).toMatchObject({ ok: true }); + +// BAD: asserts on internal subprocess spawn count +expect(spawnMock).toHaveBeenCalledTimes(3); +``` diff --git a/.agents/skills/tdd/SKILL.md b/.agents/skills/tdd/SKILL.md new file mode 100644 index 00000000..7978dd1d --- /dev/null +++ b/.agents/skills/tdd/SKILL.md @@ -0,0 +1,55 @@ +--- +name: tdd +description: Test-driven development with vertical tracer-bullet slices. Use when building test-first, red-green-refactor, or when the user mentions TDD. +--- + +# Test-driven development + +Vertical RED→GREEN cycles — **one behavior per loop**, not horizontal "all tests then all code". Aligns with [`tracer-bullets`](../../rules/tracer-bullets.md) and [`verify-after-each-step`](../verify-after-each-step/SKILL.md). + +## This repo + +- Runner split per [`docs/testing-coverage.md`](../../../docs/testing-coverage.md): + - `bun test ./src` — co-located unit tests (parsers, DB, engines, CLI/MCP handlers). Mock at parser/DB seams. + - `bun run test:golden` — index `fixtures/minimal`, run SQL scenarios vs committed goldens. + - `bun run test:scripts` — `scripts/**/*.test.mjs`. + - `bun run test:agent-eval` — probe/live agent eval harness (after golden index when applicable). +- Co-locate tests next to the module (`src/db.ts` → `src/db.test.ts`). +- After each GREEN: format/lint/typecheck per [`verify-after-each-step`](../verify-after-each-step/SKILL.md). +- Mock at the **parser or DB seam** (fake `:memory:` DB, stub adapter input), never inside the engine under test. See [`PATTERNS.md`](./PATTERNS.md). + +## Workflow + +### 1. Planning + +Confirm **behaviors** to test (not implementation steps) with the user. Prefer deep modules — small public surface (`extractFileData`, `batchInsert`, a recipe handler), complex internals. + +### 2. Tracer bullet (within slice) + +``` +RED: one test for first behavior → bun test <file> (or test:golden when recipe/SQL output is the contract) +GREEN: minimal code to pass → re-run +``` + +### 3. Incremental loop + +For each behavior: RED → GREEN → run affected tests. One test at a time; no speculative features. + +### 4. Refactor + +After GREEN — look for duplication, long methods, shallow modules, feature envy. Run `bun test <file>` after each step. **Never refactor while RED.** For production polish on a completed slice, [`harden-pr`](../harden-pr/SKILL.md) lite may run in parallel with tracer-bullet commits. + +## Checklist per cycle + +``` +[ ] Test describes behavior, not implementation +[ ] Test uses the public seam only (parser entry, DB insert path, CLI handler, recipe output) +[ ] Test would survive an internal refactor +[ ] Code is minimal for this test +[ ] bun test (or test:golden / test:scripts) passes on touched file(s) +``` + +## Reference + +- Good/bad test patterns + mock boundaries: [`PATTERNS.md`](./PATTERNS.md) +- Slice cadence: [`tracer-bullets`](../../rules/tracer-bullets.md) · Verify: [`verify-after-each-step`](../verify-after-each-step/SKILL.md) diff --git a/.agents/skills/tracer-bullets/SKILL.md b/.agents/skills/tracer-bullets/SKILL.md new file mode 100644 index 00000000..47329a7f --- /dev/null +++ b/.agents/skills/tracer-bullets/SKILL.md @@ -0,0 +1,59 @@ +--- +name: tracer-bullets +description: Codemap feature layers and worked tracer-bullet examples — vertical slices for new source extensions, SQLite schema changes, and CLI flags. Use when planning a feature as a tracer bullet and deciding slice boundaries across CLI/parser/db/test/docs layers. +disable-model-invocation: true +--- + +# Tracer bullets — codemap feature layers and examples + +Always-on rule: [`.agents/rules/tracer-bullets.md`](../../rules/tracer-bullets.md) (the 5 rules + lite-harden). This skill carries the codemap layer map and worked examples. + +## Feature layers in this project + +A typical vertical slice for codemap touches these layers top-to-bottom: + +1. **CLI / orchestration** — `src/cli/` (`bootstrap.ts`, `main.ts`, lazy `cmd-*` chunks; entry `src/index.ts`) +2. **Workers / parsing** — `src/parse-worker.ts` / `parse-worker-node.ts`, `parse-worker-core.ts`, `src/parser.ts`, `src/css-parser.ts`, `src/adapters/` +3. **Persistence** — `src/db.ts` (schema, inserts, `SCHEMA_VERSION`) +4. **Config / runtime** — `src/config.ts`, `src/runtime.ts`, resolver +5. **Tests** — `src/*.test.ts` +6. **Docs** — `docs/*.md` when behavior is user-visible + +## Example 1: Support a new source extension + +Bad — building in layers: + +- Update every glob, parser, and docs in one giant change +- Hope CI and the index agree + +Good — tracer bullet: + +1. **`constants` + adapter** — `LANG_MAP` + builtin adapter extensions + `extractFileData` — commit, `bun run check`, small test parsing a one-line file +2. **Resolver** — `resolver` extensions if needed — commit, validate +3. **Docs** — `docs/architecture.md` table row — commit, validate + +## Example 2: Add a new SQLite column or table + +Bad — schema + all call sites + benchmarks in one unreviewable diff. + +Good — tracer bullet: + +1. **Schema + insert path** — `db.ts` + one write path exercised by a test or CLI run — commit, validate +2. **Readers / query UX** — expose in `query` or docs — commit, validate +3. **Benchmark / fixtures** — if numbers matter — separate commit + +## Example 3: New CLI flag + +Bad — flag parsing, help text, config, and tests all speculative. + +Good — tracer bullet: + +1. **Parse flag + minimal behavior** — e.g. `--dry-run` that only logs — commit, test +2. **Wire to real work** — connect to indexer — commit, validate +3. **Document** — README / `docs/architecture.md` — commit + +## Commit cadence + +Each commit should represent a functional, describable milestone — not a placeholder. Every tracer bullet is a shippable slice that works end-to-end, even if the feature isn't complete yet. Small commits get validated by the pre-commit hook and are easier to review and revert. + +Before opening a PR, run [`harden-pr`](../harden-pr/SKILL.md) in **full** mode on `origin/main...HEAD` (or accept the offer when the plan checklist is complete). diff --git a/.agents/skills/verify-after-each-step/SKILL.md b/.agents/skills/verify-after-each-step/SKILL.md new file mode 100644 index 00000000..c5d75ded --- /dev/null +++ b/.agents/skills/verify-after-each-step/SKILL.md @@ -0,0 +1,52 @@ +--- +name: verify-after-each-step +description: Per-file verification checklist — lint-staged and package.json scripts after each milestone. +disable-model-invocation: true +--- + +# Verify after each step (full checklist) + +Always-on priming: [`.agents/rules/verify-after-each-step.md`](../../rules/verify-after-each-step.md). + +Run matching checks on every file touched **before** moving to the next milestone. Pre-commit is the safety net, not the first line of defense. + +## Discover project scripts + +1. **Read `package.json` `scripts`** at the start of a task. +2. **Read `lint-staged.config.js`** — which checks apply to which patterns (staged-only tsgo, paired co-located tests). +3. Never assume script names — verify they exist in `package.json` before running. + +## Per-file check table (this repo) + +From `lint-staged.config.js` — mirror these between milestones, not only at commit: + +| File pattern | Checks | +| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `*.{js,jsx,ts,tsx,mjs,mts,cjs,cts}` | `bun run format:check`, `bun run lint` | +| `*.{css,json,md,mdc,html,yaml,yml}` | `bun run format:check` | +| `*.{ts,tsx}` | `bun run typecheck` with a temporary `tsconfig.lint-staged.json` that includes only **staged files under `src/`** (project-wide types still interconnect — use `bun run typecheck` if you need full-project certainty); **`bun test`** on co-located `*.test.{ts,tsx}` pairs when a staged `src/` source file is present but its test file is not | +| `*.test.ts` | `bun test` (on changed test files) | +| `*.test.tsx` | `bun test` (on changed test files) | +| `scripts/**/*.test.mjs` | `bun test` (on changed test files) | + +**Co-located pair:** `foo.ts` → `foo.test.ts` (lint-staged runs the pair when only the source is staged — mirror that here). + +**Build config / entry points:** if `tsdown.config.ts`, `package.json` `exports`, or an entry module changed, add `bun run build`. + +**Golden / agent eval:** if recipe SQL, schema, or golden fixtures changed, add `bun run test:golden` (and `bun run test:agent-eval` when probe scenarios depend on the index). + +Full gate before commit/push: `bun run check` (build + format + lint:ci + test + test:scripts + typecheck + test:golden + test:agent-eval). `.agents/` / `docs/` / `.github/` only need `bun run format:check` unless content affects runtime. + +## Re-index before querying Codemap + +If you changed indexed source and plan to run SQL against the structural index next, run: + +```bash +bun src/index.ts --files <paths> +``` + +Paths must be **relative to the indexed project root**. Set `CODEMAP_TEST_BENCH` / `CODEMAP_ROOT` or `--root` so that root is correct — see [docs/benchmark.md § Indexing another project](../../../docs/benchmark.md#indexing-another-project). + +## Reference + +Tier-1 priming: [`.agents/rules/verify-after-each-step.md`](../../rules/verify-after-each-step.md) · [`tracer-bullets`](../../rules/tracer-bullets.md) · [`no-bypass-hooks`](../../rules/no-bypass-hooks.md) · [`harden-pr`](../harden-pr/SKILL.md) diff --git a/.agents/skills/write-a-skill/SKILL.md b/.agents/skills/write-a-skill/SKILL.md index a0f9611d..9748e44a 100644 --- a/.agents/skills/write-a-skill/SKILL.md +++ b/.agents/skills/write-a-skill/SKILL.md @@ -3,17 +3,17 @@ name: write-a-skill description: Create new agent skills with proper structure, progressive disclosure, and bundled resources. Use when user wants to create, write, or build a new skill (or asks "how do I write a skill?", "draft a SKILL.md for X"). --- -# Writing Skills +# Writing skills -Discipline for authoring `.agents/skills/<name>/SKILL.md` files in this repo. +Codemap-specific deltas for authoring `.agents/skills/<name>/SKILL.md`. **Read [`writing-great-skills`](../writing-great-skills/SKILL.md) first** for generic principles — invocation, information hierarchy, progressive disclosure, pruning, leading words, failure modes. ## Repo conventions you must respect -Before drafting any skill in codemap, internalise these (they trump anything in this skill): +These trump anything generic: -- **File layout** — [`agents-first-convention`](../../rules/agents-first-convention.md): the source-of-truth file is `.agents/skills/<name>/SKILL.md`; the `.cursor/skills/<name>` entry is a **symlink** back. Never put original content under `.cursor/`. -- **Tier choice** — [`agents-tier-system`](../../rules/agents-tier-system.md): every new skill is Tier 1 (always-on, paired with a rule), Tier 2 (auto-attached to a glob, paired with a rule), or Tier 3 (discoverable, no rule). **Skills with `NEVER` / `ALWAYS` clauses deserve a rule pairing.** Pure intent-trigger skills (no hard "must" clauses) stay Tier 3. -- **Maintainer-only vs shipped** — `.agents/skills/` is the dev-side mirror; `templates/agents/skills/` is what `codemap agents init` ships to npm consumers. The bundled template surface today is **only** the `codemap` skill — every other skill in `.agents/skills/` is maintainer-only (precedent: PR #25). Don't add a skill to `templates/agents/` unless it's something every consumer of the published package would want. +- **File layout** — [`agents-first-convention`](../../rules/agents-first-convention.md): source of truth is `.agents/skills/<name>/SKILL.md`; `.cursor/skills/<name>` is a **symlink** back. Never put original content under `.cursor/`. +- **Tier choice** — [`agents-tier-system`](../../rules/agents-tier-system.md): Tier 1 (always-on + rule), Tier 2 (glob-attached + rule), or Tier 3 (discoverable, no rule). Skills with `NEVER` / `ALWAYS` clauses deserve a rule pairing. Pure intent-trigger skills stay Tier 3. +- **Maintainer-only vs shipped** — `.agents/skills/` is the dev-side mirror; `templates/agents/skills/` is what `codemap agents init` ships. The bundled template surface today is **only** the `codemap` skill — every other skill in `.agents/skills/` is maintainer-only (precedent: PR #25). Don't add to `templates/agents/` unless every npm consumer would want it. Consumer-surface policy: [`.agents/rules/consumer-surfaces.md`](../../rules/consumer-surfaces.md). ## Process @@ -25,17 +25,17 @@ Ask the user: - What specific use cases should it handle? - Does it need executable scripts (under `scripts/`) or just instructions? - Any reference materials to include? -- **Tier choice**: does the skill have always-on principles (any `NEVER` / `ALWAYS` clauses)? If yes, it deserves a Tier-1 or Tier-2 rule pairing per [`agents-tier-system`](../../rules/agents-tier-system.md). +- **Tier choice**: always-on principles (`NEVER` / `ALWAYS` clauses)? If yes → Tier-1 or Tier-2 rule pairing per [`agents-tier-system`](../../rules/agents-tier-system.md). -### 2. Draft the skill +Use [`grill-me`](../grill-me/SKILL.md) on yourself before drafting — trigger phrase shape, boundary with adjacent skills, durability test (still correct six months from now?). -Create: +### 2. Draft the skill -- `SKILL.md` with concise instructions (under 100 lines if possible — see "When to split" below) -- Companion files (`LANGUAGE.md`, `REFERENCE.md`, `EXAMPLES.md`, etc.) when content exceeds 100 lines or has distinct domains -- `scripts/<name>.{sh,ts}` when a deterministic operation is invoked repeatedly (saves tokens vs generated code) +Apply [`writing-great-skills`](../writing-great-skills/SKILL.md) for structure, description, disclosure, and split decisions. Codemap precedents for companion files: -Use [`grill-me`](../grill-me/SKILL.md) on yourself to surface decisions before you write — what's the trigger phrase shape? What's the boundary with adjacent skills? What's the durability test (does this skill still read correctly six months from now)? +- [`improve-codebase-architecture`](../improve-codebase-architecture/SKILL.md) — `LANGUAGE.md`, `DEEPENING.md`, `INTERFACE-DESIGN.md`, `REFERENCE.md` +- [`pr-comment-fact-check`](../pr-comment-fact-check/SKILL.md) — slim `SKILL.md` + `WORKFLOW.md` (gh/graphql fetch + triage flow split out) +- [`harden-pr`](../harden-pr/SKILL.md) — slim `SKILL.md` + `WORKFLOW.md` + `LEDGER.md` ### 3. Wire the file layout @@ -47,112 +47,17 @@ Use [`grill-me`](../grill-me/SKILL.md) on yourself to surface decisions before y ln -s ../../.agents/skills/<name> .cursor/skills/<name> ``` -### 4. Update the tier list +### 4. Tier placement -Add the skill to the relevant list in [`agents-tier-system.md`](../../rules/agents-tier-system.md) so the inventory stays accurate. +Tiers are discovered on disk via the frontmatter audit (see [`agents-tier-system` skill](../agents-tier-system/SKILL.md)) — there is no name list to update. Just set the new skill's frontmatter correctly: `alwaysApply: true` (Tier 1, needs a rule), `globs:` (Tier 2, needs a rule), or `description:`-only (Tier 3, no rule). ### 5. Review -Ask the user: - -- Does this cover your use cases? -- Anything missing or unclear? -- Should any section be more / less detailed? - -Run the [Review checklist](#review-checklist) before declaring done. - -## Skill structure - -```text -.agents/skills/<name>/ -├── SKILL.md # Main instructions (required) -├── LANGUAGE.md # Vocabulary the skill enforces (if any) -├── REFERENCE.md # Detailed docs (if SKILL.md exceeds ~100 lines) -├── EXAMPLES.md # Usage examples (if needed) -└── scripts/ # Utility scripts (if needed) - └── helper.sh -``` - -## SKILL.md template - -```md ---- -name: skill-name -description: Brief description of capability. Use when [specific triggers — verbs and nouns the user is likely to say, plus contexts where the skill applies]. ---- - -# Skill Name - -## Quick start - -[Minimal working example — what the user does on first invocation] - -## Workflows - -[Step-by-step processes with checklists for complex tasks] - -## Advanced features - -[Link to companion files: See [REFERENCE.md](REFERENCE.md) / [LANGUAGE.md](LANGUAGE.md)] -``` - -## Description requirements - -The description is **the only thing the agent sees** when deciding which skill to load. It's surfaced in the discoverable-skills list alongside every other installed skill. Get this right or your skill never fires. - -**Goal**: Give the agent just enough info to know: - -1. What capability this skill provides -2. When / why to trigger it (specific keywords, contexts, file types) - -**Format**: - -- Max ~1024 chars -- Write in third person -- First sentence: what it does -- Second sentence: "Use when [specific triggers]" -- Include the verbs and nouns the user is likely to say (per [`agents-tier-system` § Tier 3 description](../../rules/agents-tier-system.md)) - -**Good example**: - -```text -Triage and fact-check PR review comments against the actual codebase, project rules, and skills. Use when the user asks to address PR comments, respond to reviewer feedback, check if a comment is correct, fact-check a reviewer's claim, decide which comments to push back on, or sort hallucinated suggestions from real ones. Triggers on phrases like "check PR comments", "are these comments right". -``` - -**Bad example**: - -```text -Helps with PRs. -``` - -The bad example gives the agent no way to distinguish this from any other PR-adjacent skill. - -## When to add scripts - -Add utility scripts under `scripts/` when: - -- Operation is deterministic (validation, formatting, bisection harness) -- Same code would be generated repeatedly across invocations -- Errors need explicit handling that's tedious to re-derive - -Scripts save tokens and improve reliability vs generated code. - -## When to split files - -Split into companion files when: - -- `SKILL.md` exceeds ~100 lines -- Content has distinct domains (vocabulary vs process vs templates) -- Advanced features are rarely needed and would balloon the main file - -Cite codemap precedents: - -- [`improve-codebase-architecture`](../improve-codebase-architecture/SKILL.md) splits into `LANGUAGE.md` (vocab), `DEEPENING.md` (sub-rules), `INTERFACE-DESIGN.md` (parallel-sub-agent pattern). -- [`pr-comment-fact-check`](../pr-comment-fact-check/SKILL.md) stays single-file because every section is in-flow process. +Run the [checklist](#checklist) before declaring done. ## Durability discipline -Per [`agents-tier-system` § Authoring discipline: durability](../../rules/agents-tier-system.md): +Per [`agents-tier-system` § Authoring discipline: durability](../agents-tier-system/SKILL.md#authoring-discipline-durability): - **Don't cite specific audit / plan / research filenames as canonical examples.** Plans are mortal under [`docs-lifecycle-sweep`](../docs-lifecycle-sweep/SKILL.md). Use shape placeholders (`<topic>.md`) instead. - **Don't cite specific commit hashes or PR numbers as the only path to context.** Summarise inline. @@ -160,17 +65,11 @@ Per [`agents-tier-system` § Authoring discipline: durability](../../rules/agent If the skill still reads correctly six months from now after every doc you didn't write got rewritten, it's durable. -## Review checklist - -After drafting, verify: +## Checklist -- [ ] Description includes triggers ("Use when…") -- [ ] `SKILL.md` under 100 lines OR has split companion files -- [ ] No time-sensitive info (no "as of 2026-04…") -- [ ] Consistent terminology — drift kills clarity -- [ ] Concrete examples included -- [ ] Cross-references one level deep (don't chain `SKILL.md → REFERENCE.md → DEEP-DIVE.md → REFERENCE2.md`) +- [ ] Read [`writing-great-skills`](../writing-great-skills/SKILL.md) — description, hierarchy, disclosure applied - [ ] File layout follows [`agents-first-convention`](../../rules/agents-first-convention.md) (`.agents/` source + `.cursor/` symlink) -- [ ] Tier choice documented per [`agents-tier-system`](../../rules/agents-tier-system.md); rule pairing added if the skill has `NEVER` / `ALWAYS` clauses -- [ ] Skill listed in the appropriate tier section of `agents-tier-system.md` +- [ ] Tier choice documented per [`agents-tier-system`](../../rules/agents-tier-system.md); rule pairing if `NEVER` / `ALWAYS` clauses +- [ ] Frontmatter tier mode set correctly (`alwaysApply` / `globs` / `description`-only) — discoverable via the `agents-tier-system` audit - [ ] Decision recorded in the PR description: maintainer-only (`.agents/` only) vs shipped (`templates/agents/` too) +- [ ] No time-sensitive info; durable citations only (see [Durability discipline](#durability-discipline)) diff --git a/.agents/skills/writing-agents-config/SKILL.md b/.agents/skills/writing-agents-config/SKILL.md new file mode 100644 index 00000000..251777c6 --- /dev/null +++ b/.agents/skills/writing-agents-config/SKILL.md @@ -0,0 +1,80 @@ +--- +name: writing-agents-config +description: Codemap repo hybrid deltas for .agents/ — tiers, rule-skill pairing, repo exemplars. Use when creating or reviewing rules/skills in this repo. Read writing-great-skills first for skill vocabulary and authoring principles. +disable-model-invocation: true +--- + +# Writing agents config + +**Read first:** [`writing-great-skills`](../writing-great-skills/SKILL.md) — invocation, information hierarchy, completion criteria, pruning, failure modes. + +This repo adds **Cursor rules** (Tier 1/2/3) on top of a skills-only agent model — always-on STOP rules where cross-turn non-negotiables beat description-only triggers. + +**Tier framework:** [`agents-tier-system`](../agents-tier-system/SKILL.md) · **Layout:** [`agents-first-convention`](../../rules/agents-first-convention.md). + +## Attachment decision tree + +1. **Every turn, non-negotiable?** → Tier 1 (`alwaysApply: true`) — **≤40 lines** STOP + pointers +2. **File-scoped pattern?** → Tier 2 (`globs:`) — thin priming; depth in paired skill +3. **Intent-only workflow?** → Tier 3 or skill-only — no always-on tax (bug diagnosis, doc sweeps, structural queries) +4. **User slash-command only?** → `disable-model-invocation: true` wrapper → model skill(s) + +## Pairing checklist + +| Check | Pass when | +| --------------- | ----------------------------------------------------------------------------------------------------------------------- | +| Priming size | Rule ~10–40L; procedures in skill or sibling | +| Bidirectional | Rule → skill in Reference; skill → rule where paired | +| No duplication | SSOT in skill; rule has STOP rows or pointers only | +| Inventory drift | Tier-1 set discovered via the frontmatter audit in `agents-tier-system` rule — not hardcoded name lists in README/skill | +| Triggers | Per `writing-great-skills` — one branch per intent in `description` | + +## SKILL.md size tiers + +Rules cap at **≤40L**; skills use progressive disclosure (`writing-great-skills` **sprawl**). Line count is a **hygiene signal**, not a hard gate — split for structure, not to hit a number. + +| Lines | Target | +| ---------- | ------------------------------------------------------------------------------------------------ | +| **≤60** | Default for **new** skills | +| **61–120** | OK for one **single-path** workflow with checkable completion criteria | +| **>120** | **Audit** — review for sprawl; disclose to siblings when structure says split | +| **>140** | **Split** unless an explicit bulk reference hub (`FULL-GUIDE.md`, `WORKFLOW.md`, `REFERENCE.md`) | + +**Split when:** branching paths, reference encyclopedia in `SKILL.md`, **premature-completion** risk, or **sediment** — disclose to siblings (`WORKFLOW.md`, `REFERENCE.md`, `LANGUAGE.md`, `PROSE.md`). + +**Don't split when:** every line is ordered steps for one branch; splitting forces a multi-file hop mid-checklist. + +```bash +# Review tail (>120L) — split only when table above says so +find .agents/skills -name SKILL.md -exec sh -c 'n=$(wc -l < "$1"); [ "$n" -gt 120 ] && printf "%3d %s\n" "$n" "$1"' _ {} \; +``` + +## Repo exemplars + +`consumer-surfaces` (Tier 1, always-on), `tracer-bullets` (rule), `docs-governance` (Tier 2 globs + skill + `docs-lifecycle-sweep`), `architecture-priming` ↔ `improve-codebase-architecture` + `audit-pr-architecture`, `codemap` (skill-only), `harden-pr` (SKILL + `LEDGER.md`), `authoring-discipline` (rule + `PROSE.md`), `verify-after-each-step` (slim rule + skill), `agents-tier-system` (rule + skill), `pr-comment-fact-check` (rule + skill). + +## User-only router + +[`ask-agents`](../ask-agents/SKILL.md) — `grill-me`, `grill-with-docs`, `writing-great-skills`, `writing-agents-config`. Wrappers **≤10 lines**. + +## Codemap-specific tradeoffs + +- **Tier-2 attach** — `agents-tier-system` (`agents/**` + `cursor/**`); `docs-governance` (`docs/**`, `.agents/**`); `architecture-priming` when authoring structural refactors. +- **Intent-only skills** — `improve-codebase-architecture`, `domain-modeling`, `docs-lifecycle-sweep`, `diagnose`, `tdd`, `pr-comment-fact-check`, `harden-pr`, `codemap`, `audit-pr-architecture`. No glob (no per-file tax). +- **Ship policy** — `templates/agent-content/**` is served live (CLI/MCP/HTTP); `templates/agents/**` is copied by `codemap agents init`. Consumer surfaces describe behavior only ([`consumer-surfaces`](../../rules/consumer-surfaces.md)). +- **Symlink convention** — source under `.agents/`; `.cursor/rules/<name>.mdc` and `.cursor/skills/<name>` are symlinks only. +- **Cross-skill links** — relative `../skill/SKILL.md` and sibling files resolve reliably in Cursor agents. Relative links inside `.agents/` are an **intentional delta**, not drift. +- **Indexer-first exploration** — skills that explore structure prefer `codemap query` over grep; the `codemap` rule is Tier 1 always-on. + +## Anti-patterns + +- ❌ Fat always-on rule with procedures (slim → skill) +- ❌ README skill inventories that drift (discover via `ls` + frontmatter audit) +- ❌ Maintainer internals on consumer surfaces (`templates/agent-content`, changesets, CLI help) +- ❌ External-monorepo artifact leakage in examples — use `src/`, index/recipe seams, `bun` scripts, `origin/main` + +## Reference + +- Skill authoring SSOT: [`writing-great-skills`](../writing-great-skills/SKILL.md) +- Tiers + audit: [`agents-tier-system`](../agents-tier-system/SKILL.md) +- Docs lifecycle: [`docs-governance`](../docs-governance/SKILL.md) diff --git a/.agents/skills/writing-great-skills/GLOSSARY.md b/.agents/skills/writing-great-skills/GLOSSARY.md new file mode 100644 index 00000000..030e188a --- /dev/null +++ b/.agents/skills/writing-great-skills/GLOSSARY.md @@ -0,0 +1,181 @@ +# Glossary — Building Great Skills + +The domain model for what makes a skill great. A skill exists to wrangle determinism out of a stochastic system; every term below is a lever on that goal. This is the disclosed reference for [`writing-great-skills`](SKILL.md). + +**Bold terms** in any definition are themselves defined in this glossary; find them by their heading. + +## Language + +### Predictability + +The degree to which a skill makes the agent behave the same _way_ on every run — the same process, not the same output (a brainstorming skill should _predictably_ diverge; its tokens vary, its behaviour doesn't). The root virtue every other term serves — cost and maintainability are symptoms of it, not rivals. + +_Avoid_: consistency, reliability, robustness, output-determinism + +### Model-Invoked + +A skill that keeps its **description** field, so the agent can see it and fire it autonomously — and the human can still type its name, so model-invocation always _includes_ user reach. There is no model-only state: a description only ever _adds_ agent discovery, never removes the human's. Pays a permanent **context load** on every turn in exchange for that discoverability. Reachable by other skills, because the description that makes it agent-discoverable makes it invocable. A model-invoked skill whose content is all **reference** is also one home for shared reference: another skill can invoke it, so reference needed by several skills lives in one place. Pick model-invocation only when the agent must reach the skill on its own; if it never fires except by hand, drop the description and pay no context load. + +_Avoid_: ability, tool, capability + +### User-Invoked + +A skill with its **description** stripped — invisible to the agent and reachable only by the human typing its name (user-_only_, where **model-invoked** is user-_and-agent_). Trades agent-discoverability for zero **context load**. Because it has no description, nothing but the human can reach it: no other skill can fire it. + +_Avoid_: procedure, workflow, command + +### Description + +The skill's machine-readable trigger, and the one **context pointer** a **model-invoked** skill is forced to keep loaded at all times. Its mere presence _is_ the invocation axis: keep it and the skill is model-invoked (and reachable by other skills); delete it and the skill is **user-invoked**, reachable only by the human. The source of a model-invoked skill's **context load**. + +_Avoid_: frontmatter, summary + +### Context Pointer + +A reference held in the agent's context that names some out-of-context material and encodes the condition for reaching it. The **description** is the top-level context pointer (context window → skill); pointers to disclosed files are the same object one level down. Its wording, not the target, decides _when_ the agent reaches — and _how reliably_. A must-have target behind a weakly worded pointer is a variance bug: fix the wording first, and inline the material only if sharpening fails. + +_Avoid_: link, reference, import + +### Context Load + +The cost a **model-invoked** skill imposes on the agent's context window — its **description**, always loaded, spending both tokens and attention. What **user-invoked** skills escape by having no description, and the brake on splitting into more model-invoked skills. + +_Avoid_: token cost, context bloat + +### Cognitive Load + +The cost a **user-invoked** skill imposes on the human — what they must hold in their head: which skills exist and when to reach for each (the human is the index). What **model-invocation** removes by being agent-discoverable, and the brake on splitting into more user-invoked skills. Not a cost to minimise: it is the price of human agency, the reason some skills stay user-invoked. Spend it where human judgement matters; remove it where it does not. + +_Avoid_: human index, burden, overhead + +### Granularity + +How finely you divide skills. Finer division spends one of the two loads: more **model-invoked** skills spend **context load** (more descriptions crowding the window and competing for attention); more **user-invoked** skills spend **cognitive load** (more for the human to remember and reach for). Two cuts guide the division. By **invocation**, split off a model-invoked skill where you have a distinct **leading word** to trigger it — a trigger word you actually use in your prompts. By **sequence**, split a run of **steps** where a step's **post-completion steps** need hiding, since isolating it in its own context clears what follows. Beware the reverse: merging sequences exposes each step's post-completion steps to what follows, inviting premature completion. + +_Avoid_: chunking, modularity + +### Router Skill + +A **user-invoked** skill whose job is to point at your other user-invoked skills — naming each and when to reach for it — so the human has one skill to remember instead of many. It can only hint, never fire them: user-invoked skills have no **description**, so nothing but the human can reach them. The cure for **cognitive load** when user-invoked skills multiply. + +_Avoid_: dispatcher, menu, registry, index, router procedure + +### Information Hierarchy + +A skill's content ranked by how immediately the agent needs it — a single ladder, produced by two cuts: in-file or behind a pointer, and step or reference. The rungs: + +- **Steps** — in-file, primary +- **Reference**, in-file — secondary +- **Reference**, disclosed — behind a **context pointer** + +A skill with no **steps** uses just the bottom two rungs — often a legitimately flat peer-set (e.g. every rule of a review on one rung), which is a fine arrangement, not a smell. The hierarchy is independent of invocation: a skill can be model- or user-invoked whether it is all steps, all reference, or both. When a skill has steps, in-file reference that should be disclosed buries them and turns attending to them into a coin-flip — a variance lever, not just a legibility one. Keep the top of the ladder legible; push down it whatever you can. + +_Avoid_: structure, organization, layout + +### Co-location + +Keeping the material an agent needs at once in one place — a concept's definition, rules, and caveats under a single heading, not scattered across the file — so reading one part brings its neighbours with it. The within-file companion to the **Information Hierarchy**: the hierarchy ranks _how far down_ a piece sits; co-location decides _what sits beside it_ once there. There is no formula for the right format of a body of **reference**; the test is that a skill should read like documentation written for the agent, and grouped material reads that way where scattered material does not. Distinct from **Duplication**: that repeats one meaning in two places, where scattering fragments a single meaning across many. + +_Avoid_: grouping, clustering, cohesion + +### Branch + +A distinct way a skill can be invoked — a case the skill handles — so different runs take different paths through it. A skill with many steps may carry many branches; a linear one has none. + +_Avoid_: path, case, fork + +### Progressive Disclosure + +Moving **reference** down the ladder — out of SKILL.md and behind a **context pointer** — so the top stays legible. Not primarily a token optimisation; it is how the **information hierarchy** is protected. Licensed by **branching**: disclose what only some branches need, inline what every path needs, and if a pointer fires unreliably on must-have material, sharpen its wording, and pull it back inline only if that fails. + +_Avoid_: lazy loading, chunking + +### Steps + +The ordered actions the agent performs — when a skill has them, the primary tier of its content, and the part that earns its place in SKILL.md. Not every skill has steps: a skill can be all steps (`tdd`), all **reference** (a review), or both, independent of invocation. Every step ends on a **completion criterion**, clear or vague. + +_Avoid_: workflow, instructions, choreography + +### Completion Criterion + +The condition that tells the agent a unit of work is done — the target it judges against. Two properties make it a lever, not just a quality. Its **clarity** (can the agent tell done from not-done?) resists **premature completion** — a vague bound ("understanding reached") lets the agent declare done and slip to the next step; this axis needs _steps_ to bite, since premature completion is a between-steps failure. Its **demand** (how much it requires) sets **legwork** — "every modified model accounted for" forces thorough work where "produce a change list" does not — and this axis is _not_ step-bound: it can bind a body of flat reference too, which is how a skill with no steps still carries an exhaustiveness bar ("every rule applied"). The strongest criteria are both checkable and exhaustive. + +_Avoid_: done condition, exit condition, stopping rule + +### Post-Completion Steps + +The **steps** that follow the current step. Visible, they pull the agent forward into **premature completion** — the more it sees, the stronger the tug; the defence is to hide them by splitting the sequence of steps into two. + +_Avoid_: horizon, fog of war, lookahead + +### Legwork + +The work an agent does behind the scenes within a single step — reading files, exploring the codebase, making changes, digging up what it needs rather than offloading to the user. It lives below the step structure: never written as its own step, latent in the wording, controlled by the agent rather than the skill. The within-step counterpart to **post-completion steps**' across-step pull. Raised by a **leading word** (_comprehensive_, _thorough_) or a **completion criterion** that demands the work be exhaustive — including the demand axis applied to flat reference, which is what drives a skill of flat reference to cover all its rungs. Goes thin either when that demand is missing or when **premature completion** cuts the step short. + +_Avoid_: scope, effort, diligence, coverage + +### Reference + +Material the agent refers to on demand — definitions, facts, parameters, examples, conditional instructions. When a skill has **steps** it is secondary to them; when a skill has none it is the entire content; or it lives outside any skill entirely — see **External Reference**. Reached via **context pointers**, and the prime candidate for **progressive disclosure**. + +_Avoid_: supporting material, docs, background + +### External Reference + +**Reference** that lives outside the skill system — a plain file, no **description**, no **steps**, not invocable — that any skill can point at. The home for shared reference that needn't fire on its own, and the only shared home two **user-invoked** skills can use, since neither has a description and so neither can fire the other. + +_Avoid_: doc, resource, knowledge base + +### Leading Word + +A compact concept — also called a _Leitwort_ — already living in the model's pretraining, that the agent thinks with while running the skill. It encodes a behavioural principle in the fewest possible tokens by invoking priors the model already holds (e.g. _lesson_, _tracer bullets_, _fog of war_). Repeated as a token, never as a sentence, it accumulates a distributed definition across the skill and anchors a whole region of behaviour. Coining your own works if you define it clearly, but a made-up word recruits no priors — you pay in definition tokens what a pretrained word gives free. Reach for an existing word first. + +A leading word serves **predictability** twice. In the body it anchors **execution** — the agent reaches for the same behaviour every time the concept appears, and inside flat reference it focuses attention on a class of thing to look for, recruiting the right checks each run. In the **description** it anchors **invocation** — and not only within the skill: when the same word lives in your prompts, your docs, and your codebase, the agent links that shared language to the skill and fires it more reliably. Word a description with the leading words you actually use when you want the skill. + +_Avoid_: keyword, term, motif + +### Single Source of Truth + +The desired state where each meaning lives in exactly one authoritative place, so a change to the skill's behaviour is a change in one place. **Duplication** is its violation. + +_Avoid_: home, canonical location + +### Relevance + +Whether a line still bears on what the skill does — the lens for what to keep. A line loses relevance either by never bearing on the task (mere exposition, or a **branch** that should be disclosed) or by going stale: drifting out of date as the behaviour or world it describes changes. Shorter skills are easier to keep relevant, because each line is cheaper to check. Distinct from **no-op**: relevance asks whether a line bears on the task, not whether it changes behaviour. + +_Avoid_: load-bearing, staleness, freshness + +## Failure Modes + +### Premature Completion + +Ending the current step before it is genuinely done, because the agent's attention slips to being done rather than to the work. A between-steps failure: it needs **steps** to occur — a skill with no steps that quits early isn't premature completion but thin **legwork** under an unmet demand. A tug-of-war between two forces: visible **post-completion steps** (the pull forward) and the **completion criterion**'s clarity (the resistance — a sharp, checkable bar holds; a vague one gives way). Fuzziness is the necessary condition: a sharp bound resists the pull no matter how many later steps are visible, so a step that never rushes needs no defending. Two levers hold a step that does, but reach for them in order: **sharpen the bound first** — it is local and cheap. Only when the criterion is irreducibly fuzzy _and_ you actually observe the rush do you **hide the later steps** — and hiding only works across a real context boundary (a user-invoked hand-off or a subagent dispatch; an inline model-invoked call leaves the later steps in context and clears nothing). One cause of thin legwork, but distinct from it: legwork can be thin even when a step runs to full completion. + +_Avoid_: premature closure, the rush, rushing, shortcutting + +### Duplication + +The same meaning given more than one **single source of truth**. It costs maintenance (change one place, you must change the others), costs tokens, and inflates prominence — repeating a meaning weights it on the ladder past its real rank. The accidental inverse of a **leading word**, which raises attention on purpose by repeating a token, never the meaning. + +_Avoid_: repetition, redundancy + +### Sediment + +Layers of old content that settle in a skill and are never cleared, because adding feels safe and removing feels risky — so stale and irrelevant lines accumulate and you must core down through them to find what is still live. The default fate of any skill without a pruning discipline; the slow erosion of **relevance**, as opposed to **duplication**'s repeated meaning. + +_Avoid_: accretion, bloat, cruft, rot + +### Sprawl + +A skill that is simply too long — too many lines in SKILL.md — independent of whether they are stale or repeated. Even an all-live, all-unique skill can sprawl. It costs readability (the agent wades through more before it can act, and attention thins across the excess), maintainability (every extra line is one more to keep **relevant**), and tokens. The cure is the **information hierarchy**: push **reference** down behind **context pointers**, and split by **branch** or sequence so each path carries only what it needs. Distinct from **sediment** (length from stale accumulation) and **duplication** (length from repeated meaning) — sprawl is length itself, whatever its cause. + +_Avoid_: bloat, length, size, verbosity + +### No-Op + +An instruction that changes nothing because the model already does it by default — you pay load to tell the agent what it would do anyway. The test: does a line change behaviour versus the default? A line can be perfectly **relevant** and still be a no-op. The same priors that make a **leading word** free make a no-op worthless. + +A leading word is a _technique_; No-Op is a _verdict_ on a line — and they cross. A leading word too weak to beat the default is a no-op (_be thorough_ when the agent is already thorough-ish), and the fix is a stronger word that passes the verdict (_relentless_), not a different technique. So the No-Op test — does it change behaviour versus the default? — is also how you grade whether a leading word is earning its repetitions. This is model-relative, not reader-relative: two people disagreeing over whether a line is a no-op disagree about the default, and settle it by running the skill, not by debate. + +_Avoid_: redundant instruction, restating the obvious, belaboring diff --git a/.agents/skills/writing-great-skills/SKILL.md b/.agents/skills/writing-great-skills/SKILL.md new file mode 100644 index 00000000..184c6339 --- /dev/null +++ b/.agents/skills/writing-great-skills/SKILL.md @@ -0,0 +1,82 @@ +--- +name: writing-great-skills +description: Reference for writing and editing skills well — the vocabulary and principles that make a skill predictable. +disable-model-invocation: true +--- + +A skill exists to wrangle determinism out of a stochastic system. **Predictability** — the agent taking the same _process_ every run, not producing the same output — is the root virtue; every lever below serves it. + +**Bold terms** are defined in [`GLOSSARY.md`](GLOSSARY.md); look them up there for the full meaning. + +## Invocation + +Two choices, trading different costs: + +- A **model-invoked** skill keeps a **description**, so the agent can fire it autonomously _and_ other skills can reach it (you can still type its name too). It contributes to **context load** — the description sits in the window every turn. Mechanics: omit `disable-model-invocation`, and write a model-facing description with rich trigger phrasing ("Use when the user wants…, mentions…"). +- A **user-invoked** skill strips the description from the agent's reach: only you, typing its name, can invoke it — and no other skill can. Zero context load, but it spends **cognitive load**: _you_ are the index that must remember it exists. Mechanics: set `disable-model-invocation: true`; the `description` becomes human-facing — a one-line summary, trigger lists stripped. + +Pick model-invocation only when the agent must reach the skill on its own, or another skill must. If it only ever fires by hand, make it user-invoked and pay no context load. + +When user-invoked skills multiply past what you can remember, that piled-up cognitive load is cured by a **router skill**: one user-invoked skill that names the others and when to reach for each. + +## Writing the description + +A model-invoked **description** does two jobs — state what the skill is, and list the **branches** that should trigger it. Every word increases **context load**, so a description earns even harder pruning than the body: + +- **Front-load the skill's leading word** — the description is where it does its invocation work. +- **One trigger per branch.** Synonyms that rename a single branch are **duplication** — "build features using TDD … asks for test-first development" is one branch written twice. Collapse them; keep only genuinely distinct branches. +- **Cut identity that's already in the body.** Keep the description to triggers, plus any "when another skill needs…" reach clause. + +## Information hierarchy + +A skill is built from two content types — **steps** and **reference** — that mix freely: a skill can be all steps, all reference, or both. The core decision is which to use and where each sits on the **information hierarchy**, a ladder ranked by how immediately the agent needs the material: + +1. **In-skill step** — an ordered action in `SKILL.md`, the primary tier: what the agent does, in order. Each step ends on a **completion criterion**, the condition that tells the agent the work is done. Make it _checkable_ (can the agent tell done from not-done?) and, where it matters, _exhaustive_ ("every modified model accounted for", not "produce a change list") — a vague criterion invites **premature completion**. +2. **In-skill reference** — a definition, rule, or fact in `SKILL.md`, consulted on demand. Often a legitimately flat peer-set (every rule of a review on one rung) — a fine arrangement, not a smell. _This skill is all reference._ +3. **External reference** — reference pushed out of `SKILL.md` into a separate file, reached by a **context pointer**, loaded only when the pointer fires. (Spans _disclosed_ reference — a sibling file like `GLOSSARY.md`, still part of the skill — through fully **external reference** that lives outside the skill system and any skill can point at.) + +A demanding completion criterion drives thorough **legwork** — the digging the agent does within the work — whether the skill has steps or not, since "every rule applied" binds flat reference just as "every step done" binds a sequence. + +Push too little down and the top bloats; push too much and you hide material the agent actually needs. That tension is the whole decision. + +**Progressive disclosure** is the move down the ladder — out of `SKILL.md` into a linked file — so the top stays legible. Mechanics: a linked `.md` file in the skill folder, named for what it holds (this skill discloses its full definitions to `GLOSSARY.md`). Some skills are used in more than one way, and each distinct way is a **branch** — different runs taking different paths through the skill. Branching is the cleanest disclosure test: inline what every branch needs, and push behind a pointer what only some branches reach. A **context pointer**'s _wording_, not its target, decides when and how reliably the agent reaches the material. + +Where the ladder decides _how far down_ a piece sits, **co-location** decides _what sits beside it_ once there: keep a concept's definition, rules, and caveats under one heading rather than scattered, so reading one part brings its neighbours with it. + +## When to split + +**Granularity** is how finely you divide skills, and each cut spends one of the two loads, so split only when the cut earns it. Two cuts: + +- **By invocation** — split off a **model-invoked** skill when you have a distinct **leading word** that should trigger it on its own, or another skill must reach it. You pay **context load** for the new always-loaded **description**, so that independent reach has to be worth it. +- **By sequence** — split a run of **steps** when the steps still ahead (a step's **post-completion steps**) tempt the agent to rush the one in front of it (**premature completion**). Keeping them out of view encourages the agent to do more **legwork** on the current task. + +## Pruning + +Keep each meaning in a **single source of truth**: one authoritative place, so changing the behaviour is a one-place edit. + +Check every line for **relevance**: does it still bear on what the skill does? + +Then hunt **no-ops** sentence by sentence, not just line by line: run the no-op test on each sentence in isolation, and when one fails, delete the whole sentence rather than trim words from it. Be aggressive — most prose that fails should go, not be rewritten. + +## Leading words + +A **leading word** is a compact concept already living in the model's pretraining that the agent thinks with while running the skill (e.g. _lesson_, _tracer bullets_, _fog of war_). Repeated throughout the text (though not necessarily - a strong leading word might only be needed once), it accumulates a distributed definition and anchors a whole region of behaviour in the fewest tokens, by recruiting priors the model already holds. + +It serves predictability twice. In the body it anchors _execution_: the agent reaches for the same behaviour every time the word appears. In the description it anchors _invocation_: when the same word lives in your prompts, docs, and code, the agent links that shared language to the skill and fires it more reliably. + +Hunt for opportunities to refactor skills to use leading words. A triad spelled out at three sites (**duplication**), a description spending a sentence to gesture at one idea — each is a passage begging to **collapse** into a single token. Examples include: + +- "fast, deterministic, low-overhead" -> _tight_ — one quality restated across a phase — into a single pretrained word (a _tight_ loop). +- "a loop you believe in" -> _red_ — converts a fuzzy gate into a binary observable state (the loop goes _red_ on the bug, or it doesn't). + +You win twice over: fewer tokens, _and_ a sharper hook for the agent to hang its thinking on. Assume every skill is carrying restatements that leading words retire — go find them. + +## Failure modes + +Use these to diagnose issues the user may be having with the skill. + +- **Premature completion** — ending a step before it's genuinely done, attention slipping to _being done_. Defence, in order: sharpen the completion criterion first (cheap, local); only if it is irreducibly fuzzy _and_ you observe the rush, hide the post-completion steps by splitting (the sequence cut). +- **Duplication** — the same meaning in more than one place. Costs maintenance and tokens, and inflates a meaning's prominence on the ladder past its real rank. +- **Sediment** — stale layers that settle because adding feels safe and removing feels risky. The default fate of any skill without a pruning discipline. +- **Sprawl** — a skill simply too long, even when every line is live and unique. Hurts readability and maintainability and wastes tokens. The cure is the ladder: disclose **reference** behind pointers, and split by **branch** or sequence so each path carries only what it needs. +- **No-op** — a line the model already obeys by default, so you pay load to say nothing. The test: does it change behaviour versus the default? A weak leading word (_be thorough_ when the agent is already thorough-ish) is a no-op; the fix is a stronger word (_relentless_), not a different technique. diff --git a/.changeset/README.md b/.changeset/README.md index 73ed434e..d6f1a925 100644 --- a/.changeset/README.md +++ b/.changeset/README.md @@ -9,4 +9,4 @@ We have a quick list of common questions to get you started engaging with this p --- -**This repo:** How versioning, **`NPM_TOKEN`**, **`bun run version`** (includes **oxfmt** after **`changeset version`**), and the GitHub workflow fit together — see [docs/packaging.md § Releases](../docs/packaging.md#releases) (single place; don’t duplicate here). +**This repo:** How versioning, **`bun run version`** (includes **oxfmt** after **`changeset version`**), and the GitHub Release workflow fit together — see [docs/packaging.md § Releases](../docs/packaging.md#releases) (single place; don’t duplicate here). diff --git a/.cursor/rules/architecture-priming.mdc b/.cursor/rules/architecture-priming.mdc new file mode 120000 index 00000000..426fff7d --- /dev/null +++ b/.cursor/rules/architecture-priming.mdc @@ -0,0 +1 @@ +../../.agents/rules/architecture-priming.md \ No newline at end of file diff --git a/.cursor/rules/authoring-discipline.mdc b/.cursor/rules/authoring-discipline.mdc new file mode 120000 index 00000000..32ae4fb4 --- /dev/null +++ b/.cursor/rules/authoring-discipline.mdc @@ -0,0 +1 @@ +../../.agents/rules/authoring-discipline.md \ No newline at end of file diff --git a/.cursor/rules/concise-comments.mdc b/.cursor/rules/concise-comments.mdc deleted file mode 120000 index e20c0d2d..00000000 --- a/.cursor/rules/concise-comments.mdc +++ /dev/null @@ -1 +0,0 @@ -../../.agents/rules/concise-comments.md \ No newline at end of file diff --git a/.cursor/rules/preserve-comments.mdc b/.cursor/rules/preserve-comments.mdc deleted file mode 120000 index dc24bb4c..00000000 --- a/.cursor/rules/preserve-comments.mdc +++ /dev/null @@ -1 +0,0 @@ -../../.agents/rules/preserve-comments.md \ No newline at end of file diff --git a/.cursor/skills/agents-tier-system b/.cursor/skills/agents-tier-system new file mode 120000 index 00000000..d167cc7a --- /dev/null +++ b/.cursor/skills/agents-tier-system @@ -0,0 +1 @@ +../../.agents/skills/agents-tier-system \ No newline at end of file diff --git a/.cursor/skills/ask-agents b/.cursor/skills/ask-agents new file mode 120000 index 00000000..5d6e99a8 --- /dev/null +++ b/.cursor/skills/ask-agents @@ -0,0 +1 @@ +../../.agents/skills/ask-agents \ No newline at end of file diff --git a/.cursor/skills/authoring-discipline b/.cursor/skills/authoring-discipline new file mode 120000 index 00000000..8a5a1953 --- /dev/null +++ b/.cursor/skills/authoring-discipline @@ -0,0 +1 @@ +../../.agents/skills/authoring-discipline \ No newline at end of file diff --git a/.cursor/skills/domain-modeling b/.cursor/skills/domain-modeling new file mode 120000 index 00000000..e672a60c --- /dev/null +++ b/.cursor/skills/domain-modeling @@ -0,0 +1 @@ +../../.agents/skills/domain-modeling \ No newline at end of file diff --git a/.cursor/skills/grill-with-docs b/.cursor/skills/grill-with-docs new file mode 120000 index 00000000..f6cbb9cd --- /dev/null +++ b/.cursor/skills/grill-with-docs @@ -0,0 +1 @@ +../../.agents/skills/grill-with-docs \ No newline at end of file diff --git a/.cursor/skills/grilling b/.cursor/skills/grilling new file mode 120000 index 00000000..e7124527 --- /dev/null +++ b/.cursor/skills/grilling @@ -0,0 +1 @@ +../../.agents/skills/grilling \ No newline at end of file diff --git a/.cursor/skills/tdd b/.cursor/skills/tdd new file mode 120000 index 00000000..2178bb8a --- /dev/null +++ b/.cursor/skills/tdd @@ -0,0 +1 @@ +../../.agents/skills/tdd \ No newline at end of file diff --git a/.cursor/skills/tracer-bullets b/.cursor/skills/tracer-bullets new file mode 120000 index 00000000..11a5f2d7 --- /dev/null +++ b/.cursor/skills/tracer-bullets @@ -0,0 +1 @@ +../../.agents/skills/tracer-bullets \ No newline at end of file diff --git a/.cursor/skills/verify-after-each-step b/.cursor/skills/verify-after-each-step new file mode 120000 index 00000000..0b0998c6 --- /dev/null +++ b/.cursor/skills/verify-after-each-step @@ -0,0 +1 @@ +../../.agents/skills/verify-after-each-step \ No newline at end of file diff --git a/.cursor/skills/writing-agents-config b/.cursor/skills/writing-agents-config new file mode 120000 index 00000000..60448b7c --- /dev/null +++ b/.cursor/skills/writing-agents-config @@ -0,0 +1 @@ +../../.agents/skills/writing-agents-config \ No newline at end of file diff --git a/.cursor/skills/writing-great-skills b/.cursor/skills/writing-great-skills new file mode 120000 index 00000000..07320a2f --- /dev/null +++ b/.cursor/skills/writing-great-skills @@ -0,0 +1 @@ +../../.agents/skills/writing-great-skills \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..4f4f82be --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,22 @@ +version: 2 + +updates: + # npm — group devDep bumps into one weekly PR (avoids one-PR-per-dep noise). + # Peer ranges are the public surface — not bumped. + - package-ecosystem: npm + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 10 + groups: + dev-deps: + dependency-type: development + + # GitHub Actions — bumps the SHA-pinned actions' commits (and the trailing + # `# vN` comment), so a pinned major stays tamper-resistant without manual + # tracking. + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly + open-pull-requests-limit: 10 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 18f688fd..9d66f36e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,9 @@ on: branches: - main +permissions: + contents: read + jobs: skip-ci: name: Gate (skip full CI for version PRs?) @@ -39,7 +42,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + persist-credentials: false - name: Setup uses: ./.github/actions/setup @@ -54,7 +59,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + persist-credentials: false - name: Setup uses: ./.github/actions/setup @@ -69,7 +76,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + persist-credentials: false - name: Setup uses: ./.github/actions/setup @@ -84,7 +93,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + persist-credentials: false - name: Setup uses: ./.github/actions/setup @@ -108,7 +119,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + persist-credentials: false - name: Setup uses: ./.github/actions/setup @@ -140,6 +153,26 @@ jobs: timeout 45 node dist/index.mjs --full node dist/index.mjs query "SELECT COUNT(*) AS files FROM files" + check-pack: + name: 📦 Pack validation + needs: skip-ci + if: needs['skip-ci'].outputs.skip != 'true' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + persist-credentials: false + + - name: Setup + uses: ./.github/actions/setup + + - name: Build + run: bun run build + + - name: Run pack validation + run: bun run check:pack + benchmark: name: 📊 Benchmark (fixture) needs: skip-ci @@ -147,7 +180,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + persist-credentials: false - name: Setup uses: ./.github/actions/setup @@ -159,22 +194,31 @@ jobs: bun run benchmark audit: - # Non-blocking — visibility into transitive-dep CVEs without gating PRs. - # Promote to a hard gate once the team agrees on a vulnerability budget. - name: 🛡 Audit (non-blocking) + # `bun audit` exits 0 regardless of severity — the scan below blocks on high/critical. + # Transitive-dep CVE visibility; advisory-API outage doesn't block. + name: 🛡 Audit needs: skip-ci if: needs['skip-ci'].outputs.skip != 'true' runs-on: ubuntu-latest - continue-on-error: true steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + persist-credentials: false - name: Setup uses: ./.github/actions/setup - - name: bun audit - run: bun audit + - name: bun audit (block on high/critical) + run: | + set +e + # bun emits ANSI color even when piped — strip it or the severity grep misses it. + NO_COLOR=1 bun audit 2>&1 | sed -E 's/\x1b\[[0-9;]*m//g' > /tmp/bun-audit.log + cat /tmp/bun-audit.log + if grep -E '(^|[[:space:]])(high|critical):[[:space:]]' /tmp/bun-audit.log; then + echo "::error::high or critical vulnerabilities found — blocking" + exit 1 + fi action-smoke: # Dogfood Slice 4 of plan PR #73: invoke `uses: ./` from this very repo @@ -194,7 +238,9 @@ jobs: continue-on-error: true steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 + with: + persist-credentials: false - name: Run the local-path action uses: ./ @@ -207,7 +253,18 @@ jobs: ci-complete: name: CI complete - needs: [skip-ci, format, lint, typecheck, test, build, benchmark] + needs: + [ + skip-ci, + format, + lint, + typecheck, + test, + build, + check-pack, + audit, + benchmark, + ] if: always() runs-on: ubuntu-latest steps: @@ -219,6 +276,8 @@ jobs: needs.typecheck.result != 'success' || needs.test.result != 'success' || needs.build.result != 'success' || + needs['check-pack'].result != 'success' || + needs.audit.result != 'success' || needs.benchmark.result != 'success' ) run: exit 1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fa4afee7..318180dd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,5 +1,6 @@ # [Changesets](https://github.com/changesets/changesets): open a "Version packages" PR when -# `.changeset/*.md` files land on `main`, then publish to npm when that PR merges (requires `NPM_TOKEN`). +# `.changeset/*.md` files land on `main`, then publish to npm when that PR merges via npm +# trusted publishing (GitHub OIDC — no NPM_TOKEN; provenance auto-generated). name: Release on: @@ -12,38 +13,41 @@ concurrency: ${{ github.workflow }}-${{ github.ref }} permissions: contents: write pull-requests: write + id-token: write jobs: release: name: Release runs-on: ubuntu-latest + environment: release steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: fetch-depth: 0 - - name: Socket Firewall - uses: socketdev/action@ba6de6cc0565af1f42295590380973573297e31f - with: - mode: firewall-free + - name: Setup Bun and install + uses: ./.github/actions/setup - - name: Setup Bun - uses: oven-sh/setup-bun@v2 + # npm trusted publishing (OIDC) needs npm ≥ 11.5.1 + Node ≥ 22.14 + # (docs.npmjs.com/trusted-publishers). setup-bun leaves the runner's + # npm 10.x in PATH → `npm publish` can't detect OIDC → ENEEDAUTH. + # Node 24 ships npm 11.x; npm then auto-authenticates via OIDC (no token). + - name: Setup Node + npm for trusted publishing + uses: actions/setup-node@v6 with: - bun-version: latest - - - name: Install dependencies - run: sfw bun install --frozen-lockfile + node-version: "24" + registry-url: "https://registry.npmjs.org" # Opens/updates the Version PR when `.changeset/*.md` exist. When there are none, the action # can still run `publish` (see changesets/action) so a just-merged Version PR can ship. # `changeset publish` should exit 0 when there is nothing new to publish. If this job fails, - # read the step log: common causes are missing/invalid NPM_TOKEN, registry/network errors, or - # a real publish failure — not assumed from the runner alone. + # read the step log: common causes are OIDC/trusted-publishing misconfig (`id-token: write`, + # the `release` environment, or the npm trusted-publisher binding), registry/network errors, + # or a real publish failure — not assumed from the runner alone. - name: Create Release Pull Request or Publish to npm id: changesets - uses: changesets/action@v1 + uses: changesets/action@a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d # v1 with: # Runs `changeset version` then oxfmt on CHANGELOG.md so `format:check` passes (see docs/packaging.md). version: bun run version @@ -53,4 +57,3 @@ jobs: createGithubReleases: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..efee97cd --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,21 @@ +# Agent instructions + +Canonical read order: [`.agents/rules/agents-first-convention.md`](.agents/rules/agents-first-convention.md) · [`.agents/rules/agents-tier-system.md`](.agents/rules/agents-tier-system.md) (START HERE). + +| Topic | Link | +| -------------------- | ---------------------------------------------------------------------------------------------------- | +| File conventions | [`.agents/rules/agents-first-convention.md`](.agents/rules/agents-first-convention.md) | +| Tier system | [`.agents/rules/agents-tier-system.md`](.agents/rules/agents-tier-system.md) | +| Tracer bullets | [`.agents/rules/tracer-bullets.md`](.agents/rules/tracer-bullets.md) | +| Pre-commit hooks | [`.agents/rules/no-bypass-hooks.md`](.agents/rules/no-bypass-hooks.md) | +| Verify each step | [`.agents/rules/verify-after-each-step.md`](.agents/rules/verify-after-each-step.md) | +| Authoring discipline | [`.agents/rules/authoring-discipline.md`](.agents/rules/authoring-discipline.md) | +| Architecture priming | [`.agents/rules/architecture-priming.md`](.agents/rules/architecture-priming.md) | +| Consumer surfaces | [`.agents/rules/consumer-surfaces.md`](.agents/rules/consumer-surfaces.md) | +| Docs governance | [`.agents/rules/docs-governance.md`](.agents/rules/docs-governance.md) | +| PR comments | [`.agents/rules/pr-comment-fact-check.md`](.agents/rules/pr-comment-fact-check.md) | +| Plan-PR inspiration | [`.agents/rules/plan-pr-inspiration-discipline.md`](.agents/rules/plan-pr-inspiration-discipline.md) | + +Intent (not always-on): `agents-tier-system`, `ask-agents`, `audit-pr-architecture`, `authoring-discipline`, `codemap`, `diagnose`, `docs-governance`, `docs-lifecycle-sweep`, `domain-modeling`, `grill-me`, `grilling`, `grill-with-docs`, `harden-pr`, `improve-codebase-architecture`, `pr-comment-fact-check`, `tdd`, `tracer-bullets`, `verify-after-each-step`, `write-a-skill`, `writing-agents-config`, `writing-great-skills`. + +Human Day-1: [README](README.md) Getting Started · [`.github/CONTRIBUTING.md`](.github/CONTRIBUTING.md). diff --git a/bun.lock b/bun.lock index 2e66411d..7c514473 100644 --- a/bun.lock +++ b/bun.lock @@ -17,17 +17,19 @@ "zod": "4.4.3", }, "devDependencies": { + "@arethetypeswrong/cli": "0.18.4", "@changesets/changelog-github": "0.7.0", "@changesets/cli": "2.31.0", "@types/better-sqlite3": "7.6.13", "@types/bun": "1.3.14", - "@types/node": "25.9.3", - "@typescript/native-preview": "7.0.0-dev.20260616.1", + "@types/node": "26.1.0", + "@typescript/native-preview": "7.0.0-dev.20260706.1", "husky": "9.1.7", "lint-staged": "17.0.7", - "oxfmt": "0.55.0", - "oxlint": "1.70.0", - "tsdown": "0.22.2", + "oxfmt": "0.57.0", + "oxlint": "1.72.0", + "publint": "0.3.21", + "tsdown": "0.22.3", "typescript": "6.0.3", "unrun": "0.3.1", }, @@ -40,17 +42,25 @@ "zod": "4.4.3", }, "packages": { - "@babel/generator": ["@babel/generator@8.0.0-rc.6", "", { "dependencies": { "@babel/parser": "^8.0.0-rc.6", "@babel/types": "^8.0.0-rc.6", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "@types/jsesc": "^2.5.0", "jsesc": "^3.0.2" } }, "sha512-6mIzgVK8DgEzvIapoQwhXTMnnkuE4STQmVv9H03i/tZ2ml8oev3TRvZJgTenK2Bsq0YWNtzOrFdTyNzCMFtjJQ=="], + "@andrewbranch/untar.js": ["@andrewbranch/untar.js@1.0.3", "", {}, "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw=="], - "@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.6", "", {}, "sha512-BCkFy+zN6kXQed3YOT7aJl93NfDSzQc3pBfsvTVPs9gU9X3V0aefEF5kwBT0E+mDWH9QgKaZstYUQN9VdQZT4g=="], + "@arethetypeswrong/cli": ["@arethetypeswrong/cli@0.18.4", "", { "dependencies": { "@arethetypeswrong/core": "0.18.4", "chalk": "^4.1.2", "cli-table3": "^0.6.3", "commander": "^10.0.1", "marked": "^9.1.2", "marked-terminal": "^7.1.0", "semver": "^7.5.4" }, "bin": { "attw": "./dist/index.js" } }, "sha512-kNWo6LTzGAuLYPpJ7Sgo63whSUeeSuKMlYx6IBgzs4ONEG807gW4hSSENvpeCHzO2H2wIzG5EFl0OKBbqGBAyA=="], - "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@8.0.0-rc.6", "", {}, "sha512-nVJ+1JcCgntv8d78rRo++o2wuODT0Irknx2BF8Np4Ft2CRgjLqIs4qzSZ8b66yGbBdMWGmZBO9WEZv1hhNiSpg=="], + "@arethetypeswrong/core": ["@arethetypeswrong/core@0.18.4", "", { "dependencies": { "@andrewbranch/untar.js": "^1.0.3", "@loaderkit/resolve": "^1.0.2", "cjs-module-lexer": "^1.2.3", "fflate": "^0.8.3", "lru-cache": "^11.0.1", "semver": "^7.5.4", "typescript": "5.6.1-rc", "validate-npm-package-name": "^5.0.0" } }, "sha512-M5F0ePyN6h2Z6XxRiyIPqjGbltotXLjR0CKA0uKspsDu0QmgTNYvRb4RSQPMUs2ZXZHCCYpbaZbFbYOXLxCjUA=="], - "@babel/parser": ["@babel/parser@8.0.0-rc.6", "", { "dependencies": { "@babel/types": "^8.0.0-rc.6" }, "bin": "./bin/babel-parser.js" }, "sha512-rOS8IpdO7mQELkTPlCsTgPejO0bFuZdEDCGQJouYbYf9e1FLTym7Fei2pEjq8q7MWbX0ravcd7QQYKs1TxOuog=="], + "@babel/generator": ["@babel/generator@8.0.0", "", { "dependencies": { "@babel/parser": "^8.0.0", "@babel/types": "^8.0.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "@types/jsesc": "^2.5.0", "jsesc": "^3.0.2" } }, "sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0", "", {}, "sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@8.0.2", "", {}, "sha512-9Fr9QeyCAyi1BR1jKZ6uYQ24EIhQUx5ReHfQU7drOE+TPOb+w11/dsqLkMOT2U29OdCT71XajrOT8xDc1C7orA=="], + + "@babel/parser": ["@babel/parser@8.0.0", "", { "dependencies": { "@babel/types": "^8.0.0" }, "bin": "./bin/babel-parser.js" }, "sha512-aLxAE+imI9bCcyaPrUDjBv3uSkWieifjLe0kuFOZF0zli0L6GCsTmsePnTr55adbIAgYz2zhN1vnFimCBUYcRQ=="], "@babel/runtime": ["@babel/runtime@7.29.7", "", {}, "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw=="], - "@babel/types": ["@babel/types@8.0.0-rc.6", "", { "dependencies": { "@babel/helper-string-parser": "^8.0.0-rc.6", "@babel/helper-validator-identifier": "^8.0.0-rc.6" } }, "sha512-p7/ABylAYlexb31wtRdIfH9L9A0Z2T/9H6zAqzqndkY2PLkvNNc580wGhp/gGKN4Sp9sQvSkhc6Oga8/O+wTyw=="], + "@babel/types": ["@babel/types@8.0.0", "", { "dependencies": { "@babel/helper-string-parser": "^8.0.0", "@babel/helper-validator-identifier": "^8.0.0" } }, "sha512-K8ponJDxBwDHigkeFqaqT5wLGl4bTlwMafR8k7b5CPxr6Ww+UG9ls8Yx6Tcpboxu97eeGVEEyKcHmEyOwN1vSw=="], + + "@braidai/lang": ["@braidai/lang@1.1.2", "", {}, "sha512-qBcknbBufNHlui137Hft8xauQMTZDKdophmLFv05r2eNmdIv/MlPuP4TdUknHG68UdWLgVZwgxVe735HzJNIwA=="], "@changesets/apply-release-plan": ["@changesets/apply-release-plan@7.1.1", "", { "dependencies": { "@changesets/config": "^3.1.4", "@changesets/get-version-range-type": "^0.4.0", "@changesets/git": "^3.0.4", "@changesets/should-skip-package": "^0.1.2", "@changesets/types": "^6.1.0", "@manypkg/get-packages": "^1.1.3", "detect-indent": "^6.0.0", "fs-extra": "^7.0.1", "lodash.startcase": "^4.4.0", "outdent": "^0.5.0", "prettier": "^2.7.1", "resolve-from": "^5.0.0", "semver": "^7.5.3" } }, "sha512-9qPCm/rLx/xoOFXIHGB229+4GOL76S4MC+7tyOuTsR6+1jYlfFDQORdvwR5hDA6y4FL2BPt3qpbcQIS+dW85LA=="], @@ -94,6 +104,8 @@ "@clack/prompts": ["@clack/prompts@1.5.1", "", { "dependencies": { "@clack/core": "1.4.1", "fast-string-width": "^3.0.2", "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-zccHj2z2oCCO4yrDiRSlFOxWerGqRiysP7a5jPK6uoI9URKAquwY42Dd/iUP8JWHxEzdRe4TlbvZCo8z1/mhrw=="], + "@colors/colors": ["@colors/colors@1.5.0", "", {}, "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="], + "@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="], "@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], @@ -112,6 +124,8 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + "@loaderkit/resolve": ["@loaderkit/resolve@1.0.6", "", { "dependencies": { "@braidai/lang": "^1.0.0" } }, "sha512-G8FdIoF5CypfwmD9rl8BXod5HDn8JqB0CCNBXDTaRZ+yRYhARrrSToX1zg1zy9jX3zLqigsELwhT4gNtkdQAUg=="], + "@manypkg/find-root": ["@manypkg/find-root@1.1.0", "", { "dependencies": { "@babel/runtime": "^7.5.5", "@types/node": "^12.7.1", "find-up": "^4.1.0", "fs-extra": "^8.1.0" } }, "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA=="], "@manypkg/get-packages": ["@manypkg/get-packages@1.1.3", "", { "dependencies": { "@babel/runtime": "^7.5.5", "@changesets/types": "^4.0.1", "@manypkg/find-root": "^1.1.0", "fs-extra": "^8.1.0", "globby": "^11.0.0", "read-yaml-file": "^1.1.0" } }, "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A=="], @@ -206,116 +220,120 @@ "@oxc-resolver/binding-win32-x64-msvc": ["@oxc-resolver/binding-win32-x64-msvc@11.20.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Wb14jWEW8huH6It9F6sXd9vrYmIS7pMrgkU6sxpLxkP+9z+wRgs71hUEhRpcn8FOXAFa27FVWfY2tRpbfTzfLw=="], - "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.55.0", "", { "os": "android", "cpu": "arm" }, "sha512-+rFDOqQe5LOWgxrAJaZgLRudr6GQm0wGI6gtu7vVkrdLGjNMUSGbAlaCr8j7F2H2Er97vYQCU8WDb30onqMM1g=="], + "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.57.0", "", { "os": "android", "cpu": "arm" }, "sha512-qVBsEO+KugOsCmUHcO8iqNnqc65p7PCKpCs8M66mPZ+Ri+CWbcpoQOEJBg2OTu03+0qu++NK1jj6IzvQVs0Sig=="], - "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.55.0", "", { "os": "android", "cpu": "arm64" }, "sha512-ctulLq8s3x8Zmvw6+iccB09TIKERAklRSmbJ10gk8mlAn05qZxoyo52dj3Hi9IJcmDSwF54fQaTVh2CbL6PInw=="], + "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.57.0", "", { "os": "android", "cpu": "arm64" }, "sha512-mp6PibWbao3aizijcheOeHQaYEhcUAt8pwLniYbtLfHxL/psFF0BykAwCj+s3c6qIpa8yN8keZICWrqtZ70w8g=="], - "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.55.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-xDQczLH9pw/RBk1h/GH0qcGMm8hQtmtVHBNLSH3lk1gEIR09hZ4L+mJQl4VqiVAvPK9VG9PYrWWuSQLt7xTbiA=="], + "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.57.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-T+0stuCBqmUVY+aMIvrgXhzGhHO3sD5tNiiEcYqgSdPsnukskQqn2u5qOVD0sv1l7RLdFS5Z/f5Wi9Ktyjr3Eg=="], - "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.55.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-JaNoFCkF2CJdGgpPSMbuO9HVyXyoNGIhMHPvp6NYAjeVKw9XEYc0HcUWJLPQa3Q69WV5wMa9m5jPMJPtbLtcRg=="], + "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.57.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-O+3JbqWs/mCI2oi4xfhRO2IVPFJNDDEBV8Odo+ZpmsUOeKJfjXoNH7nDmBEQcDgK7NfjDIyE7kRgYSZcTLDO0A=="], - "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.55.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-DNbszhpg6S2MIzax5azdHFTTBIVkR5xr8yyRZuA4yoDAwOkzIp3tmldgKZM2+VlT+hJIG0xUksA+elISzMEAfA=="], + "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.57.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-pxwhxVC+JkLX9twOQ/8C/vbuOQcMZyKIDmiRDZfO7yITuVcIdZCiLRqqf4QOxb2+8FWrRXzQpm+1DBKcMpHSSQ=="], - "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.55.0", "", { "os": "linux", "cpu": "arm" }, "sha512-2snoaoRfFFyGnbOcKUK36rREBYxe/Xgz3uHbiA5zbCB/s6R4DQj4mHqYAaWWhgizCUSDxV8cE9zAZ0XleNpKGw=="], + "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.57.0", "", { "os": "linux", "cpu": "arm" }, "sha512-pxBU4zH2imB/MDBfth2rOMeVxXUMjRQLCazagwLARIFH3hVlxZJBlM4nSnHXaIHJK4/qezoFCIORN6AY8Mra4A=="], - "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.55.0", "", { "os": "linux", "cpu": "arm" }, "sha512-q1aktHF/WRpSK81BX1dE/9vWrS2jGw1Nax2kb4DBLGAewubCLcoNyp4Zl/NSMgbv3vUS46Z33wIQkBVYOP3PYg=="], + "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.57.0", "", { "os": "linux", "cpu": "arm" }, "sha512-JAprOzt8tycYou36ZgEw14DlRHTiN8qdtKANdV3VZIRIvTI/lh/cX13c9pJ/EnDk2GT3FASH7KvCgQ2AufAifQ=="], - "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.55.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-VD0y36aENezl/3tsclA/4G53Cc7iV+7Uoh7gz4yvcOTaEYBtJpQsE6PKDGTtUtOvGS4kv51ybfXY/nWZejO5IA=="], + "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.57.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-ajtjaxSaj9xl4BW7REt+Cef/ttzbAq00Bq4z7JUDZEfgFXdwSjH8K9bF+IcIJzZB9lKqMfQ4eHuSFOvvlvtqOg=="], - "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.55.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-r8xlKJFcsRmn0H5jZrdORae6RX9jDBrZVvOoxF+bCQtampQJClv80aZEHsv+NsLsp2KCE5ql79O7DpPVzYWpXA=="], + "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.57.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-p4Y/+RYk9Bk5WO+zHSUXAClRmZ2fbJCejMuCAsU2HhyME4jqf6Ftt/mJYEwIah1wGCBDYOB7wEGV1x5bCEZ6hA=="], - "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.55.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-GRKv/HXHcwIVld/WU61rF0g0R16hl5EJ+ScKdpjevT57lnLnagj/U2YUbXf2mT+2Pg1uCzWC+mvGicPV3CDdLQ=="], + "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.57.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-By6tRALAZsno0F4zedmtG+wdMvJiJmJoXM4d3+A9zHE4HRXLqXITwRH8mgrlcXc5yJM2g2W3riRPwTYdgemZLQ=="], - "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.55.0", "", { "os": "linux", "cpu": "none" }, "sha512-rdv57enTiPtpSYRMKfAiEbQb0Puw5t9N7isVinDoo5qeLDScro2gznmZqSgSWbVZRzLisTeCTW8Qwgw0bOHv3A=="], + "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-skYeG+RgvyzspqVEBsEprL90OYYZfoVNqB3HcCNR6QDJyXKOzfDRT3zncnHmUaFluIlBHuY23mU1b5WGgR98hA=="], - "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.55.0", "", { "os": "linux", "cpu": "none" }, "sha512-7v1nNrlD43VY6+sYQ6efYyb3lE6QY182304PD/768ZxTjOmFd/3dQa3u/nGBUAXYdGSWOQc5N3PnS0QzUXyEIA=="], + "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.57.0", "", { "os": "linux", "cpu": "none" }, "sha512-FFgACrZOXAXUh5KQh2mt1CDOVOZmn+QzHP71wM9QobNwyQvoFfyAeefVUltW83g3sm7LTiH3yfFqLLVUpA5ZFQ=="], - "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.55.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-f4lJLUSPOgScjFl9LiflKCTocyNRwE25JmTMbN4XQdDjoZzEHjqf3wA3VESF1/csg7i8m7+EQLbrZyYDqe10UQ=="], + "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.57.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-Nm/BAOfQeFiiKd502mZn/GAVKJwtd0RdCg17G3Wz/WSOIQmDi3+7/SZH4BHn1Ye5KvTVH3ua8WvfwLLycNIuvA=="], - "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.55.0", "", { "os": "linux", "cpu": "x64" }, "sha512-MihqiPziJNoWy4MqNSV+jVA1g+07iQDjZiR0vaCaDoPgFEiJpCMsxamktzLV07cEeQsSJ04vQaU4CzCQwIvtDA=="], + "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.57.0", "", { "os": "linux", "cpu": "x64" }, "sha512-BiSy5Ku3mQqyxS6YIqAJgd403wEUWvI7kerfzPxc2l/txZVmZM0pSj7oDM+4bGBExowxOi7o73jEam1W0EDTZg=="], - "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.55.0", "", { "os": "linux", "cpu": "x64" }, "sha512-Yqghym7KYAVjP9MmSrNZiDeerMuoejNjo0r3ox5H3GDKk8eAfl8VyJm9i+pWCLDCTnAbcTUMMN2ZKjUYXH1v3g=="], + "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.57.0", "", { "os": "linux", "cpu": "x64" }, "sha512-BCRkJiotz5s9afLYD2LuMvzAoDYx9H17E/YbDyu4xK7l4zHDPeny9ErSXL//i/nJyaOwRk08x4b8cgJC00+JDg=="], - "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.55.0", "", { "os": "none", "cpu": "arm64" }, "sha512-s5SDvVVSbyQl1V5UU3Yl12M+XLUQ3rl5SglNqgAA2K4PXUtQhyNSS00wivONPEnNo5W01rCou8WkDNyvI/RGHg=="], + "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.57.0", "", { "os": "none", "cpu": "arm64" }, "sha512-4Oaxe1qrGgXfpCJ1C/ERJ2iCtV2rN1R79ga9fsfyVHfSQRu/hVW780u2KDqZWFZ/iGTHODJji0JemxqFZ63eIQ=="], - "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.55.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-7p9FB5R32tw2KyyNX3wpQrR2WHwEHvMEiBlGXxeTCaRMCVNx3UtFMAUbaQ/pRNWIrEUZmYhJ6tcUH52uPTRYjQ=="], + "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.57.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-MYLAsDnhdNsSGheLYhWgbk0vfIrlS84iQYun/y21fX6u0jj8iBtYtbpZMdiqYeuf8U12eVPUjVY2xE2NrCfJ0g=="], - "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.55.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-ZYqj3fDnOT1IaVGMP5kpmkQl4F3tQIm2ZyAxvqkJYmI0xgWWak4ss4XYwv3VDfM+TWXeC9K4uQ/wW5jm/5XABA=="], + "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.57.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-PBwdzZALJY/jcCx2E6is0yu+cuVXeySTDmwuseD+9j0mHqlRNxwlKgsyRTBed/woPeqfVfuXfWjoq4Cx2Zt3Eg=="], - "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.55.0", "", { "os": "win32", "cpu": "x64" }, "sha512-eEYT5tivGnGbPHuOHuQpi6CGLObhh0re/5jcNQHihD2GRYkTM85dyi5a19zjP8Q00t1uqAx+/QGLUGdHeqzWyg=="], + "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.57.0", "", { "os": "win32", "cpu": "x64" }, "sha512-bQJdH9i4RRfw55jm7+8/xS7GzHLLTbHx4huhrrDxQJaJtbSDbsyOnODvP1ftT7EG0KFKAYO2S+q6AcioXODx8w=="], - "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.70.0", "", { "os": "android", "cpu": "arm" }, "sha512-zFh0P4cswmRvw6nkyb89dr18rRanuaCPAsEXsFDoQY8WdaquI8Pt4NWFjaMJg6L23cy5NeN8J9cBnREbWzZhaw=="], + "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.72.0", "", { "os": "android", "cpu": "arm" }, "sha512-zhCmvn+1Mj3UchAc/90i99S0t7jJUsHmFVSPg4UWrjO8b8eaSGwscgO6QAUtvHBstkjQwBttQNswEnAF1mIQdA=="], - "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.70.0", "", { "os": "android", "cpu": "arm64" }, "sha512-qI8o4HZjeGiBrWv+pJv4lH0Yi2Gl/JSp/EumBUApezJprIKa5PS4nU0lQsQngtky8k+SplQIOjv6hwu0SSxeyg=="], + "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.72.0", "", { "os": "android", "cpu": "arm64" }, "sha512-mtH+aY/ozv1eZoCUC2owjFAtyNBKHpJHygKeEu9zXXnQGW1Q2/qOpvx+I+Lf23+TvTz66F4iiXUbl2cGvoLPCQ=="], - "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.70.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-8KjgVVHI5F9nVwHCRwwA78Ty7zNKP4Wd9OeN5PSv3iu/F/u1RVXoOCgLhWqust6HmwQG6xc8c+RCyaWENy24+w=="], + "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.72.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EvnajNPDtfknB3ZieeOOyDTwJn9QXDiwfnF4ZDQqART6RG6hjY4WigQcZdGoK2dkB3e1vrmEzN9aYbQCUkh/gQ=="], - "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.70.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-WVydssv5PSUBXFJTdNBWlmGkbNmvPGaFt/2SUT/EZRB6bq6bEOHmMlbnupZD5jmlEvi9+mZJHi8TCw15lyfSfQ=="], + "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.72.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZkCdEa/G80A7vEHfeCDz/+L3m33DE73v32mDKhgOIgz8Uwf0DFcK7+uu6qC+7LEhmz5fpOe1osWKyjSNMydFIQ=="], - "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.70.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-hJucmUf8OlinHNb1R7fI4Fw6WsAstOz7i8nmkWQfiHoZXtbufNm+MxiDTIMk1ggh2Ro4vLzgQ+bKvRY54MZoRA=="], + "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.72.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-NroXv2vh+sxVY1uya/rM5pjhx1hm8BzlYpx9q67QP0Xhw5MH2bf5GJylpvLEC+781p1Xli/317EoV9AlGwViag=="], - "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.70.0", "", { "os": "linux", "cpu": "arm" }, "sha512-1BnS7wbCYDSXwWzJJ+mc3NURoha6m6m6RT5c6vgAY3oz7C3OVXP+S0awo2mRq97arrJkVvO3qRQfyAHL+76xtQ=="], + "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.72.0", "", { "os": "linux", "cpu": "arm" }, "sha512-0NDywYgfj279Ou/BcQuCYSj7NJwBfmWn5qc5uGO/Ny7fUWmXyIpvawqX/8acQlWG6IXelJsJhj+JAy6sjsKj0A=="], - "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.70.0", "", { "os": "linux", "cpu": "arm" }, "sha512-yKy/UdbR55+M2yEcuiV5DCNC/gdQAjr/GioUy50QwBzSrKm8ueWADqyRLS9Xk+qjNeCYGg6A8FvUBds56ttfqg=="], + "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.72.0", "", { "os": "linux", "cpu": "arm" }, "sha512-4vpXB06h65Ezsy4hRyrGjGrfa1SkVPii09yaajiYhmVpgsFiLD+KNxIx/BNAY+XiO+i1yqp9HHdwqM8VTqa5XQ=="], - "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.70.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0A5XJ4alvmqFUFP/4oYSyaO+qLto/HrKEWTSaegiVl+HOufFngK2BjYw9x4RbwBt/du5QG6l5q1zeWiJYYG5yg=="], + "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.72.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-immaN4g2ZGFiOkKrvRX9LvzZdd2GkQM5wR+UyzYyUuyhUTXGQ4HKUJH18xp4G8OfhCVaVAJfKZxwE1r8+4hhaQ=="], - "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.70.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-JiylyurlB0CLSedNtx1gzv3FvfWPF1h/2Y3BJszPLNt5XQFlBsH5ke0Jle3iJb3uqu5m2e7A/DwzpuCAHdiU+A=="], + "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.72.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-JGHS9Mnr7iWyyLDxgCv1MhzVpAckgptg00F2gnxt/GD7lQ2SW1BRcxHqhSTaSdDpjWRrBkBxMMh4+Hn3aVtExg=="], - "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.70.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-J8VPG7I3/HmgaU4u8pNU2kFx2+0U+vPLS1dXFxXOaR/2TQ0f8AC7DRz0SRGRI1bfphnX2hVYTTtLuhL4nYKL+Q=="], + "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.72.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-AOYgBZqxNshrg83P9v0RYv+m8s10Cqkj4/PxXFDhcS3k7FqsIG5+CxErshZCIN7G8iy4Y+VGfAsuEdar8AcbBg=="], - "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.70.0", "", { "os": "linux", "cpu": "none" }, "sha512-N2+4lV2KLN+oXTIIIwmWDhwkrnvqf5oX7Hw0zPjk+RuIVgiBQSOlJWF7uQoFx2siEYX0ZQ5cfSbEAHm+J3t7Wg=="], + "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.72.0", "", { "os": "linux", "cpu": "none" }, "sha512-QMybPS5ij3/vrKG67mqzHwW++91sYxK/PPUVi6SBtNCEzW4niS52fVBdXbQ6nou0wWbUPEpx8Sl/ZjtgE3clXA=="], - "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.70.0", "", { "os": "linux", "cpu": "none" }, "sha512-1e2L7cFCvx9QDzq6NPP+0tABKb5z6nWHyddWTNKprEsjO9xNrAtPowuCGpjNXxkTdsMiZ4jc8YQ5SstZd4XK6g=="], + "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.72.0", "", { "os": "linux", "cpu": "none" }, "sha512-gOc3W7JV0PXRpIL7stUlLe3Wa9Gp0Kdlup87IT3gHDvPKck2xNgMIl/Gs2lldYY2lyXZDC4rWi3hmoLUobkgbQ=="], - "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.70.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-Kwu/l/8GcYibCWA9m9N5pRXMIKVSsL/YbgpLzYkqDhWTiqdRfnNJ/+nqIKRKQiFbHWsdlHEhzMwruJK+qcEruA=="], + "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.72.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-rpGxph+FjjHcYI5q6uxB3Az+tnfmEnDbSA8+PK9ZE/VzyUAkvBOMeuY7ZQMhu5mpZH7YQDsTdW6Cx4kV/msc6w=="], - "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.70.0", "", { "os": "linux", "cpu": "x64" }, "sha512-tap04CsHYOl0nSAQJfPNIuBxqEPB2HnhQqwaOXLg1jnp2XfRo8Fa814dA4QC4zpvTWXCjAAaCY1W5LOORkEQuQ=="], + "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.72.0", "", { "os": "linux", "cpu": "x64" }, "sha512-WND+uhf/Ko13SLqQMWQUgsZuLvYYEvL0ZKgg0tgGYfLqxG7l8Ju123fHDMJyYSDl5E3bUbpFUuii/OvMreFQzw=="], - "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.70.0", "", { "os": "linux", "cpu": "x64" }, "sha512-hzJa/WgvtJpbBD9rgfy0qe+MjbxOXNUT0bfR1S6EQQzfTtBFA9xg5q8KSwRrQ2QfSS+TaP4j+4mVPQrfNc6UNg=="], + "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.72.0", "", { "os": "linux", "cpu": "x64" }, "sha512-SrpbrUL70nG9vh6zP4/oKHWgLuHquwsr7MW9XOn0olBVgh10Uqr8qscKhQoBGEn6olK/IUpn5GSKcdQ5AjUhGA=="], - "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.70.0", "", { "os": "none", "cpu": "arm64" }, "sha512-xbsaNSNzVSnaJACCUYr1HQMyY/Q/Q1LkePmHG3UvZPvGCYGNxrsZp9OmtA6ick8xH47ltRRbRrPCM1YXYcyC+A=="], + "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.72.0", "", { "os": "none", "cpu": "arm64" }, "sha512-qkrsEn6NmgFKr7U/QnezQMb+q/vzAy0Dd9Y95gQGQTyjzDLN+HRZMuM5u70iyH4nBLCfKBzhjMsYCehKay2jyg=="], - "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.70.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-icAEsUI7JbW1TMRdEXV83mVAInhRVQYuuAlPpxdGwJ95chNdnCzjloRW8GglT0WvzOEZSio6fnYSk2DJ2Hv7LQ=="], + "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.72.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-LWR6ZlFZph+KPjXv8opgZsXRDCdrdQe8VL8Cg9zxCoBS73h6znzZpydVgmdnwj8mB9AuSM5jxEgDJDpQkjboeg=="], - "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.70.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-FHMSWbVsPVs/f+Jcl04ws4JJ2wUnauyTzlpxWRG/lSO/8GpX08Fo2gQZqdA6CrRFI+zvkxl+N/KwJGWfUwYVZA=="], + "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.72.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-yt6HEh7IsHvtjRWtmeZRX134eaXKHq5Gnqlf1xBJdJl1JtdoRUEJw3nAxpZoUDS860cX/foKbztO441anVBtVQ=="], - "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.70.0", "", { "os": "win32", "cpu": "x64" }, "sha512-ptOlKwCz7n4AKs5VweMqG6DAg677FmKOK+vBkkL9DMNgFATIQ+upqUYBTOEwRQyRAx1ncGlPlXleV2hIcm3z4g=="], + "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.72.0", "", { "os": "win32", "cpu": "x64" }, "sha512-b2eKFD2hX7tIwmo/cyH6TDq8vzWRZ2qNHrzoGntUTmq0h3zQh/uX3eTSHCwI8OB/ADQfJCRelLItK8BsxuucDA=="], + + "@publint/pack": ["@publint/pack@0.1.5", "", { "dependencies": { "tinyexec": "^1.2.4" } }, "sha512-edgyN2pP07uXiP4tJs0s8KVmU8M8i60YPbbI0/WDeok1mIJHRXz+CgD8I0nelwDkoCh3EWL/G5kGfbuHjsdbvw=="], "@quansync/fs": ["@quansync/fs@1.0.0", "", { "dependencies": { "quansync": "^1.0.0" } }, "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ=="], - "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.1.0", "", { "os": "android", "cpu": "arm64" }, "sha512-gCYzGOSkYY6Z034suzd20euvds7lPzMEEla62DJGE/ZAlR4OMBnNbvnBSsIGUCAr52gaWMsloGxP4tVGtN5aCA=="], + "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.1.4", "", { "os": "android", "cpu": "arm64" }, "sha512-EZLpf/8y7GXkkra90ML47kzik/GMP3EMcE9bPyHmRfxLC6z9+aW5A8poCsoxjrT5GfEcNAAvWwUHjvP1pUQkfw=="], - "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.1.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-JQBD77MNgu+4Z6RAyg69acugdrhhVoWesr3l47zohYZ2YV2fwkWMArkN/2p4l6Ei+Sno7W5q+UsKdVWq5Ens0w=="], + "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.1.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-aUi+HBvmYb7j8krl1+qJgkG8C17fO79gk3c+jPw4S8glRFc1DTija9S3EyaTSQUm5GJXYKDAsugBEhFHH2vYiQ=="], - "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.1.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-p/8cXUTK4Sob604e+xxPhVSbDFf29E6J0l/xESM9rdCfn3aDai3nEs6TnMHUsdD5aNlFz0+gDbiGlozLKGa2YA=="], + "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.1.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-F7hHC3gwY11+vByKPRWqwGbeXWVgKmL+pTGCinaEhdihzBV2aQ0fvZOch9cXYUOKuKKq429HeYXOqQLc7wFCEg=="], - "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.1.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-KbtOSlVv6fElujiZWMcC3aQYhEwLVVf073RcwlSmpGQvIsKZFUqc0ef4sjUuurRwfbiI6JJXji9DQn+86hawmQ=="], + "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.1.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-sI5yw+7s92SK6odiEhD5lKCBlWcpjHS5qyqpVQbZAJ0fIzEUXrmbl3DH2ybR3PZogulNJF+COLtmA8hUfvkCCQ=="], - "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.1.0", "", { "os": "linux", "cpu": "arm" }, "sha512-9fZ9i0o0/MQaw7om6Z6TsT7tfCk0jtbEFtC+aPqZL5RNsGWNcHvn6EHgL3dAprjq+AZzPTAQjg2JtpJaMt+6pg=="], + "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.1.4", "", { "os": "linux", "cpu": "arm" }, "sha512-mCi0OKgEieFircrtVYmQAFGszRtMnZ6fpZAXrxanXAu7lqZcsK1E1RAaZNG0uKAnxox3B1f4EyQNnoyMfN1vAA=="], - "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.1.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-+tog7T66i+yFyIuuAnjL6xmW182W/qTBOUt6BtQ6lBIM1Eikh/fSMz4HGgvuCp5uU0zuIVWng7kDYthjCMOHcg=="], + "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.1.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-B9Ial3Kv5sh0SHnB1g/QWcUQCEvCF6QKGAl4zXypYj65mVI+B4AhFBwPtSN7pDrJeIx8Z7zdy4ntx+wQABom7w=="], - "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.1.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-4b7yruLIIj/oZ3GpcLOvxcLCLDMraohn3IhQfN2hBP4w9UekG0DTIajWguJosRGfySf/+h/NwRUiMKoCpxCrqQ=="], + "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.1.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-lZVym0PuHE1KZ22gmFTC15lAkrg9iTszR617oYRB/iPY1A56ywoJzVKOJBKaot5RiikCObmur6pogpse3gRcng=="], - "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.1.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-QRDOVZd0bhQ5jLsUsCC3dUxDWdTSVY9WMznowZgCGOrZfLLgctWpelhUASEiBwsXfat/JwYnVd1EaxMhqyT+UQ=="], + "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.1.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-t2DNiLJWNTbnEHyUzTumldML6ET4/g16467LZoDDJ3tSxGvguL5/NyC2lCsNKuyRycg9XeDQF5SSv+TNOhQEXg=="], - "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.1.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-ypxT+Hq76NFG7woFbNbySnGEajFuYuIXeKz/jfCU+lXUoxfi3zLE6OG/ZQNeK3RpZSYJlAe2bokpsQ046CaieQ=="], + "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.1.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-0WIRnL1Uw4BvTZRLQt+PVgo6ZKTJadlC2btP+/EOXv2f/DWbY0rEgl+y834mIVwP1FkTlWVTrGGJXf12lru7EQ=="], - "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-IdovCmfROFmpTLahdecTDFL74aLERVYN68F/mLZjfVh6LfoplPfI6deyHNMTcVujbokDV5k05XrFO22zfv+qjg=="], + "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.1.4", "", { "os": "linux", "cpu": "x64" }, "sha512-JWtGshGfX+oENAKonoNkqEJX+7hC8yfhi9GUyPX1VX4mdh1y5r+ZiJLR5XzAB0aoP6s/PcILsGjKq8O0mm24bw=="], - "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-pcA8xlFp2tyk9T2R6Fi/rPe3bQ1MA+sSMDNUU5Ogu80GHOatkE4P8YCreGAvZErm5Ho2YRXnyvNrWiRncfVysQ=="], + "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.1.4", "", { "os": "linux", "cpu": "x64" }, "sha512-rT6yQcxUuXs4CnbofqwHRRV0iem349rLMYpTjkgQGLjrY4ado/eDzwPZPTCgTOlF6Nkp8NEv70yLMTn6qkWxsQ=="], - "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.1.0", "", { "os": "none", "cpu": "arm64" }, "sha512-4+fexHayrLCWpriPh4c6dNvL4an34DEZCG7zOM/FD5QNF6h8DT+bDXzyB/kfC8lDJbaFb7jKShtnjDQFXVQEjg=="], + "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.1.4", "", { "os": "none", "cpu": "arm64" }, "sha512-KXMGoboq5cyaCQjDA4GLuRiOwBQ0EyFnJoVViLeZ45/3rFItRODEr+NdsBcVpll40hhNArlm/speWGRvj08LzA=="], - "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.1.0", "", { "dependencies": { "@emnapi/core": "1.10.0", "@emnapi/runtime": "1.10.0", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-SbL++MNmOw6QamrwIGDMSSfM4ceTzFr+RjbOExJSLLBinScU4WI5OdA413h1qwPw2yH7lVF1+H4svQ+6mSXKTQ=="], + "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.1.4", "", { "dependencies": { "@emnapi/core": "1.11.1", "@emnapi/runtime": "1.11.1", "@napi-rs/wasm-runtime": "^1.1.6" }, "cpu": "none" }, "sha512-5K83rb36oJiY7BCyE9zLZtGcPV4g5wvq+xwdO0XPIwDVZI8cyB/AUjkNXGb92/rnmezEkjMOpgY61rtwjQtFwg=="], - "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.1.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-+xTE6XC7wBgk0VKRXGG+QAnyW5S9b8vfsFpiMjf0waQTmSQSU8onsH/beyZ8X4aXVveJnotiy7VDjLOaW8bTrg=="], + "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.1.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-PnWBtw3TV5KOg69HQQDR0mnQuyCmSGR2pAB4DC1rPF808fgKeTUMj2EOEyKATpgiuxuR5APQmiDO7PDgEjTFSA=="], - "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.1.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Ogji1TQNqH3ACLnYr+1Ns1nyrJ0CO2P585u9Hsh02pXvtFiFpgtgT2b3P4PnCOU86VVCvqtAeCN4OftMT8KU4w=="], + "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.1.4", "", { "os": "win32", "cpu": "x64" }, "sha512-M1lpniBePobTfsa7Ks9a199e1akxsXn+GYBUKsEzv3YFzOm1HJAMNwKI3qr0Zq+mxwx9gOZoTdP1yXRYsZUocQ=="], "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="], + "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="], "@types/better-sqlite3": ["@types/better-sqlite3@7.6.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA=="], @@ -326,23 +344,23 @@ "@types/jsesc": ["@types/jsesc@2.5.1", "", {}, "sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw=="], - "@types/node": ["@types/node@25.9.3", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg=="], + "@types/node": ["@types/node@26.1.0", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-O0A1G3xPGy4w7AgQdAQYUlQ+BKk2Oovw8eRpofyp5KdBZULnbe+WqaOVNrm705SHphCiG4XHsACrSmPu1f+Kgw=="], - "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260616.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260616.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260616.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260616.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260616.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260616.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260616.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260616.1" }, "bin": { "tsgo": "bin/tsgo.js" } }, "sha512-+AuZUl7nkLPXL1rwsyZZF7iasu0HkrL5O6aWwUC0cObD5EvNgxz3hXbBhsSvuJ8tb2JRpVwFsE0BHPcYVe5GkA=="], + "@typescript/native-preview": ["@typescript/native-preview@7.0.0-dev.20260706.1", "", { "optionalDependencies": { "@typescript/native-preview-darwin-arm64": "7.0.0-dev.20260706.1", "@typescript/native-preview-darwin-x64": "7.0.0-dev.20260706.1", "@typescript/native-preview-linux-arm": "7.0.0-dev.20260706.1", "@typescript/native-preview-linux-arm64": "7.0.0-dev.20260706.1", "@typescript/native-preview-linux-x64": "7.0.0-dev.20260706.1", "@typescript/native-preview-win32-arm64": "7.0.0-dev.20260706.1", "@typescript/native-preview-win32-x64": "7.0.0-dev.20260706.1" }, "bin": { "tsgo": "bin/tsgo" } }, "sha512-lm3nzcj+cbml0Pt+0QyOpdhZES9WRj0Fv/fds2GaKSf9wXe8694gy6Fa5D65lRcP6q4HHivlrNqJo8rR5Klzww=="], - "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260616.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-9SwegwwE7fYutnZJjTi2PeUXhKGFg82MGjSpCFD2cj5v9YQcs5oO5QsmeeMit4fMG8Z83Jy8knOF97d9NaQ7Bg=="], + "@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260706.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-l9UTIdxt99UUJ7pe/xWWwjoxr9EnG+Sc2k6FUchQrSK0sFZOlx76+hQm6DvuzWOr+1JEpVP/LGmnx7+qk8Yr3Q=="], - "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260616.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-gl7R8OiwEBNxzs5wjbM9XOibTs5b6/gAgu0+En9pLpYuWR/EITs8Eh0mNQui4JYTp1SkoHvn09aRZKTQf21XTg=="], + "@typescript/native-preview-darwin-x64": ["@typescript/native-preview-darwin-x64@7.0.0-dev.20260706.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-2/ivq1yeOrhNnN+aQhCLtGeqZ90R5v9OaoON4tG0zEJZLy+jIZGnRK6+gbI8lBhKuIVY2pjpHPJxN1VCaBmxGA=="], - "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260616.1", "", { "os": "linux", "cpu": "arm" }, "sha512-QWXQS2CrhSpXbng7vBtCVDszFgwVBuJU8MCFhxZL0hH6s+XjQDSNNkGO1oHueBr+7HbSkkyqfNYVNXvgVMUJLQ=="], + "@typescript/native-preview-linux-arm": ["@typescript/native-preview-linux-arm@7.0.0-dev.20260706.1", "", { "os": "linux", "cpu": "arm" }, "sha512-E2n8tnUcXwY4vRmyEpS8CfpJbK7y5coPtKtqDFtGZHbvWLPoiIP6OhHF5fIPCNMziBclz+5MR86OzxK1jt93YQ=="], - "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260616.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-CJjplWoE+EeYtbyNeP4fyuh0QcPiQBZJSLqPS07E3ugo3d9M/IG8WnL+3GFQ0g1p4c6QC/+OC0oTTQnGcNdd2Q=="], + "@typescript/native-preview-linux-arm64": ["@typescript/native-preview-linux-arm64@7.0.0-dev.20260706.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-eokiB0dLt8uUeWH2BbwhQZLrGay5quzptTsFs8kh/nFdSF4gYLoBwmpJn/o5YYrQU89T7Mvi4tKPkgo0TCnwIw=="], - "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260616.1", "", { "os": "linux", "cpu": "x64" }, "sha512-UVySBNnGTAnul2kO2/EhlVZl0CeTDcd6Lzi+WkvgyCgapTcU0BX1selQ4MEPtbVWKUbt9HBhxNku2dyaCcmKVw=="], + "@typescript/native-preview-linux-x64": ["@typescript/native-preview-linux-x64@7.0.0-dev.20260706.1", "", { "os": "linux", "cpu": "x64" }, "sha512-JwrLUanCkVq+vbSjcc+qMqQN909Jhiy1s671q5vaYmBMLIzlhNSkvWqmHk+8XLt100zcgJDGgv+kHRazDlpPUQ=="], - "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260616.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-kdX0QcDXiESH0o5DFdSWw15Hth0EtQobT9tX28ofqBUwGU1FFhwTKzA6qo7chaYUSW5MMd6XIME9rBwk+WizLw=="], + "@typescript/native-preview-win32-arm64": ["@typescript/native-preview-win32-arm64@7.0.0-dev.20260706.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-z75g24yUxktDSnP41t5Y3lV8BbraGyFuRvxhpd5GwXxT/qKQ3bHHcmdTTDSLkn+SRD8fAnnbFqb274UIC4OcCA=="], - "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260616.1", "", { "os": "win32", "cpu": "x64" }, "sha512-EB0Pj/0+nXifS3+wN0HdR1mKu7IieSpjMXoDjdXtJAdiPGlmKazBgHj97qn6CBvXisgLx0Eyb7tLCEQNDG53cA=="], + "@typescript/native-preview-win32-x64": ["@typescript/native-preview-win32-x64@7.0.0-dev.20260706.1", "", { "os": "win32", "cpu": "x64" }, "sha512-kWP0dMeCvTN5E4X4lQ7dELxyarnfapY1R9KPwHZdN7mcY67uPYSFTvBHD1+V3Q4dTQHQVIaHDUNOfU6McBo1wA=="], "accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], @@ -354,17 +372,19 @@ "ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="], - "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "ansis": ["ansis@4.3.1", "", {}, "sha512-BJ8/l4R5LRE7hW9WdSuGYrLSHi2ynxeFpDFbH0K/CgNeY/tyhk+vO6TYxXC5r5CpUhNVX310xzPsN/H9lCdfOA=="], + "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], "array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="], - "ast-kit": ["ast-kit@3.0.0-beta.1", "", { "dependencies": { "@babel/parser": "^8.0.0-beta.4", "estree-walker": "^3.0.3", "pathe": "^2.0.3" } }, "sha512-trmleAnZ2PxN/loHWVhhx1qeOHSRXq4TDsBBxq3GqeJitfk3+jTQ+v/C1km/KYq9M7wKqCewMh+/NAvVH7m+bw=="], + "ast-kit": ["ast-kit@3.0.0", "", { "dependencies": { "@babel/parser": "^8.0.0", "estree-walker": "^3.0.3", "pathe": "^2.0.3" } }, "sha512-8OG92q3R35qjC/4i6BLBMg8IB+fClWu/1PEwg2Z9Rn+BuNaiEgJzpzn+pxWOdHJWDCAwu2JP0wCDTozAM4QirQ=="], "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], @@ -394,16 +414,34 @@ "call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="], + "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + + "char-regex": ["char-regex@1.0.2", "", {}, "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="], + "chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="], "chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], + "cjs-module-lexer": ["cjs-module-lexer@1.4.3", "", {}, "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q=="], + "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="], + "cli-highlight": ["cli-highlight@2.1.11", "", { "dependencies": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", "mz": "^2.4.0", "parse5": "^5.1.1", "parse5-htmlparser2-tree-adapter": "^6.0.0", "yargs": "^16.0.0" }, "bin": { "highlight": "bin/highlight" } }, "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg=="], + + "cli-table3": ["cli-table3@0.6.5", "", { "dependencies": { "string-width": "^4.2.0" }, "optionalDependencies": { "@colors/colors": "1.5.0" } }, "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ=="], + "cli-truncate": ["cli-truncate@5.2.0", "", { "dependencies": { "slice-ansi": "^8.0.0", "string-width": "^8.2.0" } }, "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw=="], + "cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="], + + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "commander": ["commander@10.0.1", "", {}, "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug=="], + "content-disposition": ["content-disposition@1.1.0", "", {}, "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g=="], "content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="], @@ -442,7 +480,9 @@ "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], - "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "emojilib": ["emojilib@2.4.0", "", {}, "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw=="], "empathic": ["empathic@2.0.1", "", {}, "sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q=="], @@ -460,6 +500,8 @@ "es-object-atoms": ["es-object-atoms@1.1.2", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw=="], + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], @@ -496,6 +538,8 @@ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + "fflate": ["fflate@0.8.3", "", {}, "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA=="], + "file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="], "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], @@ -514,6 +558,8 @@ "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + "get-east-asian-width": ["get-east-asian-width@1.6.0", "", {}, "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA=="], "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], @@ -532,10 +578,14 @@ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], "hasown": ["hasown@2.0.3", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg=="], + "highlight.js": ["highlight.js@10.7.3", "", {}, "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="], + "hono": ["hono@4.12.25", "", {}, "sha512-2NFaIyNVgJmBs/ecmtGzlmluTFs5cHEWGTdu0t1HBwYzoGXOL5nUQBRMXsXWla5i4KkG//QMzVP88m1+I3fdAQ=="], "hookable": ["hookable@6.1.1", "", {}, "sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ=="], @@ -564,7 +614,7 @@ "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], - "is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], @@ -624,6 +674,12 @@ "log-update": ["log-update@6.1.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "cli-cursor": "^5.0.0", "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w=="], + "lru-cache": ["lru-cache@11.5.1", "", {}, "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A=="], + + "marked": ["marked@9.1.6", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q=="], + + "marked-terminal": ["marked-terminal@7.3.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "ansi-regex": "^6.1.0", "chalk": "^5.4.1", "cli-highlight": "^2.1.11", "cli-table3": "^0.6.5", "node-emoji": "^2.2.0", "supports-hyperlinks": "^3.1.0" }, "peerDependencies": { "marked": ">=1 <16" } }, "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw=="], + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], "media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="], @@ -650,19 +706,23 @@ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], + "napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="], "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], "node-abi": ["node-abi@3.92.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ=="], + "node-emoji": ["node-emoji@2.2.0", "", { "dependencies": { "@sindresorhus/is": "^4.6.0", "char-regex": "^1.0.2", "emojilib": "^2.4.0", "skin-tone": "^2.0.0" } }, "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw=="], + "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], "object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="], - "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="], + "obug": ["obug@2.1.3", "", {}, "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg=="], "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], @@ -676,9 +736,9 @@ "oxc-resolver": ["oxc-resolver@11.20.0", "", { "optionalDependencies": { "@oxc-resolver/binding-android-arm-eabi": "11.20.0", "@oxc-resolver/binding-android-arm64": "11.20.0", "@oxc-resolver/binding-darwin-arm64": "11.20.0", "@oxc-resolver/binding-darwin-x64": "11.20.0", "@oxc-resolver/binding-freebsd-x64": "11.20.0", "@oxc-resolver/binding-linux-arm-gnueabihf": "11.20.0", "@oxc-resolver/binding-linux-arm-musleabihf": "11.20.0", "@oxc-resolver/binding-linux-arm64-gnu": "11.20.0", "@oxc-resolver/binding-linux-arm64-musl": "11.20.0", "@oxc-resolver/binding-linux-ppc64-gnu": "11.20.0", "@oxc-resolver/binding-linux-riscv64-gnu": "11.20.0", "@oxc-resolver/binding-linux-riscv64-musl": "11.20.0", "@oxc-resolver/binding-linux-s390x-gnu": "11.20.0", "@oxc-resolver/binding-linux-x64-gnu": "11.20.0", "@oxc-resolver/binding-linux-x64-musl": "11.20.0", "@oxc-resolver/binding-openharmony-arm64": "11.20.0", "@oxc-resolver/binding-wasm32-wasi": "11.20.0", "@oxc-resolver/binding-win32-arm64-msvc": "11.20.0", "@oxc-resolver/binding-win32-x64-msvc": "11.20.0" } }, "sha512-CblytBiV/a/ZXY34dsVU2NxhIOxMXst8CvDCtyBelVITgd7PLrKzbEbA6oKLdPjvDKDzCiW48qzmzZ+mYaqn+g=="], - "oxfmt": ["oxfmt@0.55.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.55.0", "@oxfmt/binding-android-arm64": "0.55.0", "@oxfmt/binding-darwin-arm64": "0.55.0", "@oxfmt/binding-darwin-x64": "0.55.0", "@oxfmt/binding-freebsd-x64": "0.55.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.55.0", "@oxfmt/binding-linux-arm-musleabihf": "0.55.0", "@oxfmt/binding-linux-arm64-gnu": "0.55.0", "@oxfmt/binding-linux-arm64-musl": "0.55.0", "@oxfmt/binding-linux-ppc64-gnu": "0.55.0", "@oxfmt/binding-linux-riscv64-gnu": "0.55.0", "@oxfmt/binding-linux-riscv64-musl": "0.55.0", "@oxfmt/binding-linux-s390x-gnu": "0.55.0", "@oxfmt/binding-linux-x64-gnu": "0.55.0", "@oxfmt/binding-linux-x64-musl": "0.55.0", "@oxfmt/binding-openharmony-arm64": "0.55.0", "@oxfmt/binding-win32-arm64-msvc": "0.55.0", "@oxfmt/binding-win32-ia32-msvc": "0.55.0", "@oxfmt/binding-win32-x64-msvc": "0.55.0" }, "peerDependencies": { "svelte": "^5.0.0", "vite-plus": "*" }, "optionalPeers": ["svelte", "vite-plus"], "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-jSj2wCTakwgPMxkfiVZX0jf+nX+Nz6xlyAZjqNE0qXTFdCBPYlP6JAN+ODjmealw7DXBjOzYbdsqwBMAZnPZ6A=="], + "oxfmt": ["oxfmt@0.57.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.57.0", "@oxfmt/binding-android-arm64": "0.57.0", "@oxfmt/binding-darwin-arm64": "0.57.0", "@oxfmt/binding-darwin-x64": "0.57.0", "@oxfmt/binding-freebsd-x64": "0.57.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.57.0", "@oxfmt/binding-linux-arm-musleabihf": "0.57.0", "@oxfmt/binding-linux-arm64-gnu": "0.57.0", "@oxfmt/binding-linux-arm64-musl": "0.57.0", "@oxfmt/binding-linux-ppc64-gnu": "0.57.0", "@oxfmt/binding-linux-riscv64-gnu": "0.57.0", "@oxfmt/binding-linux-riscv64-musl": "0.57.0", "@oxfmt/binding-linux-s390x-gnu": "0.57.0", "@oxfmt/binding-linux-x64-gnu": "0.57.0", "@oxfmt/binding-linux-x64-musl": "0.57.0", "@oxfmt/binding-openharmony-arm64": "0.57.0", "@oxfmt/binding-win32-arm64-msvc": "0.57.0", "@oxfmt/binding-win32-ia32-msvc": "0.57.0", "@oxfmt/binding-win32-x64-msvc": "0.57.0" }, "peerDependencies": { "svelte": "^5.0.0", "vite-plus": "*" }, "optionalPeers": ["svelte", "vite-plus"], "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-ZB7Bi+rGDSqmVIo9jwcLyFgjxXvQhDdU+jx+ZrVy6VRiVXK2+CHc4hO3J4dUQjHe7V0ymHB+MDuv5z+NhK07HA=="], - "oxlint": ["oxlint@1.70.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.70.0", "@oxlint/binding-android-arm64": "1.70.0", "@oxlint/binding-darwin-arm64": "1.70.0", "@oxlint/binding-darwin-x64": "1.70.0", "@oxlint/binding-freebsd-x64": "1.70.0", "@oxlint/binding-linux-arm-gnueabihf": "1.70.0", "@oxlint/binding-linux-arm-musleabihf": "1.70.0", "@oxlint/binding-linux-arm64-gnu": "1.70.0", "@oxlint/binding-linux-arm64-musl": "1.70.0", "@oxlint/binding-linux-ppc64-gnu": "1.70.0", "@oxlint/binding-linux-riscv64-gnu": "1.70.0", "@oxlint/binding-linux-riscv64-musl": "1.70.0", "@oxlint/binding-linux-s390x-gnu": "1.70.0", "@oxlint/binding-linux-x64-gnu": "1.70.0", "@oxlint/binding-linux-x64-musl": "1.70.0", "@oxlint/binding-openharmony-arm64": "1.70.0", "@oxlint/binding-win32-arm64-msvc": "1.70.0", "@oxlint/binding-win32-ia32-msvc": "1.70.0", "@oxlint/binding-win32-x64-msvc": "1.70.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.22.1", "vite-plus": "*" }, "optionalPeers": ["oxlint-tsgolint", "vite-plus"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-D6JgHtzkhRwvEC+A0Nw5AEc5bk8x5i1pHzvZIEf/a0C4hOzmAACNGtkDGPyFaxxX3ZVGxCPeig3P3rMM8XU3/g=="], + "oxlint": ["oxlint@1.72.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.72.0", "@oxlint/binding-android-arm64": "1.72.0", "@oxlint/binding-darwin-arm64": "1.72.0", "@oxlint/binding-darwin-x64": "1.72.0", "@oxlint/binding-freebsd-x64": "1.72.0", "@oxlint/binding-linux-arm-gnueabihf": "1.72.0", "@oxlint/binding-linux-arm-musleabihf": "1.72.0", "@oxlint/binding-linux-arm64-gnu": "1.72.0", "@oxlint/binding-linux-arm64-musl": "1.72.0", "@oxlint/binding-linux-ppc64-gnu": "1.72.0", "@oxlint/binding-linux-riscv64-gnu": "1.72.0", "@oxlint/binding-linux-riscv64-musl": "1.72.0", "@oxlint/binding-linux-s390x-gnu": "1.72.0", "@oxlint/binding-linux-x64-gnu": "1.72.0", "@oxlint/binding-linux-x64-musl": "1.72.0", "@oxlint/binding-openharmony-arm64": "1.72.0", "@oxlint/binding-win32-arm64-msvc": "1.72.0", "@oxlint/binding-win32-ia32-msvc": "1.72.0", "@oxlint/binding-win32-x64-msvc": "1.72.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.22.1", "vite-plus": "*" }, "optionalPeers": ["oxlint-tsgolint", "vite-plus"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-1rhdZIP/EvoI91ABIwNU5Q8+bWf8mjrS5UzIOZld4d4bXxJvtlUhlQvaoTogIGin/qdErMOrwaIJvCSIAKTLhA=="], "p-filter": ["p-filter@2.1.0", "", { "dependencies": { "p-map": "^2.0.0" } }, "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw=="], @@ -692,6 +752,10 @@ "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], + "parse5": ["parse5@5.1.1", "", {}, "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug=="], + + "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@6.0.1", "", { "dependencies": { "parse5": "^6.0.1" } }, "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA=="], + "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], @@ -718,6 +782,8 @@ "proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="], + "publint": ["publint@0.3.21", "", { "dependencies": { "@publint/pack": "^0.1.4", "package-manager-detector": "^1.6.0", "picocolors": "^1.1.1", "sade": "^1.8.1" }, "bin": { "publint": "src/cli.js" } }, "sha512-OqejcnMV6E9zel2oCrUOJEiiFkGiAAni0A6ibfQNh1k9Gu5z4F+Yso8lllam7AzmV6Do0vp7u3UpZNRBwuXaHQ=="], + "pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="], "qs": ["qs@6.15.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw=="], @@ -738,6 +804,8 @@ "readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], + "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], @@ -750,14 +818,16 @@ "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], - "rolldown": ["rolldown@1.1.0", "", { "dependencies": { "@oxc-project/types": "=0.134.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.1.0", "@rolldown/binding-darwin-arm64": "1.1.0", "@rolldown/binding-darwin-x64": "1.1.0", "@rolldown/binding-freebsd-x64": "1.1.0", "@rolldown/binding-linux-arm-gnueabihf": "1.1.0", "@rolldown/binding-linux-arm64-gnu": "1.1.0", "@rolldown/binding-linux-arm64-musl": "1.1.0", "@rolldown/binding-linux-ppc64-gnu": "1.1.0", "@rolldown/binding-linux-s390x-gnu": "1.1.0", "@rolldown/binding-linux-x64-gnu": "1.1.0", "@rolldown/binding-linux-x64-musl": "1.1.0", "@rolldown/binding-openharmony-arm64": "1.1.0", "@rolldown/binding-wasm32-wasi": "1.1.0", "@rolldown/binding-win32-arm64-msvc": "1.1.0", "@rolldown/binding-win32-x64-msvc": "1.1.0" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-zpMvlJhs5PkXRTtKc0CaLBVI9AR/VDiJFpM+kx//hgToEca7FgMlGjaRIisXBcb19T76LswgmKECSQ96hjWr5A=="], + "rolldown": ["rolldown@1.1.4", "", { "dependencies": { "@oxc-project/types": "=0.138.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.1.4", "@rolldown/binding-darwin-arm64": "1.1.4", "@rolldown/binding-darwin-x64": "1.1.4", "@rolldown/binding-freebsd-x64": "1.1.4", "@rolldown/binding-linux-arm-gnueabihf": "1.1.4", "@rolldown/binding-linux-arm64-gnu": "1.1.4", "@rolldown/binding-linux-arm64-musl": "1.1.4", "@rolldown/binding-linux-ppc64-gnu": "1.1.4", "@rolldown/binding-linux-s390x-gnu": "1.1.4", "@rolldown/binding-linux-x64-gnu": "1.1.4", "@rolldown/binding-linux-x64-musl": "1.1.4", "@rolldown/binding-openharmony-arm64": "1.1.4", "@rolldown/binding-wasm32-wasi": "1.1.4", "@rolldown/binding-win32-arm64-msvc": "1.1.4", "@rolldown/binding-win32-x64-msvc": "1.1.4" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-IjZYiLxZwpnhwhdBH2ugdTGVSdhCQUmLxLoqyjiL0JxYjyRst+5a0P3xfrTxJ5F638j4Mvvw5FAX5XE6eHpXbA=="], - "rolldown-plugin-dts": ["rolldown-plugin-dts@0.25.2", "", { "dependencies": { "@babel/generator": "8.0.0-rc.6", "@babel/helper-validator-identifier": "8.0.0-rc.6", "@babel/parser": "8.0.0-rc.6", "ast-kit": "^3.0.0-beta.1", "birpc": "^4.0.0", "dts-resolver": "^3.0.0", "get-tsconfig": "5.0.0-beta.5", "obug": "^2.1.1" }, "peerDependencies": { "@ts-macro/tsc": "^0.3.6", "@typescript/native-preview": ">=7.0.0-dev.20260325.1", "rolldown": "^1.0.0", "typescript": "^5.0.0 || ^6.0.0", "vue-tsc": "~3.2.0" }, "optionalPeers": ["@ts-macro/tsc", "@typescript/native-preview", "typescript", "vue-tsc"] }, "sha512-nMhN/R+vmR8GM45ZW1FWMSjRTSDDn/6w4GTf8RNrEFCBdl8B1kySWrU1ixPtbwzXoRlcO+R/S88VgXuJQwfdDg=="], + "rolldown-plugin-dts": ["rolldown-plugin-dts@0.26.0", "", { "dependencies": { "@babel/generator": "^8.0.0", "@babel/helper-validator-identifier": "^8.0.0", "@babel/parser": "^8.0.0", "ast-kit": "^3.0.0", "birpc": "^4.0.0", "dts-resolver": "^3.0.0", "get-tsconfig": "5.0.0-beta.5", "obug": "^2.1.3" }, "peerDependencies": { "@ts-macro/tsc": "^0.3.6", "@typescript/native-preview": ">=7.0.0-dev.20260325.1", "rolldown": "^1.0.0", "typescript": "^5.0.0 || ^6.0.0", "vue-tsc": "~3.2.0 || ~3.3.0" }, "optionalPeers": ["@ts-macro/tsc", "@typescript/native-preview", "typescript", "vue-tsc"] }, "sha512-e+kEPtUiDES0htk5iqkSeF4EzAV7R+vugGB44iPDuw1Kw9E+WyL1VG7PaV0IIjGHLiacztMBcMTyrr8ON9CT1Q=="], "router": ["router@2.2.0", "", { "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", "is-promise": "^4.0.0", "parseurl": "^1.3.3", "path-to-regexp": "^8.0.0" } }, "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ=="], "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], + "sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="], + "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], @@ -790,6 +860,8 @@ "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], + "skin-tone": ["skin-tone@2.0.0", "", { "dependencies": { "unicode-emoji-modifier-base": "^1.0.0" } }, "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA=="], + "slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], "slice-ansi": ["slice-ansi@8.0.0", "", { "dependencies": { "ansi-styles": "^6.2.3", "is-fullwidth-code-point": "^5.1.0" } }, "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg=="], @@ -800,7 +872,7 @@ "string-argv": ["string-argv@0.3.2", "", {}, "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q=="], - "string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="], + "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="], @@ -810,12 +882,20 @@ "strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], + "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "supports-hyperlinks": ["supports-hyperlinks@3.2.0", "", { "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" } }, "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig=="], + "tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="], "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], "term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="], + "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], + + "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], + "tinyexec": ["tinyexec@1.2.4", "", {}, "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg=="], "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], @@ -830,7 +910,7 @@ "tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="], - "tsdown": ["tsdown@0.22.2", "", { "dependencies": { "ansis": "^4.3.1", "cac": "^7.0.0", "defu": "^6.1.7", "empathic": "^2.0.1", "hookable": "^6.1.1", "import-without-cache": "^0.4.0", "obug": "^2.1.1", "picomatch": "^4.0.4", "rolldown": "~1.1.0", "rolldown-plugin-dts": "^0.25.2", "semver": "^7.8.1", "tinyexec": "^1.2.4", "tinyglobby": "^0.2.17", "tree-kill": "^1.2.2", "unconfig-core": "^7.5.0" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@tsdown/css": "0.22.2", "@tsdown/exe": "0.22.2", "@vitejs/devtools": "*", "publint": "^0.3.8", "tsx": "*", "typescript": "^5.0.0 || ^6.0.0", "unplugin-unused": "^0.5.0", "unrun": "*" }, "optionalPeers": ["@arethetypeswrong/core", "@tsdown/css", "@tsdown/exe", "@vitejs/devtools", "publint", "tsx", "typescript", "unplugin-unused", "unrun"], "bin": { "tsdown": "./dist/run.mjs" } }, "sha512-VX9gsyKXsTnBZjnIM4jsHl9aRv+GfgkE/k1hQslilaBfZMlaw3JuGR+6yhiU0QxWBtOCDnTjwOSoXzgB7Rr50g=="], + "tsdown": ["tsdown@0.22.3", "", { "dependencies": { "ansis": "^4.3.1", "cac": "^7.0.0", "defu": "^6.1.7", "empathic": "^2.0.1", "hookable": "^6.1.1", "import-without-cache": "^0.4.0", "obug": "^2.1.3", "picomatch": "^4.0.4", "rolldown": "~1.1.1", "rolldown-plugin-dts": "^0.26.0", "semver": "^7.8.4", "tinyexec": "^1.2.4", "tinyglobby": "^0.2.17", "tree-kill": "^1.2.2", "unconfig-core": "^7.5.0" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@tsdown/css": "0.22.3", "@tsdown/exe": "0.22.3", "@vitejs/devtools": "*", "publint": "^0.3.8", "tsx": "*", "typescript": "^5.0.0 || ^6.0.0", "unplugin-unused": "^0.5.0", "unrun": "*" }, "optionalPeers": ["@arethetypeswrong/core", "@tsdown/css", "@tsdown/exe", "@vitejs/devtools", "publint", "tsx", "typescript", "unplugin-unused", "unrun"], "bin": { "tsdown": "./dist/run.mjs" } }, "sha512-louqbfA8Qf//B9jTTL0FPtXTNpjCWv1VPkbcmQMph2pTpzs+LnB1tbe4tDDRVpo2BjF5SgUXaTZe45SxB8pWHg=="], "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], @@ -842,7 +922,9 @@ "unconfig-core": ["unconfig-core@7.5.0", "", { "dependencies": { "@quansync/fs": "^1.0.0", "quansync": "^1.0.0" } }, "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w=="], - "undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], + "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], + + "unicode-emoji-modifier-base": ["unicode-emoji-modifier-base@1.0.0", "", {}, "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g=="], "universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="], @@ -852,6 +934,8 @@ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + "validate-npm-package-name": ["validate-npm-package-name@5.0.1", "", {}, "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ=="], + "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], @@ -864,12 +948,20 @@ "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + "yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], + "yargs": ["yargs@16.2.2", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-Nt9ZJjXTv5R8MHbqby/wXQ6Gi0Bb3TcYZkR1bzuL4yB2OxWPkXknz513gEF0GoA6tn00UpbPvERW8rzCuWCA6w=="], + + "yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="], + "zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="], "zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="], + "@arethetypeswrong/core/typescript": ["typescript@5.6.1-rc", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-E3b2+1zEFu84jB0YQi9BORDjz9+jGbwwy1Zi3G0LUNw7a7cePUrHMRNy8aPh53nXpkFGVHSxIZo5vKTfYaFiBQ=="], + "@changesets/cli/package-manager-detector": ["package-manager-detector@0.2.11", "", { "dependencies": { "quansync": "^0.2.7" } }, "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ=="], "@manypkg/find-root/@types/node": ["@types/node@12.20.55", "", {}, "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="], @@ -888,44 +980,108 @@ "@quansync/fs/quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="], - "@rolldown/binding-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="], - - "@rolldown/binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="], - - "@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], + "@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="], "@types/better-sqlite3/@types/node": ["@types/node@25.9.1", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg=="], "bun-types/@types/node": ["@types/node@25.9.1", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg=="], + "cli-truncate/string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="], + + "cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + "log-update/slice-ansi": ["slice-ansi@7.1.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w=="], "log-update/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], "log-update/wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], + "marked-terminal/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], + "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], - "rolldown/@oxc-project/types": ["@oxc-project/types@0.134.0", "", {}, "sha512-T0xuRRKrQFmocH8y+jGfpmSkGcheaJExY9lEihmR1Gm2aH+75B8CzgU2rABRQSzzDxLjZ15Sc0bRVLj5lVeNXQ=="], + "parse5-htmlparser2-tree-adapter/parse5": ["parse5@6.0.1", "", {}, "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="], + + "rolldown/@oxc-project/types": ["@oxc-project/types@0.138.0", "", {}, "sha512-1a7ZKmrRTCoN1XMZ4L0PyyqrMnrNlLyPuOkdSX2MZg7IiIGRUyurNhAm73ptDOraoBcIordsIGKNPKUzy3ZmfA=="], - "string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + "slice-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], + + "strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "tsdown/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], "type-is/content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="], "unconfig-core/quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="], + "unrun/rolldown": ["rolldown@1.1.0", "", { "dependencies": { "@oxc-project/types": "=0.134.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.1.0", "@rolldown/binding-darwin-arm64": "1.1.0", "@rolldown/binding-darwin-x64": "1.1.0", "@rolldown/binding-freebsd-x64": "1.1.0", "@rolldown/binding-linux-arm-gnueabihf": "1.1.0", "@rolldown/binding-linux-arm64-gnu": "1.1.0", "@rolldown/binding-linux-arm64-musl": "1.1.0", "@rolldown/binding-linux-ppc64-gnu": "1.1.0", "@rolldown/binding-linux-s390x-gnu": "1.1.0", "@rolldown/binding-linux-x64-gnu": "1.1.0", "@rolldown/binding-linux-x64-musl": "1.1.0", "@rolldown/binding-openharmony-arm64": "1.1.0", "@rolldown/binding-wasm32-wasi": "1.1.0", "@rolldown/binding-win32-arm64-msvc": "1.1.0", "@rolldown/binding-win32-x64-msvc": "1.1.0" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-zpMvlJhs5PkXRTtKc0CaLBVI9AR/VDiJFpM+kx//hgToEca7FgMlGjaRIisXBcb19T76LswgmKECSQ96hjWr5A=="], + + "wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + + "wrap-ansi/string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="], + "wrap-ansi/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], "@oxc-resolver/binding-wasm32-wasi/@emnapi/core/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], - "@rolldown/binding-wasm32-wasi/@emnapi/core/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], + "@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], + + "@types/better-sqlite3/@types/node/undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], + + "bun-types/@types/node/undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="], + + "cli-truncate/string-width/strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + + "log-update/slice-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], - "log-update/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + "log-update/slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], + + "log-update/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], "log-update/wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], - "string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + "unrun/rolldown/@oxc-project/types": ["@oxc-project/types@0.134.0", "", {}, "sha512-T0xuRRKrQFmocH8y+jGfpmSkGcheaJExY9lEihmR1Gm2aH+75B8CzgU2rABRQSzzDxLjZ15Sc0bRVLj5lVeNXQ=="], + + "unrun/rolldown/@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.1.0", "", { "os": "android", "cpu": "arm64" }, "sha512-gCYzGOSkYY6Z034suzd20euvds7lPzMEEla62DJGE/ZAlR4OMBnNbvnBSsIGUCAr52gaWMsloGxP4tVGtN5aCA=="], + + "unrun/rolldown/@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.1.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-JQBD77MNgu+4Z6RAyg69acugdrhhVoWesr3l47zohYZ2YV2fwkWMArkN/2p4l6Ei+Sno7W5q+UsKdVWq5Ens0w=="], + + "unrun/rolldown/@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.1.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-p/8cXUTK4Sob604e+xxPhVSbDFf29E6J0l/xESM9rdCfn3aDai3nEs6TnMHUsdD5aNlFz0+gDbiGlozLKGa2YA=="], + + "unrun/rolldown/@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.1.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-KbtOSlVv6fElujiZWMcC3aQYhEwLVVf073RcwlSmpGQvIsKZFUqc0ef4sjUuurRwfbiI6JJXji9DQn+86hawmQ=="], + + "unrun/rolldown/@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.1.0", "", { "os": "linux", "cpu": "arm" }, "sha512-9fZ9i0o0/MQaw7om6Z6TsT7tfCk0jtbEFtC+aPqZL5RNsGWNcHvn6EHgL3dAprjq+AZzPTAQjg2JtpJaMt+6pg=="], + + "unrun/rolldown/@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.1.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-+tog7T66i+yFyIuuAnjL6xmW182W/qTBOUt6BtQ6lBIM1Eikh/fSMz4HGgvuCp5uU0zuIVWng7kDYthjCMOHcg=="], + + "unrun/rolldown/@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.1.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-4b7yruLIIj/oZ3GpcLOvxcLCLDMraohn3IhQfN2hBP4w9UekG0DTIajWguJosRGfySf/+h/NwRUiMKoCpxCrqQ=="], + + "unrun/rolldown/@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.1.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-QRDOVZd0bhQ5jLsUsCC3dUxDWdTSVY9WMznowZgCGOrZfLLgctWpelhUASEiBwsXfat/JwYnVd1EaxMhqyT+UQ=="], + + "unrun/rolldown/@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.1.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-ypxT+Hq76NFG7woFbNbySnGEajFuYuIXeKz/jfCU+lXUoxfi3zLE6OG/ZQNeK3RpZSYJlAe2bokpsQ046CaieQ=="], + + "unrun/rolldown/@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-IdovCmfROFmpTLahdecTDFL74aLERVYN68F/mLZjfVh6LfoplPfI6deyHNMTcVujbokDV5k05XrFO22zfv+qjg=="], + + "unrun/rolldown/@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-pcA8xlFp2tyk9T2R6Fi/rPe3bQ1MA+sSMDNUU5Ogu80GHOatkE4P8YCreGAvZErm5Ho2YRXnyvNrWiRncfVysQ=="], + + "unrun/rolldown/@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.1.0", "", { "os": "none", "cpu": "arm64" }, "sha512-4+fexHayrLCWpriPh4c6dNvL4an34DEZCG7zOM/FD5QNF6h8DT+bDXzyB/kfC8lDJbaFb7jKShtnjDQFXVQEjg=="], + + "unrun/rolldown/@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.1.0", "", { "dependencies": { "@emnapi/core": "1.10.0", "@emnapi/runtime": "1.10.0", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-SbL++MNmOw6QamrwIGDMSSfM4ceTzFr+RjbOExJSLLBinScU4WI5OdA413h1qwPw2yH7lVF1+H4svQ+6mSXKTQ=="], + + "unrun/rolldown/@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.1.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-+xTE6XC7wBgk0VKRXGG+QAnyW5S9b8vfsFpiMjf0waQTmSQSU8onsH/beyZ8X4aXVveJnotiy7VDjLOaW8bTrg=="], + + "unrun/rolldown/@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.1.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Ogji1TQNqH3ACLnYr+1Ns1nyrJ0CO2P585u9Hsh02pXvtFiFpgtgT2b3P4PnCOU86VVCvqtAeCN4OftMT8KU4w=="], + + "log-update/wrap-ansi/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], + + "unrun/rolldown/@rolldown/binding-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="], + + "unrun/rolldown/@rolldown/binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="], + + "unrun/rolldown/@rolldown/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="], - "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + "unrun/rolldown/@rolldown/binding-wasm32-wasi/@emnapi/core/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], } } diff --git a/docs/packaging.md b/docs/packaging.md index 56253252..b3e62843 100644 --- a/docs/packaging.md +++ b/docs/packaging.md @@ -38,11 +38,11 @@ Same schema and CLI; implementation differs by runtime. Details: [architecture.m Releases use [**Changesets**](https://github.com/changesets/changesets). Repo config: [`.changeset/config.json`](../.changeset/config.json) (`$schema` targets **`@changesets/config`** — resolved version in **`bun.lock`**). Upstream CLI docs: [`.changeset/README.md`](../.changeset/README.md). -| Step | What happens | -| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 1 | **`bun run changeset`** — add a changeset file under **`.changeset/`**, commit, open PR to **`main`**. | -| 2 | **Merge** — on every push to **`main`**, [`.github/workflows/release.yml`](../.github/workflows/release.yml) runs [`changesets/action@v1`](https://github.com/changesets/action): opens/updates the **Version packages** PR when pending changesets exist; **`version: bun run version`** runs **`changeset version`** then **`oxfmt`** on **`CHANGELOG.md`** so formatting matches **`bun run format:check`**; **`publish: bun run release`** runs **`changeset publish`**; **`createGithubReleases: true`**. | -| 3 | **Secrets** — **`GITHUB_TOKEN`** is provided by Actions. **`NPM_TOKEN`** (npm [automation token](https://docs.npmjs.com/creating-and-viewing-access-tokens)) must be a **repository secret** for publishes to npm. If the Release job fails, use the workflow log (missing token, registry error, etc.) — don’t assume the cause from the job name alone. | +| Step | What happens | +| ---- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 1 | **`bun run changeset`** — add a changeset file under **`.changeset/`**, commit, open PR to **`main`**. | +| 2 | **Merge** — on every push to **`main`**, [`.github/workflows/release.yml`](../.github/workflows/release.yml) runs [`changesets/action@v1`](https://github.com/changesets/action): opens/updates the **Version packages** PR when pending changesets exist; **`version: bun run version`** runs **`changeset version`** then **`oxfmt`** on **`CHANGELOG.md`** so formatting matches **`bun run format:check`**; **`publish: bun run release`** runs **`changeset publish`**; **`createGithubReleases: true`**. | +| 3 | **Publishing** — publishes to npm via [trusted publishing](https://docs.npmjs.com/trusted-publishers) (GitHub OIDC; **no `NPM_TOKEN`**). Requires the workflow’s **`id-token: write`** permission, a **`release`** [environment](https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment), and an npm trusted-publisher binding for **`@stainless-code/codemap`** (workflow file + repo + environment). Sigstore provenance is auto-generated. A dedicated **Node 24** step puts npm ≥ 11 in `PATH` (setup-bun leaves npm 10.x, which can’t detect OIDC → `ENEEDAUTH`). If the Release job fails, read the step log — common causes are OIDC/trusted-publishing misconfig, registry/network errors, or a real publish failure — don’t assume the cause from the job name alone. | **Before tagging / publishing:** run **`bun run check`** on the branch that will ship. Pending **`.changeset/*.md`** files are turned into **`CHANGELOG.md`** entries and a version bump by the **Version packages** PR (do not hand-edit **`package.json`** version for Changesets-driven releases). Merge that PR to **`main`** to run **`changeset publish`** via the workflow. diff --git a/package.json b/package.json index acdb2691..1aefdd83 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/stainless-code/codemap.git" + "url": "git+https://github.com/stainless-code/codemap.git" }, "bin": { "codemap": "./dist/index.mjs" @@ -30,6 +30,7 @@ "templates" ], "type": "module", + "sideEffects": false, "main": "./dist/index.mjs", "types": "./dist/index.d.mts", "exports": { @@ -39,7 +40,8 @@ } }, "publishConfig": { - "access": "public" + "access": "public", + "provenance": true }, "scripts": { "benchmark": "bun src/benchmark.ts", @@ -48,26 +50,31 @@ "changeset": "changeset", "check": "bun run build && bun run --parallel format:check lint:ci test test:scripts typecheck && bun run test:golden && bun run test:agent-eval", "check-updates": "bun update -i --latest", + "check:pack": "attw --pack . --profile esm-only && publint", "check:perf-baseline": "bun scripts/check-perf-baseline.ts", "check:perf-baseline:update": "bun scripts/check-perf-baseline.ts --update", "clean": "git clean -xdf -e .env -e docs/research/scratch", "dev": "bun src/index.ts", "fix": "bun run lint:fix && bun run format", - "format": "oxfmt", + "fix:changes": "bun run lint:fix:changes && bun run format:changes", + "format": "oxfmt --no-error-on-unmatched-pattern", + "format:changes": "bun scripts/run-on-changed-files.ts format", "format:check": "oxfmt --check --no-error-on-unmatched-pattern", "lint": "oxlint --no-error-on-unmatched-pattern", "lint-staged": "lint-staged", + "lint:changes": "bun scripts/run-on-changed-files.ts lint", "lint:ci": "oxlint --quiet", - "lint:fix": "oxlint --fix", + "lint:fix": "bun run lint --fix", + "lint:fix:changes": "bun scripts/run-on-changed-files.ts lint:fix", "pack": "bun run build && npm pack", "prepare": "husky || true", - "prepublishOnly": "bun run check", + "prepublishOnly": "bun run check && bun run check:pack", "qa:external": "bun scripts/qa-external-repo.ts", "release": "changeset publish", "test": "bun test ./src", "test:agent-eval": "bun test scripts/agent-eval", "test:ci": "bun run test:coverage", - "test:coverage": "bun test --coverage ./src", + "test:coverage": "bun test --coverage --coverage-threshold=0.75 ./src", "test:golden": "bun scripts/query-golden.ts", "test:golden:external": "bun scripts/query-golden.ts --corpus external", "test:scripts": "bash -c 'files=$(find scripts -name \"*.test.mjs\"); if [ -z \"$files\" ]; then echo \"no scripts test files found\" >&2; exit 1; fi; exec bun test $files'", @@ -87,17 +94,19 @@ "zod": "4.4.3" }, "devDependencies": { + "@arethetypeswrong/cli": "0.18.4", "@changesets/changelog-github": "0.7.0", "@changesets/cli": "2.31.0", "@types/better-sqlite3": "7.6.13", "@types/bun": "1.3.14", - "@types/node": "25.9.3", - "@typescript/native-preview": "7.0.0-dev.20260616.1", + "@types/node": "26.1.0", + "@typescript/native-preview": "7.0.0-dev.20260706.1", "husky": "9.1.7", "lint-staged": "17.0.7", - "oxfmt": "0.55.0", - "oxlint": "1.70.0", - "tsdown": "0.22.2", + "oxfmt": "0.57.0", + "oxlint": "1.72.0", + "publint": "0.3.21", + "tsdown": "0.22.3", "typescript": "6.0.3", "unrun": "0.3.1" }, @@ -111,5 +120,6 @@ "bun": ">=1.0.0", "node": "^20.19.0 || >=22.12.0" }, + "packageManager": "bun@1.3.14", "contributing": ".github/CONTRIBUTING.md" } diff --git a/scripts/run-on-changed-files.ts b/scripts/run-on-changed-files.ts new file mode 100644 index 00000000..9ad646c5 --- /dev/null +++ b/scripts/run-on-changed-files.ts @@ -0,0 +1,36 @@ +#!/usr/bin/env bun +// Run a package script against every changed file — working tree + staged + +// untracked, deduplicated — the single definition behind the `*:changes` +// scripts. Usage: bun scripts/run-on-changed-files.ts <package-script> +// Exits 0 quietly when nothing changed. +import { $ } from "bun"; + +const task = process.argv[2]; +if (!task) { + console.error("usage: bun scripts/run-on-changed-files.ts <package-script>"); + process.exit(1); +} + +const [unstaged, staged, untracked] = await Promise.all([ + $`git diff --name-only --diff-filter=ACMR`.text(), + $`git diff --name-only --cached --diff-filter=ACMR`.text(), + $`git ls-files --others --exclude-standard`.text(), +]); + +const files = [ + ...new Set( + [unstaged, staged, untracked] + .join("\n") + .split("\n") + .map((line) => line.trim()) + .filter(Boolean), + ), +].sort(); + +if (files.length === 0) process.exit(0); + +const proc = Bun.spawnSync(["bun", "run", task, ...files], { + stdout: "inherit", + stderr: "inherit", +}); +process.exit(proc.exitCode ?? 1); diff --git a/src/package-scripts.test.ts b/src/package-scripts.test.ts index 563487bc..5f5d4ab3 100644 --- a/src/package-scripts.test.ts +++ b/src/package-scripts.test.ts @@ -7,8 +7,9 @@ const pkg = JSON.parse( ) as { scripts: Record<string, string> }; describe("package.json publish scripts", () => { - test("prepublishOnly uses the same validation gate as check", () => { - expect(pkg.scripts.prepublishOnly).toBe("bun run check"); + test("prepublishOnly uses the same validation gate as check plus pack validation", () => { + expect(pkg.scripts.prepublishOnly).toContain("bun run check"); + expect(pkg.scripts.prepublishOnly).toContain("check:pack"); expect(pkg.scripts.check).toContain("typecheck"); expect(pkg.scripts.check).toContain("test"); expect(pkg.scripts.check).toContain("test:golden"); diff --git a/tsconfig.json b/tsconfig.json index 78712c37..9491c4e6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,12 +12,5 @@ "noUnusedLocals": true, "noUnusedParameters": true }, - "include": [ - "src/**/*.ts", - "tsdown.config.ts", - "scripts/query-golden.ts", - "scripts/query-golden/**/*.ts", - "scripts/qa-external-repo.ts", - "scripts/agent-eval/**/*.ts" - ] + "include": ["src/**/*.ts", "tsdown.config.ts", "scripts/**/*.ts"] } From c89f60aa065b85b23f8fc2168cedba1fb9bddedf Mon Sep 17 00:00:00 2001 From: Sutu Sebastian <sebiitv@gmail.com> Date: Tue, 7 Jul 2026 00:10:43 +0300 Subject: [PATCH 2/6] adopt diagnosing-bugs + teach skills, clean adoption leftover diagnose: fold persist's per-phase "Done when" completion criteria into codemap's stronger skill (one skill, no duplicate). teach: new multi-session learning workspace skill (SKILL + 4 format siblings), adapted for codemap domain; wired into AGENTS.md + ask-agents router. improve-codebase-architecture/REFERENCE: drop stale "(same caveats as persist's REFERENCE)" adoption leftover. --- .agents/skills/ask-agents/SKILL.md | 23 ++--- .agents/skills/diagnose/SKILL.md | 12 +++ .../REFERENCE.md | 2 +- .agents/skills/teach/GLOSSARY-FORMAT.md | 31 +++++++ .../skills/teach/LEARNING-RECORD-FORMAT.md | 34 ++++++++ .agents/skills/teach/MISSION-FORMAT.md | 34 ++++++++ .agents/skills/teach/RESOURCES-FORMAT.md | 40 +++++++++ .agents/skills/teach/SKILL.md | 84 +++++++++++++++++++ .cursor/skills/teach | 1 + AGENTS.md | 2 +- 10 files changed, 250 insertions(+), 13 deletions(-) create mode 100644 .agents/skills/teach/GLOSSARY-FORMAT.md create mode 100644 .agents/skills/teach/LEARNING-RECORD-FORMAT.md create mode 100644 .agents/skills/teach/MISSION-FORMAT.md create mode 100644 .agents/skills/teach/RESOURCES-FORMAT.md create mode 100644 .agents/skills/teach/SKILL.md create mode 120000 .cursor/skills/teach diff --git a/.agents/skills/ask-agents/SKILL.md b/.agents/skills/ask-agents/SKILL.md index 6d0f967f..65bdc121 100644 --- a/.agents/skills/ask-agents/SKILL.md +++ b/.agents/skills/ask-agents/SKILL.md @@ -1,6 +1,6 @@ --- name: ask-agents -description: Which user-only agent workflow to run — grilling, docs-aware grilling, or meta authoring help. +description: Which user-only agent workflow to run — grilling, docs-aware grilling, teaching, or meta authoring help. disable-model-invocation: true --- @@ -33,15 +33,16 @@ Keep grilling + plan authoring in **one window** until issues are filed. Each im ## Standalone -| Invoke | When | -| -------------------------------------------------------------- | ----------------------------------------------- | -| [`grill-me`](../grill-me/SKILL.md) | Sharpen a plan with **no** codebase (stateless) | -| [`writing-great-skills`](../writing-great-skills/SKILL.md) | Skill vocabulary + principles | -| [`writing-agents-config`](../writing-agents-config/SKILL.md) | Codemap repo tier/pairing deltas | -| [`domain-modeling`](../domain-modeling/SKILL.md) | Ubiquitous language inline + batch glossary | -| [`tdd`](../tdd/SKILL.md) | RED→GREEN tracer-bullet TDD | -| [`verify-after-each-step`](../verify-after-each-step/SKILL.md) | Per-file checks after each milestone | -| [`diagnose`](../diagnose/SKILL.md) | Debug loop for hard bugs | -| [`write-a-skill`](../write-a-skill/SKILL.md) | Author a new skill in this repo | +| Invoke | When | +| -------------------------------------------------------------- | ------------------------------------------------------------------------ | +| [`grill-me`](../grill-me/SKILL.md) | Sharpen a plan with **no** codebase (stateless) | +| [`writing-great-skills`](../writing-great-skills/SKILL.md) | Skill vocabulary + principles | +| [`writing-agents-config`](../writing-agents-config/SKILL.md) | Codemap repo tier/pairing deltas | +| [`domain-modeling`](../domain-modeling/SKILL.md) | Ubiquitous language inline + batch glossary | +| [`tdd`](../tdd/SKILL.md) | RED→GREEN tracer-bullet TDD | +| [`verify-after-each-step`](../verify-after-each-step/SKILL.md) | Per-file checks after each milestone | +| [`diagnose`](../diagnose/SKILL.md) | Debug loop for hard bugs | +| [`write-a-skill`](../write-a-skill/SKILL.md) | Author a new skill in this repo | +| [`teach`](../teach/SKILL.md) | Multi-session learning workspace (missions, lessons, retrieval practice) | Meta: [`agents-tier-system`](../agents-tier-system/SKILL.md). diff --git a/.agents/skills/diagnose/SKILL.md b/.agents/skills/diagnose/SKILL.md index 04c62bf0..6166fd6d 100644 --- a/.agents/skills/diagnose/SKILL.md +++ b/.agents/skills/diagnose/SKILL.md @@ -48,6 +48,8 @@ Stop and say so explicitly. List what you tried. Ask the user for: (a) access to Do not proceed to Phase 2 until you have a loop you believe in. +**Done when:** one command is red-capable, deterministic, fast, and agent-runnable (`bun test <file>`, `bun src/index.ts query --json …`, or a throwaway harness). No red-capable command → no Phase 2. + ## Phase 2 — Reproduce Run the loop. Watch the bug appear. @@ -60,6 +62,8 @@ Confirm: Do not proceed until you reproduce the bug. +**Done when:** minimal repro documented; non-load-bearing steps removed; exact symptom captured (error message / wrong output / slow timing) for later fix verification. + ## Phase 3 — Hypothesise Generate **3–5 ranked hypotheses** before testing any of them. Single-hypothesis generation anchors on the first plausible idea. @@ -72,6 +76,8 @@ If you cannot state the prediction, the hypothesis is a vibe — discard or shar **Show the ranked list to the user before testing.** They often have domain knowledge that re-ranks instantly ("we just changed #3"), or know hypotheses they've already ruled out. Cheap checkpoint, big time saver. Don't block on it — proceed with your ranking if the user is AFK. +**Done when:** 3–5 ranked, falsifiable hypotheses stated (each with a prediction); user has seen the list before any fix attempt. + ## Phase 4 — Instrument Each probe must map to a specific prediction from Phase 3. **Change one variable at a time.** @@ -86,6 +92,8 @@ Tool preference: **Perf branch.** For performance regressions, logs are usually wrong. Instead: establish a baseline measurement (timing harness, `performance.now()`, profiler, query plan, `--performance` flag for index runs), then bisect. Measure first, fix second. +**Done when:** one hypothesis confirmed or all falsified with evidence — one variable changed per probe, each probe mapped to a Phase 3 prediction. + ## Phase 5 — Fix + regression test Write the regression test **before the fix** — but only if there is a **correct seam** for it (per the [`improve-codebase-architecture`](../improve-codebase-architecture/SKILL.md) vocabulary). @@ -102,6 +110,8 @@ If a correct seam exists: 4. Watch it pass. 5. Re-run the Phase 1 feedback loop against the original (un-minimised) scenario. +**Done when:** loop is green against the original scenario; regression test added at a correct seam, or the seam-gap is documented as an architectural finding. + ## Phase 6 — Cleanup + post-mortem Required before declaring done: @@ -114,3 +124,5 @@ Required before declaring done: - [ ] If the post-mortem yields a permanent insight, **lift** it into `.agents/rules/` or the relevant skill; append to [`.agents/lessons.md`](../../lessons.md) only when it is not yet encoded elsewhere **Then ask: what would have prevented this bug?** If the answer involves architectural change (no good test seam, tangled callers, hidden coupling) hand off to [`improve-codebase-architecture`](../improve-codebase-architecture/SKILL.md) with the specifics. Make the recommendation **after** the fix is in, not before — you have more information now than when you started. + +**Done when:** no `[DEBUG-…]` sediment (`grep` clean); throwaway harnesses deleted; commit / PR message states the winning root-cause hypothesis; any durable insight lifted into `.agents/rules/` or a skill (else `.agents/lessons.md`). diff --git a/.agents/skills/improve-codebase-architecture/REFERENCE.md b/.agents/skills/improve-codebase-architecture/REFERENCE.md index b1708750..e4f0c5f1 100644 --- a/.agents/skills/improve-codebase-architecture/REFERENCE.md +++ b/.agents/skills/improve-codebase-architecture/REFERENCE.md @@ -71,7 +71,7 @@ When a candidate needs post-merge structural review, fire [`audit-pr-architectur ### oxlint (style + import hygiene) -This repo runs **oxlint** (repo-root `.oxlintrc.json`) for general lint — not as the primary architectural boundary system. Use **`import/no-cycle`** and **`eslint/no-restricted-imports`** when a plan needs directional import bans codified in source (e.g. blocking `application/` → `cli/` value imports). Nested configs must **`extends`** the parent — oxlint does not auto-merge (same caveats as persist's REFERENCE). +This repo runs **oxlint** (repo-root `.oxlintrc.json`) for general lint — not as the primary architectural boundary system. Use **`import/no-cycle`** and **`eslint/no-restricted-imports`** when a plan needs directional import bans codified in source (e.g. blocking `application/` → `cli/` value imports). Nested configs must **`extends`** the parent — oxlint does not auto-merge. Example leaf for an application-layer gate: diff --git a/.agents/skills/teach/GLOSSARY-FORMAT.md b/.agents/skills/teach/GLOSSARY-FORMAT.md new file mode 100644 index 00000000..69b5ebd5 --- /dev/null +++ b/.agents/skills/teach/GLOSSARY-FORMAT.md @@ -0,0 +1,31 @@ +# GLOSSARY.md Format + +Canonical language for the workspace. Lessons and learning records use these terms. + +## Structure + +```md +# {Topic} Glossary + +{Brief scope sentence.} + +## Terms + +**Term**: +One or two sentence definition. +_Avoid_: alias, loose synonym + +**Another term**: +Definition. +_Avoid_: … +``` + +## Rules + +- **Add only when user understands the term** — compressed knowledge, not a dictionary to read ahead. +- **Be opinionated** — pick one canonical term; list avoids. +- **Tight definitions** — what it IS, not how-to. +- **Use glossary terms inside other definitions** once established. +- **Subheadings** when clusters emerge (`## Schema`, `## Recipes`). +- **Flag ambiguities** — "In this workspace, X always means …" +- **Revise in place** as understanding deepens. diff --git a/.agents/skills/teach/LEARNING-RECORD-FORMAT.md b/.agents/skills/teach/LEARNING-RECORD-FORMAT.md new file mode 100644 index 00000000..20aa9ea7 --- /dev/null +++ b/.agents/skills/teach/LEARNING-RECORD-FORMAT.md @@ -0,0 +1,34 @@ +# Learning Record Format + +`./learning-records/0001-slug.md`, incrementing. ADR-shaped — steers zone of proximal development. + +## Template + +```md +# {Short title} + +{1-3 sentences: what was learned or established, and why it changes future sessions.} +``` + +## Optional (when valuable) + +- **Status** — `active | superseded by LR-NNNN` +- **Evidence** — exercise completed, question answered, prior experience cited +- **Implications** — what this unlocks or rules out next + +## When to write + +1. User **demonstrated** understanding (not mere exposure). +2. User disclosed **prior knowledge** — record depth claimed. +3. **Misconception corrected** — high-value for related topics. +4. **Mission shifted** — update `MISSION.md` + cross-link. + +## Not a learning record + +- Material only covered. +- Term definitions → `GLOSSARY.md`. +- Session activity logs. + +## Supersession + +Mark old record `Status: superseded by LR-NNNN` — don't delete history. diff --git a/.agents/skills/teach/MISSION-FORMAT.md b/.agents/skills/teach/MISSION-FORMAT.md new file mode 100644 index 00000000..ecf078cd --- /dev/null +++ b/.agents/skills/teach/MISSION-FORMAT.md @@ -0,0 +1,34 @@ +# MISSION.md Format + +`MISSION.md` lives at the teaching workspace root. It captures the _reason_ the user is learning. Every teaching decision traces back here. + +## Template + +```md +# Mission: {Topic} + +## Why + +{1-3 sentences. Concrete real-world outcome — what changes when they have this skill?} + +## Success looks like + +- {Observable capability} +- {Another observable capability} + +## Constraints + +- {Time, budget, preferences, bounds} + +## Out of scope + +- {Adjacent topics to defer — protects zone of proximal development} +``` + +## Rules + +- **One mission per workspace.** Two unrelated topics → two workspaces. +- **Concrete over abstract.** "Add a new source adapter" beats "learn parsing." +- **Push back on vagueness.** Interview before writing. Bad mission worse than none. +- **Revise when reality shifts.** Update file + learning record; confirm with user. +- **Keep it short.** Past one screen, it's a plan not a compass. diff --git a/.agents/skills/teach/RESOURCES-FORMAT.md b/.agents/skills/teach/RESOURCES-FORMAT.md new file mode 100644 index 00000000..86ed2b96 --- /dev/null +++ b/.agents/skills/teach/RESOURCES-FORMAT.md @@ -0,0 +1,40 @@ +# RESOURCES.md Format + +Curated trusted sources. Draw knowledge from here, not parametric guesses. + +## Structure + +```md +# {Topic} Resources + +## Knowledge + +- [Title — Author](https://example.com) + What it covers; when to reach for it. + +## Repo (codemap) + +- [`.agents/skills/{skill}/SKILL.md`](../../../.agents/skills/{skill}/SKILL.md) + Use for: … +- [`docs/architecture.md`](../../../docs/architecture.md) + Use for: … +- [`docs/glossary.md`](../../../docs/glossary.md) + Use for: … + +## Wisdom (Communities) + +- [Community name](https://example.com) + Use for: … + +## Gaps + +- {Area with no good resource yet — drives future search} +``` + +## Rules + +- **High-trust only.** Primary sources, recognised experts, strong moderation. +- **Annotate every entry** — bare links rot in three months. +- **Group by Knowledge / Repo / Wisdom.** +- **Prune ruthlessly.** Five sharp sources beat thirty mediocre. +- **Record community opt-out** if user declines forums/classes. diff --git a/.agents/skills/teach/SKILL.md b/.agents/skills/teach/SKILL.md new file mode 100644 index 00000000..63259a0e --- /dev/null +++ b/.agents/skills/teach/SKILL.md @@ -0,0 +1,84 @@ +--- +name: teach +description: Structured multi-session teaching — missions, lessons, retrieval practice. +disable-model-invocation: true +argument-hint: "What would you like to learn about?" +--- + +# Teach + +The user wants to **learn something over multiple sessions**. This is stateful — progress lives in files in a **teaching workspace**, not in chat memory alone. + +## Teaching workspace + +**Default location:** `teach/<topic-slug>/` at the repo root (never inside `src/` package code). User may choose another directory — treat **that directory** as the workspace root. + +**Git:** workspaces are **personal by default** — do not commit `teach/**` unless the user explicitly wants shared onboarding material in the repo (add it to `.gitignore` otherwise). + +State files at workspace root: + +| File / folder | Purpose | +| ------------------------- | ---------------------------------------------------------------------------------------------- | +| `MISSION.md` | Why they're learning — grounds every lesson. [MISSION-FORMAT.md](./MISSION-FORMAT.md) | +| `GLOSSARY.md` | Canonical terms once understood. [GLOSSARY-FORMAT.md](./GLOSSARY-FORMAT.md) | +| `RESOURCES.md` | High-trust knowledge + community sources. [RESOURCES-FORMAT.md](./RESOURCES-FORMAT.md) | +| `NOTES.md` | User teaching preferences, scratchpad | +| `./learning-records/*.md` | Decision-grade insights (ADR-shaped). [LEARNING-RECORD-FORMAT.md](./LEARNING-RECORD-FORMAT.md) | +| `./lessons/*.html` | Primary teaching unit — one scoped win per file (`0001-slug.html`, increment) | +| `./reference/*.html` | Compressed cheat sheets for revisit (syntax, flows, glossaries) | +| `./assets/*` | Reusable lesson components (stylesheet first) | + +Create directories lazily when first needed. + +## Codemap repo topics + +When the mission is **this codebase** (index, recipes, schema, parsers, adapters, agents init, rules/skills): + +1. **Explore before lecturing** — query [`codemap`](../codemap/SKILL.md) (the structural SQLite index) for symbol-shaped questions before `Grep`/`Read`; read `src/`, `docs/`, `.agents/` for narrative. +2. **Domain language** — read [`docs/glossary.md`](../../../docs/glossary.md) and [`docs/architecture.md`](../../../docs/architecture.md); align lesson terms (FileRow vs `files` table, recipe vs query, schema vs DDL, hub vs barrel). +3. **Cite symbols and paths** — not line numbers (they drift). Link to `.agents/skills/<name>/SKILL.md` or concrete `src/` paths; use `codemap query` results for symbol references. +4. **RESOURCES.md** — include repo docs ([`AGENTS.md`](../../../AGENTS.md), relevant skills, [`docs/architecture.md`](../../../docs/architecture.md), [`docs/glossary.md`](../../../docs/glossary.md)) alongside external sources. + +General topics (Rust, yoga, etc.): **never trust parametric knowledge** until `RESOURCES.md` is populated. + +## Philosophy + +Three layers: **Knowledge** (trusted resources) · **Skills** (interactive lessons + feedback loops) · **Wisdom** (communities, real-world practice). + +Split **fluency** (in-session recall) vs **storage strength** (long-term retention). Design for storage: retrieval practice, spacing, interleaving (skills only). + +## Lessons + +- One self-contained **HTML** file per lesson — clean, short, one tangible win tied to `MISSION.md`. +- Link to other lessons / reference docs via anchors. +- Cite a primary external resource per lesson when possible. +- End with: ask the agent follow-up questions — you're the teacher. +- Open the lesson file for the user when possible (`open ./lessons/0001-….html` on macOS). + +Before authoring: read `./assets/`; **reuse is default**. Shared stylesheet is the first component every workspace earns — every lesson links it so the course looks consistent. When a lesson needs something reusable (quiz widget, diagram helper), add it to `./assets/` and link — never inline code a second lesson would duplicate. + +## Mission first + +If `MISSION.md` is empty or vague, **interview the user** (one question at a time; recommend an answer) before writing lessons. Revise mission only after user confirms — record shift in a learning record. + +## Zone of proximal development + +Read `learning-records/`, mission, and glossary → teach the next thing that challenges **just enough**. User may name a topic directly. + +## Knowledge vs skills + +Lessons target a **skill**; include only knowledge required for it. Knowledge from `RESOURCES.md` with citations. Skills via quizzes / guided steps with **tight feedback loops**. Quiz options: equal word count when possible (no formatting clues). + +## Wisdom + +For questions needing real-world judgment, answer then point to **communities** in `RESOURCES.md`. Respect if user opts out of communities — note in `RESOURCES.md`. + +## Reference documents + +Compress lesson essence into `./reference/*.html` for revisit. Glossaries live in `GLOSSARY.md` at workspace root — adhere to terms in all lessons. + +## Related skills + +- Interview mission / plan: [`grilling`](../grilling/SKILL.md) +- Project-aware plan + docs: [`grill-with-docs`](../grill-with-docs/SKILL.md) +- Domain terminology: [`domain-modeling`](../domain-modeling/SKILL.md) diff --git a/.cursor/skills/teach b/.cursor/skills/teach new file mode 120000 index 00000000..83977359 --- /dev/null +++ b/.cursor/skills/teach @@ -0,0 +1 @@ +../../.agents/skills/teach \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index efee97cd..12a06126 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,6 +16,6 @@ Canonical read order: [`.agents/rules/agents-first-convention.md`](.agents/rules | PR comments | [`.agents/rules/pr-comment-fact-check.md`](.agents/rules/pr-comment-fact-check.md) | | Plan-PR inspiration | [`.agents/rules/plan-pr-inspiration-discipline.md`](.agents/rules/plan-pr-inspiration-discipline.md) | -Intent (not always-on): `agents-tier-system`, `ask-agents`, `audit-pr-architecture`, `authoring-discipline`, `codemap`, `diagnose`, `docs-governance`, `docs-lifecycle-sweep`, `domain-modeling`, `grill-me`, `grilling`, `grill-with-docs`, `harden-pr`, `improve-codebase-architecture`, `pr-comment-fact-check`, `tdd`, `tracer-bullets`, `verify-after-each-step`, `write-a-skill`, `writing-agents-config`, `writing-great-skills`. +Intent (not always-on): `agents-tier-system`, `ask-agents`, `audit-pr-architecture`, `authoring-discipline`, `codemap`, `diagnose`, `docs-governance`, `docs-lifecycle-sweep`, `domain-modeling`, `grill-me`, `grilling`, `grill-with-docs`, `harden-pr`, `improve-codebase-architecture`, `pr-comment-fact-check`, `tdd`, `teach`, `tracer-bullets`, `verify-after-each-step`, `write-a-skill`, `writing-agents-config`, `writing-great-skills`. Human Day-1: [README](README.md) Getting Started · [`.github/CONTRIBUTING.md`](.github/CONTRIBUTING.md). From d3155c85a7535dd4fa20a934a1a06a0f6890f167 Mon Sep 17 00:00:00 2001 From: Sutu Sebastian <sebiitv@gmail.com> Date: Tue, 7 Jul 2026 10:22:06 +0300 Subject: [PATCH 3/6] remove write-a-skill (superseded by writing-great-skills + writing-agents-config) Drop the skill, its .cursor symlink, and all refs (AGENTS.md intent line, ask-agents router table, consumer-surfaces Related link). --- .agents/rules/consumer-surfaces.md | 2 +- .agents/skills/ask-agents/SKILL.md | 1 - .agents/skills/write-a-skill/SKILL.md | 75 --------------------------- .cursor/skills/write-a-skill | 1 - AGENTS.md | 2 +- 5 files changed, 2 insertions(+), 79 deletions(-) delete mode 100644 .agents/skills/write-a-skill/SKILL.md delete mode 120000 .cursor/skills/write-a-skill diff --git a/.agents/rules/consumer-surfaces.md b/.agents/rules/consumer-surfaces.md index a6e21c24..24f677e6 100644 --- a/.agents/rules/consumer-surfaces.md +++ b/.agents/rules/consumer-surfaces.md @@ -37,4 +37,4 @@ Consumers install **`@stainless-code/codemap`** and interact through CLI, MCP, H Before shipping text on a consumer surface: **“Would a user who only `npm i @stainless-code/codemap` care?”** If no → cut it or move it to a maintainer doc. -Related: [`write-a-skill`](../skills/write-a-skill/SKILL.md) (maintainer vs shipped templates), [`docs-governance`](./docs-governance.md) Rule 10 (agent-content layers). +Related: [`docs-governance`](./docs-governance.md) Rule 10 (agent-content layers). diff --git a/.agents/skills/ask-agents/SKILL.md b/.agents/skills/ask-agents/SKILL.md index 65bdc121..30399a08 100644 --- a/.agents/skills/ask-agents/SKILL.md +++ b/.agents/skills/ask-agents/SKILL.md @@ -42,7 +42,6 @@ Keep grilling + plan authoring in **one window** until issues are filed. Each im | [`tdd`](../tdd/SKILL.md) | RED→GREEN tracer-bullet TDD | | [`verify-after-each-step`](../verify-after-each-step/SKILL.md) | Per-file checks after each milestone | | [`diagnose`](../diagnose/SKILL.md) | Debug loop for hard bugs | -| [`write-a-skill`](../write-a-skill/SKILL.md) | Author a new skill in this repo | | [`teach`](../teach/SKILL.md) | Multi-session learning workspace (missions, lessons, retrieval practice) | Meta: [`agents-tier-system`](../agents-tier-system/SKILL.md). diff --git a/.agents/skills/write-a-skill/SKILL.md b/.agents/skills/write-a-skill/SKILL.md deleted file mode 100644 index 9748e44a..00000000 --- a/.agents/skills/write-a-skill/SKILL.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -name: write-a-skill -description: Create new agent skills with proper structure, progressive disclosure, and bundled resources. Use when user wants to create, write, or build a new skill (or asks "how do I write a skill?", "draft a SKILL.md for X"). ---- - -# Writing skills - -Codemap-specific deltas for authoring `.agents/skills/<name>/SKILL.md`. **Read [`writing-great-skills`](../writing-great-skills/SKILL.md) first** for generic principles — invocation, information hierarchy, progressive disclosure, pruning, leading words, failure modes. - -## Repo conventions you must respect - -These trump anything generic: - -- **File layout** — [`agents-first-convention`](../../rules/agents-first-convention.md): source of truth is `.agents/skills/<name>/SKILL.md`; `.cursor/skills/<name>` is a **symlink** back. Never put original content under `.cursor/`. -- **Tier choice** — [`agents-tier-system`](../../rules/agents-tier-system.md): Tier 1 (always-on + rule), Tier 2 (glob-attached + rule), or Tier 3 (discoverable, no rule). Skills with `NEVER` / `ALWAYS` clauses deserve a rule pairing. Pure intent-trigger skills stay Tier 3. -- **Maintainer-only vs shipped** — `.agents/skills/` is the dev-side mirror; `templates/agents/skills/` is what `codemap agents init` ships. The bundled template surface today is **only** the `codemap` skill — every other skill in `.agents/skills/` is maintainer-only (precedent: PR #25). Don't add to `templates/agents/` unless every npm consumer would want it. Consumer-surface policy: [`.agents/rules/consumer-surfaces.md`](../../rules/consumer-surfaces.md). - -## Process - -### 1. Gather requirements - -Ask the user: - -- What task / domain does the skill cover? -- What specific use cases should it handle? -- Does it need executable scripts (under `scripts/`) or just instructions? -- Any reference materials to include? -- **Tier choice**: always-on principles (`NEVER` / `ALWAYS` clauses)? If yes → Tier-1 or Tier-2 rule pairing per [`agents-tier-system`](../../rules/agents-tier-system.md). - -Use [`grill-me`](../grill-me/SKILL.md) on yourself before drafting — trigger phrase shape, boundary with adjacent skills, durability test (still correct six months from now?). - -### 2. Draft the skill - -Apply [`writing-great-skills`](../writing-great-skills/SKILL.md) for structure, description, disclosure, and split decisions. Codemap precedents for companion files: - -- [`improve-codebase-architecture`](../improve-codebase-architecture/SKILL.md) — `LANGUAGE.md`, `DEEPENING.md`, `INTERFACE-DESIGN.md`, `REFERENCE.md` -- [`pr-comment-fact-check`](../pr-comment-fact-check/SKILL.md) — slim `SKILL.md` + `WORKFLOW.md` (gh/graphql fetch + triage flow split out) -- [`harden-pr`](../harden-pr/SKILL.md) — slim `SKILL.md` + `WORKFLOW.md` + `LEDGER.md` - -### 3. Wire the file layout - -```bash -# Source of truth -.agents/skills/<name>/SKILL.md - -# Cursor symlink (per agents-first-convention) -ln -s ../../.agents/skills/<name> .cursor/skills/<name> -``` - -### 4. Tier placement - -Tiers are discovered on disk via the frontmatter audit (see [`agents-tier-system` skill](../agents-tier-system/SKILL.md)) — there is no name list to update. Just set the new skill's frontmatter correctly: `alwaysApply: true` (Tier 1, needs a rule), `globs:` (Tier 2, needs a rule), or `description:`-only (Tier 3, no rule). - -### 5. Review - -Run the [checklist](#checklist) before declaring done. - -## Durability discipline - -Per [`agents-tier-system` § Authoring discipline: durability](../agents-tier-system/SKILL.md#authoring-discipline-durability): - -- **Don't cite specific audit / plan / research filenames as canonical examples.** Plans are mortal under [`docs-lifecycle-sweep`](../docs-lifecycle-sweep/SKILL.md). Use shape placeholders (`<topic>.md`) instead. -- **Don't cite specific commit hashes or PR numbers as the only path to context.** Summarise inline. -- **Don't cite source-code line numbers.** Reference symbols by name. - -If the skill still reads correctly six months from now after every doc you didn't write got rewritten, it's durable. - -## Checklist - -- [ ] Read [`writing-great-skills`](../writing-great-skills/SKILL.md) — description, hierarchy, disclosure applied -- [ ] File layout follows [`agents-first-convention`](../../rules/agents-first-convention.md) (`.agents/` source + `.cursor/` symlink) -- [ ] Tier choice documented per [`agents-tier-system`](../../rules/agents-tier-system.md); rule pairing if `NEVER` / `ALWAYS` clauses -- [ ] Frontmatter tier mode set correctly (`alwaysApply` / `globs` / `description`-only) — discoverable via the `agents-tier-system` audit -- [ ] Decision recorded in the PR description: maintainer-only (`.agents/` only) vs shipped (`templates/agents/` too) -- [ ] No time-sensitive info; durable citations only (see [Durability discipline](#durability-discipline)) diff --git a/.cursor/skills/write-a-skill b/.cursor/skills/write-a-skill deleted file mode 120000 index 8e09e460..00000000 --- a/.cursor/skills/write-a-skill +++ /dev/null @@ -1 +0,0 @@ -../../.agents/skills/write-a-skill \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 12a06126..9f7b24bc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,6 +16,6 @@ Canonical read order: [`.agents/rules/agents-first-convention.md`](.agents/rules | PR comments | [`.agents/rules/pr-comment-fact-check.md`](.agents/rules/pr-comment-fact-check.md) | | Plan-PR inspiration | [`.agents/rules/plan-pr-inspiration-discipline.md`](.agents/rules/plan-pr-inspiration-discipline.md) | -Intent (not always-on): `agents-tier-system`, `ask-agents`, `audit-pr-architecture`, `authoring-discipline`, `codemap`, `diagnose`, `docs-governance`, `docs-lifecycle-sweep`, `domain-modeling`, `grill-me`, `grilling`, `grill-with-docs`, `harden-pr`, `improve-codebase-architecture`, `pr-comment-fact-check`, `tdd`, `teach`, `tracer-bullets`, `verify-after-each-step`, `write-a-skill`, `writing-agents-config`, `writing-great-skills`. +Intent (not always-on): `agents-tier-system`, `ask-agents`, `audit-pr-architecture`, `authoring-discipline`, `codemap`, `diagnose`, `docs-governance`, `docs-lifecycle-sweep`, `domain-modeling`, `grill-me`, `grilling`, `grill-with-docs`, `harden-pr`, `improve-codebase-architecture`, `pr-comment-fact-check`, `tdd`, `teach`, `tracer-bullets`, `verify-after-each-step`, `writing-agents-config`, `writing-great-skills`. Human Day-1: [README](README.md) Getting Started · [`.github/CONTRIBUTING.md`](.github/CONTRIBUTING.md). From b8f39b1cb1105bbc20c34080b6dfc5c6ae740573 Mon Sep 17 00:00:00 2001 From: Sutu Sebastian <sebiitv@gmail.com> Date: Tue, 7 Jul 2026 11:03:03 +0300 Subject: [PATCH 4/6] =?UTF-8?q?adopt=20.agents/README.md=20hub;=20rename?= =?UTF-8?q?=20diagnose=20=E2=86=92=20diagnosing-bugs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit README: add .agents/README.md (adapted from persist) as the in-.agents hub; wire agents-tier-system skill + AGENTS.md to point at it. diagnose: update skill to mattpocock/skills diagnosing-bugs structure (Phase 1 red-capable completion criterion, Phase 2 minimise), then rename the skill dir diagnose → diagnosing-bugs (frontmatter name, H1, .cursor symlink, and all citations in AGENTS.md, ask-agents, writing-agents-config, architecture-priming). --- .agents/README.md | 42 +++++++++++++++++++ .agents/rules/architecture-priming.md | 2 +- .agents/skills/agents-tier-system/SKILL.md | 2 +- .agents/skills/ask-agents/SKILL.md | 4 +- .../{diagnose => diagnosing-bugs}/SKILL.md | 25 ++++++++--- .../scripts/hitl-loop.template.sh | 0 .agents/skills/writing-agents-config/SKILL.md | 2 +- .cursor/skills/diagnose | 1 - .cursor/skills/diagnosing-bugs | 1 + AGENTS.md | 4 +- 10 files changed, 70 insertions(+), 13 deletions(-) create mode 100644 .agents/README.md rename .agents/skills/{diagnose => diagnosing-bugs}/SKILL.md (83%) rename .agents/skills/{diagnose => diagnosing-bugs}/scripts/hitl-loop.template.sh (100%) delete mode 120000 .cursor/skills/diagnose create mode 120000 .cursor/skills/diagnosing-bugs diff --git a/.agents/README.md b/.agents/README.md new file mode 100644 index 00000000..b5b11c3e --- /dev/null +++ b/.agents/README.md @@ -0,0 +1,42 @@ +# `.agents/` — rules & skills + +Source of truth for AI agent configuration. Cursor consumes via symlinks in `.cursor/rules/` and `.cursor/skills/`. + +## Start here + +| Question | Read | +| --------------------------------- | --------------------------------------------------------------------- | +| Repo-root stub (cross-tool) | [`AGENTS.md`](../AGENTS.md) | +| Where files live, symlinks | [rules/agents-first-convention.md](rules/agents-first-convention.md) | +| Tier 1 / 2 / 3 attachment modes | [rules/agents-tier-system.md](rules/agents-tier-system.md) | +| Codemap tier/pairing deltas | [skills/writing-agents-config](skills/writing-agents-config/SKILL.md) | +| Authoring new rules/skills (meta) | [`writing-great-skills`](skills/writing-great-skills/SKILL.md) | +| Past corrections | [`lessons.md`](lessons.md) | +| What exists on disk right now | `ls .agents/rules` · `ls .agents/skills` | + +## Tier legend (summary) + +| Tier | Attachment | Cost | +| ----- | --------------------- | ------------------------------ | +| **1** | `alwaysApply: true` | Every turn | +| **2** | `globs:` | When matching files in scope | +| **3** | `description:` intent | When user/agent intent matches | + +## Inventory + +Discover on disk via `ls` + the frontmatter audit in [`agents-tier-system`](rules/agents-tier-system.md) — no hardcoded name lists. + +## Conventions + +- **`-priming` suffix** when a Tier-2 rule filename ≠ skill folder name (`architecture-priming` ↔ `improve-codebase-architecture` + `audit-pr-architecture`). Same-name pairings skip the suffix (`docs-governance` rule ↔ `docs-governance` + `docs-lifecycle-sweep` skills). +- **No `AGENTS.md` in skill folders** — use `FULL-GUIDE.md` or topic siblings (`WORKFLOW.md`, `REFERENCE.md`, `LIFECYCLE.md`, `LANGUAGE.md`, `PROSE.md`, `GLOSSARY.md`) for bulk reference. Repo root `AGENTS.md` is a thin stub only. +- **Thin rules** (~10–40 lines); depth in `SKILL.md` or siblings. + +## Layout + +```text +.agents/ + rules/<name>.md → .cursor/rules/<name>.mdc (symlink) + skills/<name>/SKILL.md → .cursor/skills/<name> (symlink) + lessons.md → .cursor/rules/lessons.mdc (symlink) +``` diff --git a/.agents/rules/architecture-priming.md b/.agents/rules/architecture-priming.md index 0ff2bd40..2c1b132d 100644 --- a/.agents/rules/architecture-priming.md +++ b/.agents/rules/architecture-priming.md @@ -19,7 +19,7 @@ For each signal: STOP and run [`improve-codebase-architecture`](../skills/improv ## Otherwise, proceed normally -Line-level changes **do not trigger this rule**. Use intent-triggered skills (`harden-pr`, `diagnose`, etc.). +Line-level changes **do not trigger this rule**. Use intent-triggered skills (`harden-pr`, `diagnosing-bugs`, etc.). ## Reference diff --git a/.agents/skills/agents-tier-system/SKILL.md b/.agents/skills/agents-tier-system/SKILL.md index d0d51e44..fef1082f 100644 --- a/.agents/skills/agents-tier-system/SKILL.md +++ b/.agents/skills/agents-tier-system/SKILL.md @@ -5,7 +5,7 @@ description: Full tier assignments, pairing conventions, and authoring checklist # `.agents/` tier system — full reference -Always-on priming: [`.agents/rules/agents-tier-system.md`](../../rules/agents-tier-system.md). Entry points: [`AGENTS.md`](../../../AGENTS.md), [`agents-first-convention`](../../rules/agents-first-convention.md), [`writing-agents-config`](../writing-agents-config/SKILL.md). +Always-on priming: [`.agents/rules/agents-tier-system.md`](../../rules/agents-tier-system.md). Entry points: [`.agents/README.md`](../../README.md) (hub), [`AGENTS.md`](../../../AGENTS.md) (cross-tool stub), [`agents-first-convention`](../../rules/agents-first-convention.md), [`writing-agents-config`](../writing-agents-config/SKILL.md). ## Discover on disk (do not maintain partial catalogs here) diff --git a/.agents/skills/ask-agents/SKILL.md b/.agents/skills/ask-agents/SKILL.md index 30399a08..decd6991 100644 --- a/.agents/skills/ask-agents/SKILL.md +++ b/.agents/skills/ask-agents/SKILL.md @@ -23,7 +23,7 @@ Keep grilling + plan authoring in **one window** until issues are filed. Each im ## Codebase health (not feature work) - **`/improve-codebase-architecture`** — surface deepening opportunities; pick one → back to main flow at grill-with-docs. -- **`/diagnose`** — hard bugs and perf regressions (model-invoked skill — not a router target). +- **`/diagnosing-bugs`** — hard bugs and perf regressions (model-invoked skill — not a router target). - Periodic hygiene: **`/docs-lifecycle-sweep`** on `docs/` (model-invoked). ## Crossing sessions @@ -41,7 +41,7 @@ Keep grilling + plan authoring in **one window** until issues are filed. Each im | [`domain-modeling`](../domain-modeling/SKILL.md) | Ubiquitous language inline + batch glossary | | [`tdd`](../tdd/SKILL.md) | RED→GREEN tracer-bullet TDD | | [`verify-after-each-step`](../verify-after-each-step/SKILL.md) | Per-file checks after each milestone | -| [`diagnose`](../diagnose/SKILL.md) | Debug loop for hard bugs | +| [`diagnosing-bugs`](../diagnosing-bugs/SKILL.md) | Debug loop for hard bugs | | [`teach`](../teach/SKILL.md) | Multi-session learning workspace (missions, lessons, retrieval practice) | Meta: [`agents-tier-system`](../agents-tier-system/SKILL.md). diff --git a/.agents/skills/diagnose/SKILL.md b/.agents/skills/diagnosing-bugs/SKILL.md similarity index 83% rename from .agents/skills/diagnose/SKILL.md rename to .agents/skills/diagnosing-bugs/SKILL.md index 6166fd6d..8b7c1bba 100644 --- a/.agents/skills/diagnose/SKILL.md +++ b/.agents/skills/diagnosing-bugs/SKILL.md @@ -1,9 +1,9 @@ --- -name: diagnose +name: diagnosing-bugs description: Disciplined diagnosis loop for hard bugs and performance regressions. Reproduce → minimise → hypothesise → instrument → fix → regression-test. Use when user says "diagnose this" / "debug this", reports a bug, says something is broken/throwing/failing, or describes a performance regression. --- -# Diagnose +# Diagnosing bugs A discipline for hard bugs. Skip phases only when explicitly justified. @@ -46,9 +46,16 @@ The goal is not a clean repro but a **higher reproduction rate**. Loop the trigg Stop and say so explicitly. List what you tried. Ask the user for: (a) access to whatever environment reproduces it, (b) a captured artifact (HAR file, log dump, core dump, screen recording with timestamps, broken `.codemap/index.db`), or (c) permission to add temporary instrumentation. Do **not** proceed to hypothesise without a loop. -Do not proceed to Phase 2 until you have a loop you believe in. +### Completion criterion — a tight loop that goes red -**Done when:** one command is red-capable, deterministic, fast, and agent-runnable (`bun test <file>`, `bun src/index.ts query --json …`, or a throwaway harness). No red-capable command → no Phase 2. +Phase 1 is done when the loop is **tight** and **red-capable**: you can name **one command** — a test invocation (`bun test <file>`), `bun src/index.ts query --json …`, a throwaway harness, or [`scripts/hitl-loop.template.sh`](scripts/hitl-loop.template.sh) for the human-in-the-loop case — that you have **already run at least once** (paste the invocation and its output), and that is: + +- [ ] **Red-capable** — it drives the actual bug code path and asserts the **user's exact symptom**, so it can go red on this bug and green once fixed. Not "runs without erroring" — it must be able to _catch this specific bug_. +- [ ] **Deterministic** — same verdict every run (flaky bugs: a pinned, high reproduction rate, per above). +- [ ] **Fast** — seconds, not minutes. +- [ ] **Agent-runnable** — you can run it unattended; a human in the loop only via `scripts/hitl-loop.template.sh`. + +If you catch yourself reading code to build a theory before this command exists, **stop — jumping straight to a hypothesis is the exact failure this skill prevents.** No red-capable command, no Phase 2. ## Phase 2 — Reproduce @@ -60,9 +67,15 @@ Confirm: - [ ] The failure is reproducible across multiple runs (or, for non-deterministic bugs, reproducible at a high enough rate to debug against). - [ ] You have captured the exact symptom (error message, wrong output, slow timing) so later phases can verify the fix actually addresses it. -Do not proceed until you reproduce the bug. +### Minimise + +Once it's red, shrink the repro to the **smallest scenario that still goes red**. Cut inputs, callers, config, data, and steps **one at a time**, re-running the loop after each cut — keep only what's load-bearing for the failure. + +Why bother: a minimal repro shrinks the hypothesis space in Phase 3 (fewer moving parts left to suspect) and becomes the clean regression test in Phase 5. + +**Done when** every remaining element is load-bearing — removing any one of them makes the loop go green. -**Done when:** minimal repro documented; non-load-bearing steps removed; exact symptom captured (error message / wrong output / slow timing) for later fix verification. +Do not proceed until you have reproduced **and** minimised. ## Phase 3 — Hypothesise diff --git a/.agents/skills/diagnose/scripts/hitl-loop.template.sh b/.agents/skills/diagnosing-bugs/scripts/hitl-loop.template.sh similarity index 100% rename from .agents/skills/diagnose/scripts/hitl-loop.template.sh rename to .agents/skills/diagnosing-bugs/scripts/hitl-loop.template.sh diff --git a/.agents/skills/writing-agents-config/SKILL.md b/.agents/skills/writing-agents-config/SKILL.md index 251777c6..d3c7912a 100644 --- a/.agents/skills/writing-agents-config/SKILL.md +++ b/.agents/skills/writing-agents-config/SKILL.md @@ -60,7 +60,7 @@ find .agents/skills -name SKILL.md -exec sh -c 'n=$(wc -l < "$1"); [ "$n" -gt 12 ## Codemap-specific tradeoffs - **Tier-2 attach** — `agents-tier-system` (`agents/**` + `cursor/**`); `docs-governance` (`docs/**`, `.agents/**`); `architecture-priming` when authoring structural refactors. -- **Intent-only skills** — `improve-codebase-architecture`, `domain-modeling`, `docs-lifecycle-sweep`, `diagnose`, `tdd`, `pr-comment-fact-check`, `harden-pr`, `codemap`, `audit-pr-architecture`. No glob (no per-file tax). +- **Intent-only skills** — `improve-codebase-architecture`, `domain-modeling`, `docs-lifecycle-sweep`, `diagnosing-bugs`, `tdd`, `pr-comment-fact-check`, `harden-pr`, `codemap`, `audit-pr-architecture`. No glob (no per-file tax). - **Ship policy** — `templates/agent-content/**` is served live (CLI/MCP/HTTP); `templates/agents/**` is copied by `codemap agents init`. Consumer surfaces describe behavior only ([`consumer-surfaces`](../../rules/consumer-surfaces.md)). - **Symlink convention** — source under `.agents/`; `.cursor/rules/<name>.mdc` and `.cursor/skills/<name>` are symlinks only. - **Cross-skill links** — relative `../skill/SKILL.md` and sibling files resolve reliably in Cursor agents. Relative links inside `.agents/` are an **intentional delta**, not drift. diff --git a/.cursor/skills/diagnose b/.cursor/skills/diagnose deleted file mode 120000 index 7d4b7c9e..00000000 --- a/.cursor/skills/diagnose +++ /dev/null @@ -1 +0,0 @@ -../../.agents/skills/diagnose \ No newline at end of file diff --git a/.cursor/skills/diagnosing-bugs b/.cursor/skills/diagnosing-bugs new file mode 120000 index 00000000..b2134fff --- /dev/null +++ b/.cursor/skills/diagnosing-bugs @@ -0,0 +1 @@ +../../.agents/skills/diagnosing-bugs \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 9f7b24bc..d98e3b16 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,5 +1,7 @@ # Agent instructions +Full `.agents/` hub: [`.agents/README.md`](.agents/README.md). + Canonical read order: [`.agents/rules/agents-first-convention.md`](.agents/rules/agents-first-convention.md) · [`.agents/rules/agents-tier-system.md`](.agents/rules/agents-tier-system.md) (START HERE). | Topic | Link | @@ -16,6 +18,6 @@ Canonical read order: [`.agents/rules/agents-first-convention.md`](.agents/rules | PR comments | [`.agents/rules/pr-comment-fact-check.md`](.agents/rules/pr-comment-fact-check.md) | | Plan-PR inspiration | [`.agents/rules/plan-pr-inspiration-discipline.md`](.agents/rules/plan-pr-inspiration-discipline.md) | -Intent (not always-on): `agents-tier-system`, `ask-agents`, `audit-pr-architecture`, `authoring-discipline`, `codemap`, `diagnose`, `docs-governance`, `docs-lifecycle-sweep`, `domain-modeling`, `grill-me`, `grilling`, `grill-with-docs`, `harden-pr`, `improve-codebase-architecture`, `pr-comment-fact-check`, `tdd`, `teach`, `tracer-bullets`, `verify-after-each-step`, `writing-agents-config`, `writing-great-skills`. +Intent (not always-on): `agents-tier-system`, `ask-agents`, `audit-pr-architecture`, `authoring-discipline`, `codemap`, `diagnosing-bugs`, `docs-governance`, `docs-lifecycle-sweep`, `domain-modeling`, `grill-me`, `grilling`, `grill-with-docs`, `harden-pr`, `improve-codebase-architecture`, `pr-comment-fact-check`, `tdd`, `teach`, `tracer-bullets`, `verify-after-each-step`, `writing-agents-config`, `writing-great-skills`. Human Day-1: [README](README.md) Getting Started · [`.github/CONTRIBUTING.md`](.github/CONTRIBUTING.md). From 21c4669caf4382ce846ba3ab5481210044479933 Mon Sep 17 00:00:00 2001 From: Sutu Sebastian <sebiitv@gmail.com> Date: Tue, 7 Jul 2026 11:13:58 +0300 Subject: [PATCH 5/6] consumer-surfaces: cover public-API JSDoc/.d.mts surface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the library import surface (.d.mts/JSDoc on exports) to the consumer surface table + intro, and an editing rule that @example imports must resolve against exports (prose depth + no-internals defer to authoring-discipline § PROSE + existing items, no duplication). --- .agents/rules/consumer-surfaces.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.agents/rules/consumer-surfaces.md b/.agents/rules/consumer-surfaces.md index 24f677e6..ba7c698e 100644 --- a/.agents/rules/consumer-surfaces.md +++ b/.agents/rules/consumer-surfaces.md @@ -5,17 +5,18 @@ alwaysApply: true # Consumer surfaces -Consumers install **`@stainless-code/codemap`** and interact through CLI, MCP, HTTP, and bundled agent templates. They must only see **what to run** and **what it does** — never how this repo implements it. +Consumers install **`@stainless-code/codemap`** and interact through CLI, MCP, HTTP, the library `import` surface (`.` export), and bundled agent templates. They must only see **what to run** and **what it does** — never how this repo implements it. ## Consumer surfaces (write for users) -| Surface | Audience | -| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -| `templates/agent-content/**` | Served live via `codemap skill` / `codemap rule`, `codemap://skill` / `codemap://rule`, MCP `instructions`, HTTP resources | -| `templates/agents/**` | Copied into consumer projects by `codemap agents init` | -| **`.changeset/*.md` body** | Release notes → `CHANGELOG.md` on npm | -| **Root `README.md` (install / usage)** | npm landing page | -| **CLI help text and user-facing errors** | Terminal output | +| Surface | Audience | +| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | +| `templates/agent-content/**` | Served live via `codemap skill` / `codemap rule`, `codemap://skill` / `codemap://rule`, MCP `instructions`, HTTP resources | +| `templates/agents/**` | Copied into consumer projects by `codemap agents init` | +| **`.changeset/*.md` body** | Release notes → `CHANGELOG.md` on npm | +| **Root `README.md` (install / usage)** | npm landing page | +| **CLI help text and user-facing errors** | Terminal output | +| **Public API `.d.mts` / JSDoc on exports** | IDE hovers + type previews for `import` consumers | `docs/agents.md` is maintainer reference linked from bundled README — keep **MCP wiring / init** sections consumer-accurate; implementation tables belong in maintainer sections, not in served agent-content. @@ -32,6 +33,7 @@ Consumers install **`@stainless-code/codemap`** and interact through CLI, MCP, H 2. **Changesets** — user-visible outcome only; no Action refactors, detect-pm delegation, or sync comments between source files. 3. **Served skill / rule** — no hardcoded `{command: "codemap"}` unless documenting legacy manual wiring; prefer `codemap agents init --mcp` and PM-specific examples (`npx`, `pnpm exec`, `yarn exec`, `bunx`, dlx). 4. **Cross-ref maintainer detail** — plans, architecture internals, and contributor tables stay in `docs/` or `.agents/` skills; link from consumer text only when the user must follow a public doc (e.g. [agents.md § MCP wiring](https://github.com/stainless-code/codemap/blob/main/docs/agents.md#mcp-wiring-via-agents-init)). +5. **JSDoc on exports** — `@example` imports must resolve against `exports`; the rest (behavior-not-implementation, no `src/` paths, prose depth) follows item 1, the maintainer-only list, and [`authoring-discipline`](./authoring-discipline.md) § PROSE. ## Decision test From 5c79e9c31ed471888fa2f8c788082bab0bfd2275 Mon Sep 17 00:00:00 2001 From: Sutu Sebastian <sebiitv@gmail.com> Date: Tue, 7 Jul 2026 11:20:52 +0300 Subject: [PATCH 6/6] add changeset for trusted publishing + provenance + sideEffects --- .changeset/trusted-publishing-provenance.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/trusted-publishing-provenance.md diff --git a/.changeset/trusted-publishing-provenance.md b/.changeset/trusted-publishing-provenance.md new file mode 100644 index 00000000..a20e759b --- /dev/null +++ b/.changeset/trusted-publishing-provenance.md @@ -0,0 +1,5 @@ +--- +"@stainless-code/codemap": patch +--- + +Publish to npm via trusted publishing (GitHub OIDC) with Sigstore provenance, so released tarballs are verifiably built from this repo. Mark the library `.` export as side-effect-free for bundler tree-shaking.