baldart 4.40.0 → 4.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +6 -2
- package/VERSION +1 -1
- package/framework/.claude/agents/coder.md +4 -2
- package/framework/.claude/agents/qa-sentinel.md +10 -1
- package/framework/.claude/commands/qa.md +2 -0
- package/framework/.claude/skills/toolchain-bootstrap/SKILL.md +127 -0
- package/framework/.claude/workflows/new-card-review.js +17 -2
- package/framework/.claude/workflows/new2.js +3 -0
- package/framework/agents/index.md +2 -0
- package/framework/agents/toolchain-protocol.md +80 -0
- package/framework/docs/TOOLCHAIN-LAYER.md +135 -0
- package/framework/templates/baldart.config.template.yml +40 -0
- package/package.json +1 -1
- package/src/commands/configure.js +81 -0
- package/src/commands/doctor.js +67 -0
- package/src/commands/update.js +12 -0
- package/src/utils/tool-currency.js +52 -0
- package/src/utils/toolchain-adapters/biome.js +92 -0
- package/src/utils/toolchain-adapters/eslint.js +39 -0
- package/src/utils/toolchain-adapters/husky.js +30 -0
- package/src/utils/toolchain-adapters/index.js +83 -0
- package/src/utils/toolchain-adapters/jest.js +34 -0
- package/src/utils/toolchain-adapters/lefthook.js +84 -0
- package/src/utils/toolchain-adapters/prettier.js +39 -0
- package/src/utils/toolchain-adapters/tsc.js +50 -0
- package/src/utils/toolchain-adapters/vitest.js +46 -0
- package/src/utils/toolchain-installer.js +233 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ All notable changes to BALDART will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [4.41.0] - 2026-06-15
|
|
9
|
+
|
|
10
|
+
**BALDART becomes opinionated about the *tools*, not just the workflow: a new curated toolchain layer installs best-in-class JS/TS dev tools at first install and makes the agents actually use them.** Until now BALDART shipped agents and workflows but was agnostic about linters/formatters/test-runners — every quality gate hard-coded `eslint`/`tsc`/`jest`. This release adds an opt-in toolchain layer (`features.has_toolchain`) that, on a JS/TS project, PRESELECTS and installs a curated set as devDependencies — **Biome** (format + lint + import organizer), **Vitest**, **tsc**, **Lefthook** (pre-commit) — then records literal gate commands in `toolchain.commands.*` that the gate flows (`/new`, `/new2`, `/qa`, `qa-sentinel`, `coder`) run verbatim instead of guessing. The design is the fourth member of the install-adapter family (alongside routine-/tool-/lsp-adapters) and inherits their invariants: **opinionated but askable** (default Y, opt-out), **non-destructive** (configs written only when absent; existing ESLint/Prettier/Jest/husky are detected and a migration is only ever PROPOSED, never automatic — `.husky/` is never overwritten), **never silent in CI** (`--non-interactive` writes the flag only; `baldart doctor` backfills), and **silent fallback** (an unset command degrades to the project-standard default; the layer is invisible to non-JS projects and consumers with their own toolchain). **MINOR** (additive capability + new `features.has_toolchain` + `toolchain.*` config keys, propagated end-to-end per the schema-change propagation rule; backwards-compatible — flag defaults `false`, every gate falls back to today's behavior when unset).
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`src/utils/toolchain-adapters/`** — new adapter family (same dispatcher pattern as `lsp-adapters/`). Curated installers `biome.js` / `vitest.js` / `tsc.js` / `lefthook.js` (each: `installCommand`/`verifyCommand`/`commands()`/`initConfig`/`static replaces`/`static detect`) + incumbent **detectors** `eslint.js` / `prettier.js` / `jest.js` / `husky.js` (detection-only, drive the migration proposal). `index.js` exposes `REGISTRY` + `INCUMBENTS` + `detectAll` + `detectIncumbents`.
|
|
15
|
+
- **`src/utils/toolchain-installer.js`** — orchestrator (modeled on `graphify-installer.js`): `recommend()` (clean installs), `migrations()` (incumbent-blocked tools → manual migration), `install()` (devDeps; writes a tool's config BEFORE the package's own postinstall so Lefthook registers our Biome pre-commit, not its commented-out example), `initConfigs()` (non-destructive), `commandsFor()`, `activeTools()`, `certify()`. Never throws.
|
|
16
|
+
- **`framework/agents/toolchain-protocol.md`** — runtime protocol: per-gate resolution (explicit `toolchain.commands.*` → project-standard fallback → skip), the command map, and the rule that a configured command which FAILS is a real failure (fallback applies only to *unset* commands). Routed from `framework/agents/index.md`.
|
|
17
|
+
- **`framework/docs/TOOLCHAIN-LAYER.md`** — operator guide (plumbing, lifecycle, edge cases, how to add a language/tool).
|
|
18
|
+
- **`framework/.claude/skills/toolchain-bootstrap/SKILL.md`** — explicit install path (`/toolchain-bootstrap`), CI-safe; mirrors `/lsp-bootstrap`.
|
|
19
|
+
- **`framework/templates/baldart.config.template.yml`** — `features.has_toolchain` + the `toolchain:` block (`installed_tools`, `commands.{lint,format,typecheck,test,test_related,build,audit}`, `auto_verify`).
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **`src/commands/configure.js`** — autodetects the prompt default (JS/TS project AND no incumbent → Y), and on enable runs the install/migrate/write/certify flow (clean set preselected; incumbents → migration proposal, never automatic).
|
|
24
|
+
- **`src/commands/update.js`** — the schema-drift detector now diffs the `toolchain:` block including its nested `commands.*` map (same nested-block contract as `graph:`), so a future gate key surfaces for pre-existing consumers.
|
|
25
|
+
- **`src/commands/doctor.js`** — backfill actions `toolchain-install` (devDeps missing) and `toolchain-init-config` (default config missing), gated on `features.has_toolchain`, never blocking.
|
|
26
|
+
- **`src/utils/tool-currency.js`** — `_toolchainRecords` reports curated devDeps behind their npm `latest` (installed version read from `node_modules`, not a global binary); `autoUpgradable:false` (devDep upgrades touch `package.json` — surfaced as a command, user-run). Honest `unknown` offline.
|
|
27
|
+
- **Consumers wired to read `toolchain.commands.*` with silent fallback** — `framework/.claude/agents/qa-sentinel.md`, `framework/.claude/agents/coder.md`, `framework/.claude/commands/qa.md`, `framework/.claude/workflows/new-card-review.js` (post-fix re-verify + qa gate brief), `framework/.claude/workflows/new2.js` (pre-flight baseline config facts).
|
|
28
|
+
|
|
8
29
|
## [4.40.0] - 2026-06-15
|
|
9
30
|
|
|
10
31
|
**The classic `/new` now slims its single-card final review the same way `new2` already does — closing an asymmetry that made an N=1 batch re-run review finders it had already run.** `new-final-review.js` has carried an F-041 single-card slim since v4.17.x (keep the unique-value cross-model Codex pass + the qa-sentinel merge gate; drop the duplicate Claude breadth finders that already ran per-card), but it only ever fired for **`new2`**, which passes `singleCard`. The classic `/new` final-review delegation (`final-review.md` Step F.1.5) **never passed the flag**, so `slim` was always false and a one-card `/new` batch ran the full breadth set in the final review even though the per-card pass had already covered the same files — a duplicate cross-model Codex + redundant doc review on every single-card run. The user's framing ("for one card, skip the per-card review") was the wrong lever (it would drop Simplify, break the fail-fast ordering that runs review *before* E2E + doc-sync, and lose the early security pass — and was already litigated: v3.35.0 introduced an N=1 final-review skip, v3.37.0 reverted it precisely because the per-card pass can run shallow under `light`). The right lever, already chosen for `new2`, is the inverse: keep the per-card pass, slim the *final*. This release extends that slim to classic `/new` — but **per-finder, coverage-gated**, because classic `/new` differs from `new2`: its `doc-reviewer` runs in the skill's Phase 3 (and can defer to Final under `light`), and its `api-perf-cost-auditor` is deferred-to-final *by design* (never runs per-card). **MINOR** (changes the N=1 merge-gate composition; no new surface, no `baldart.config.yml` key — `singleCard`/`slimDoc`/`slimApi` are workflow args ⇒ schema-propagation rule N/A).
|
package/README.md
CHANGED
|
@@ -208,13 +208,13 @@ Skills always-ask when required keys are missing — never silently default.
|
|
|
208
208
|
never overwrites your file. Full guide:
|
|
209
209
|
[`framework/docs/PROJECT-CONFIGURATION.md`](framework/docs/PROJECT-CONFIGURATION.md).
|
|
210
210
|
|
|
211
|
-
### Skills (
|
|
211
|
+
### Skills (33 portable skills)
|
|
212
212
|
|
|
213
213
|
Skills live under `.claude/skills/` and are auto-discovered by Claude Code.
|
|
214
214
|
Bundled skills:
|
|
215
215
|
|
|
216
216
|
- **Workflow**: `new`, `new2` (v4.16.0 — EXPERIMENTAL workflow-hosted `/new`, Claude-only, for A/B testing context economy), `prd`, `prd-add`, `bug`, `simplify`, `worktree-manager`, `issue-review`, `context-primer`
|
|
217
|
-
- **Code quality**: `skill-creator`, `find-skills`, `webapp-testing`, `playwright-skill`, `lsp-bootstrap` (v3.10.0), `graphify-bootstrap` (v4.21.0 — code knowledge graph), `graph-align` (v4.21.0 — doc↔graph alignment), `e2e-review` (v3.18.0)
|
|
217
|
+
- **Code quality**: `skill-creator`, `find-skills`, `webapp-testing`, `playwright-skill`, `lsp-bootstrap` (v3.10.0), `graphify-bootstrap` (v4.21.0 — code knowledge graph), `graph-align` (v4.21.0 — doc↔graph alignment), `toolchain-bootstrap` (v4.41.0 — curated dev toolchain), `e2e-review` (v3.18.0)
|
|
218
218
|
- **Design**: `frontend-design`, `ui-design`, `motion-design`, `gamification-design`, `design-system-init` (v3.11.0)
|
|
219
219
|
- **Product**: `seo-audit`, `copywriting`, `api-design-principles`
|
|
220
220
|
- **Knowledge**: `doc-writing-for-rag`, `capture` (LLM wiki overlay)
|
|
@@ -245,6 +245,10 @@ When `features.has_lsp_layer: true`, `codebase-architect` and the code-explorati
|
|
|
245
245
|
|
|
246
246
|
When `features.has_code_graph: true`, agents prefer the [Graphify](https://github.com/safishamsi/graphify) code knowledge graph (tree-sitter, local/offline, native Leiden communities) for **structural / relational** queries — "what connects X to Y", blast-radius of a change, which modules cluster — via `graphify query`/`path`/`explain`/`affected`. The same graph **re-activates the LLM-wiki auto-learning loop** (dormant since the RAG removal in v4.20.0): `wiki-curator`, `/capture`, and the nightly `doc-graph-align` routine feed synthesis candidates from Graphify's native `GRAPH_REPORT.md` (god nodes, communities, suggested questions) — entirely offline. Graphify is a single language-agnostic tool (`pipx install graphifyy`); install via `baldart configure` or `/graphify-bootstrap` (never silent in CI — `baldart doctor` backfills). Falls back silently to LSP→Grep→Git. See [`framework/agents/code-graph-protocol.md`](framework/agents/code-graph-protocol.md) and [`framework/docs/CODE-GRAPH-LAYER.md`](framework/docs/CODE-GRAPH-LAYER.md).
|
|
247
247
|
|
|
248
|
+
### Curated Toolchain Layer (new in v4.41.0)
|
|
249
|
+
|
|
250
|
+
When `features.has_toolchain: true`, BALDART becomes opinionated about the *tools* you build with, not just the workflow. On a JS/TS project `baldart configure` PRESELECTS and installs a curated set as devDependencies — **Biome** (format + lint + import organizer), **Vitest**, **tsc**, **Lefthook** (pre-commit) — and records literal gate commands in `toolchain.commands.*`. The quality-gate flows (`/new`, `/new2`, `/qa`, `qa-sentinel`, `coder`) then run those commands verbatim instead of hard-coding `eslint`/`tsc`/`jest`. Opinionated **but askable** (default Y, opt-out) and **non-destructive**: existing ESLint/Prettier/Jest/husky setups are detected and a migration is only ever PROPOSED, never automatic (`.husky/` is never overwritten). Never silent in CI (`baldart doctor` backfills); each gate falls back silently to the project-standard default when its command is unset, so non-JS projects and consumers with their own toolchain are unaffected. Install via `baldart configure` or `/toolchain-bootstrap`. See [`framework/agents/toolchain-protocol.md`](framework/agents/toolchain-protocol.md) and [`framework/docs/TOOLCHAIN-LAYER.md`](framework/docs/TOOLCHAIN-LAYER.md).
|
|
251
|
+
|
|
248
252
|
### Commands
|
|
249
253
|
|
|
250
254
|
- **/new**: Batch orchestrator with QA validation, production readiness checklist, and context recovery (also available as a skill)
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.
|
|
1
|
+
4.41.0
|
|
@@ -226,9 +226,11 @@ persistence code while `stack.database` is empty, surface a warning suggesting
|
|
|
226
226
|
|
|
227
227
|
Do NOT wait until the end to verify your work. After each sub-task that changes types, interfaces, or function signatures:
|
|
228
228
|
|
|
229
|
-
|
|
229
|
+
> **Toolchain (since v4.41.0):** when `features.has_toolchain: true`, use the commands in `toolchain.commands.*` (`typecheck`, `lint`, `test`/`test_related`) verbatim for the steps below — per `agents/toolchain-protocol.md` — falling back to the defaults shown when a key is unset.
|
|
230
|
+
|
|
231
|
+
1. **When `stack.language` includes `typescript`**: run `toolchain.commands.typecheck` if set, else `npx tsc --noEmit` — fix ALL errors before proceeding to the next sub-task. On non-TypeScript stacks, run the project's equivalent type/static check instead (e.g. `mypy` / `pyright` for Python, `go vet` for Go) when one is configured.
|
|
230
232
|
2. If the type check fails: **STOP**. Fix the errors first. Do NOT continue writing new files on top of broken types.
|
|
231
|
-
3. After the final sub-task, run the
|
|
233
|
+
3. After the final sub-task, run the linter on your changed files: `toolchain.commands.lint` if set, else the project default (e.g. `npx eslint --max-warnings=0 <files>` for a JS/TS stack, or the configured equivalent).
|
|
232
234
|
4. **Unit tests**: run ONLY the specific test file, not the full suite. `npm run test` is slow (minutes). Run the single file with the project's actual runner — check `package.json` scripts / devDependencies and use whichever is present (e.g. `npx vitest run <file>`, `npx jest <file>`, `node --import tsx <file>`, or `pytest <file>` / `go test ./<pkg>` on non-JS stacks). Do NOT assume `tsx` is installed: if the chosen command fails with a missing-loader/module error, that means the runner is wrong — try the next candidate, do NOT treat the failure as "no related tests". If the task doesn't involve a known test file, skip the test run.
|
|
233
235
|
|
|
234
236
|
**Error Recovery — three-branch state machine (cap: 3 attempts)**: If a build breaks mid-implementation:
|
|
@@ -23,7 +23,16 @@ Run mechanical quality gates fast, return a PASS/FAIL verdict, and get out of th
|
|
|
23
23
|
> patterns. Pre-commit gates below are the typical defaults — adjust the toolchain to
|
|
24
24
|
> match your project (e.g. `ruff` instead of `eslint`, `pytest` instead of `npm test`).
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
**Toolchain commands (since v4.41.0):** when `features.has_toolchain: true` in
|
|
27
|
+
`baldart.config.yml`, run the command from `toolchain.commands.<gate>` (lint,
|
|
28
|
+
typecheck, test, test_related, build, audit) **verbatim** instead of the default
|
|
29
|
+
below — per `agents/toolchain-protocol.md`. Resolve per gate: a non-empty config
|
|
30
|
+
command wins; an empty/absent one falls back to the default below. A configured
|
|
31
|
+
command that EXITS NON-ZERO is a real FAIL (do not fall back). Example: a project
|
|
32
|
+
on Biome runs `npx biome check .` for lint; a Vitest project runs `npx vitest run`.
|
|
33
|
+
|
|
34
|
+
Default pre-commit gates (MUST pass before any commit verdict) — used when no
|
|
35
|
+
`toolchain.commands.*` is configured:
|
|
27
36
|
1. Lint: `npx eslint --max-warnings=0 <changed source files>` (or project equivalent)
|
|
28
37
|
2. Type-check: `npx tsc --noEmit` (or project equivalent)
|
|
29
38
|
3. Markdown lint: `npx markdownlint-cli2 <changed .md files>` (if .md files changed)
|
|
@@ -98,6 +98,8 @@ Write the initial file:
|
|
|
98
98
|
|
|
99
99
|
## Step 3 — Execute Profile
|
|
100
100
|
|
|
101
|
+
> **Toolchain (since v4.41.0):** when `features.has_toolchain: true` in `baldart.config.yml`, run the gate commands from `toolchain.commands.*` (lint, typecheck, test, test_related, build, audit) verbatim — per `agents/toolchain-protocol.md` — instead of the generic examples below. A configured command that fails is a real FAIL.
|
|
102
|
+
|
|
101
103
|
### LIGHT — Fast confidence (<3 min target [DESIGN-CHOICE: scoped to lint + type-check + related tests only; sufficient for low-risk or doc-only diffs])
|
|
102
104
|
|
|
103
105
|
Run directly in this session (no sub-agents):
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: toolchain-bootstrap
|
|
3
|
+
effort: medium
|
|
4
|
+
description: >
|
|
5
|
+
Install, verify, and wire the curated dev toolchain for this project. Detects
|
|
6
|
+
the JS/TS stack, installs the best-in-class tools as devDependencies (Biome for
|
|
7
|
+
format+lint+import, Vitest, tsc, Lefthook), writes their default config only
|
|
8
|
+
when absent, records toolchain.installed_tools + toolchain.commands.* in
|
|
9
|
+
baldart.config.yml, and proposes (never forces) a migration off any existing
|
|
10
|
+
ESLint/Prettier/Jest/husky. Use when the user says /toolchain-bootstrap,
|
|
11
|
+
"install the toolchain", "set up biome", or after enabling
|
|
12
|
+
features.has_toolchain for the first time. Idempotent — re-running re-verifies
|
|
13
|
+
and reports drift, never overwriting existing configs.
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Toolchain Bootstrap
|
|
17
|
+
|
|
18
|
+
Set up the curated dev toolchain so the quality gates (`/new`, `/qa`, `/check`,
|
|
19
|
+
`qa-sentinel`) run best-in-class tools instead of whatever the project happened
|
|
20
|
+
to have. Non-destructive throughout: configs are written only when absent and
|
|
21
|
+
incumbent tools are never installed over or removed.
|
|
22
|
+
|
|
23
|
+
## Project Context
|
|
24
|
+
|
|
25
|
+
**Reads from `baldart.config.yml`:** `features.has_toolchain`, `toolchain.installed_tools`, `toolchain.commands.*`, `toolchain.auto_verify`.
|
|
26
|
+
**Gated by features:** `features.has_toolchain` — this skill refuses to run when the flag is `false`, prompting the user to flip it via `npx baldart configure` first.
|
|
27
|
+
**Overlay:** loads `.baldart/overlays/toolchain-bootstrap.md` if present — project-specific tool choices or install commands.
|
|
28
|
+
**On missing keys:** ask the user; do not assume defaults. See `framework/agents/project-context.md` § 3.
|
|
29
|
+
|
|
30
|
+
## Effort
|
|
31
|
+
|
|
32
|
+
**Baseline:** `effort: medium` (frontmatter). **Inline override:** pass
|
|
33
|
+
`effort=<low|medium|high|xhigh|max>` anywhere in the invocation to scale
|
|
34
|
+
reasoning depth for this run — detect it once at kickoff and strip the token
|
|
35
|
+
before consuming user input. Level→behavior mapping, parsing contract, and
|
|
36
|
+
precedence caveats: `framework/agents/effort-protocol.md`.
|
|
37
|
+
|
|
38
|
+
## What This Skill Does
|
|
39
|
+
|
|
40
|
+
1. Reads `baldart.config.yml` and confirms `features.has_toolchain: true`.
|
|
41
|
+
2. Probes the cwd via `src/utils/toolchain-installer.js` to compute the clean
|
|
42
|
+
recommendation (`recommend()`) and any incumbent-blocked migrations
|
|
43
|
+
(`migrations()`).
|
|
44
|
+
3. Installs the recommended tools as **devDependencies** (`npm install -D -E`) —
|
|
45
|
+
never global (these are project tools invoked via `npx`, unlike LSP servers).
|
|
46
|
+
4. Writes each tool's default config **only when absent** (`biome.json`,
|
|
47
|
+
`lefthook.yml`) and registers Lefthook's `pre-commit` hook.
|
|
48
|
+
5. For incumbents (ESLint/Prettier/Jest/husky), PROPOSES a migration with a
|
|
49
|
+
preview — never automatic, never touching the existing config (`.husky/` is
|
|
50
|
+
never overwritten).
|
|
51
|
+
6. Writes `toolchain.installed_tools` + `toolchain.commands.*` to
|
|
52
|
+
`baldart.config.yml`, then `certify()`s the set.
|
|
53
|
+
7. Prints a compact status and points to
|
|
54
|
+
`framework/agents/toolchain-protocol.md` for runtime behavior.
|
|
55
|
+
|
|
56
|
+
## Workflow
|
|
57
|
+
|
|
58
|
+
1. **Refusal check.** If `features.has_toolchain: false` (or missing):
|
|
59
|
+
```
|
|
60
|
+
This project hasn't opted in to the curated toolchain yet.
|
|
61
|
+
Run `npx baldart configure` and answer YES to "Enable curated dev toolchain?"
|
|
62
|
+
then re-run /toolchain-bootstrap.
|
|
63
|
+
```
|
|
64
|
+
Stop here. Do not proceed.
|
|
65
|
+
|
|
66
|
+
2. **Probe.** Call the installer:
|
|
67
|
+
```
|
|
68
|
+
node -e 'const T=require("./.framework/src/utils/toolchain-installer"); const t=new T(); console.log(JSON.stringify({hasPkg:t.hasPackageJson(),recommend:t.recommend(),migrations:t.migrations()},null,2))'
|
|
69
|
+
```
|
|
70
|
+
If `hasPkg` is false, report "no package.json — JS toolchain not applicable"
|
|
71
|
+
and stop. Otherwise show the recommended tools and any migrations.
|
|
72
|
+
|
|
73
|
+
3. **Confirm.** For the clean recommendation, default YES. For each migration,
|
|
74
|
+
show what it replaces (and for Biome, the `npx biome migrate eslint/prettier
|
|
75
|
+
--write` preview) and default NO.
|
|
76
|
+
|
|
77
|
+
4. **Install + config + commands.** Run the installer's `install`, `initConfigs`,
|
|
78
|
+
then read back `commandsFor(activeTools())`. Capture failures into a "Skipped"
|
|
79
|
+
bucket — never abort the whole skill on one failure.
|
|
80
|
+
|
|
81
|
+
5. **Persist.** Update `baldart.config.yml`:
|
|
82
|
+
```yaml
|
|
83
|
+
toolchain:
|
|
84
|
+
installed_tools: [biome, vitest, tsc, lefthook]
|
|
85
|
+
commands:
|
|
86
|
+
lint: npx biome check .
|
|
87
|
+
format: npx biome format --write .
|
|
88
|
+
typecheck: npx tsc --noEmit
|
|
89
|
+
test: npx vitest run
|
|
90
|
+
test_related: npx vitest related --run
|
|
91
|
+
auto_verify: true
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
6. **Output.** A compact one-line-per-tool status, in the project's
|
|
95
|
+
`identity.language` from `baldart.config.yml` (English default).
|
|
96
|
+
|
|
97
|
+
## Output Contract
|
|
98
|
+
|
|
99
|
+
A single short status block — never a multi-page report. Format:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
Toolchain bootstrap:
|
|
103
|
+
✓ biome (devDep 2.x, biome.json written, lint+format wired)
|
|
104
|
+
✓ vitest (devDep, test + test_related wired)
|
|
105
|
+
✓ tsc (typescript present, typecheck wired)
|
|
106
|
+
✓ lefthook (devDep, lefthook.yml + pre-commit hook installed)
|
|
107
|
+
· eslint → migration available (declined): npx biome migrate eslint --write
|
|
108
|
+
Config updated: baldart.config.yml toolchain.installed_tools = [biome, vitest, tsc, lefthook]
|
|
109
|
+
Next: /qa, /new, qa-sentinel will now run these commands instead of the defaults.
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Notes
|
|
113
|
+
|
|
114
|
+
- This skill never edits source code. Its only side effects are devDependency
|
|
115
|
+
installs, writing absent default configs, registering the Lefthook hook, and a
|
|
116
|
+
YAML write to `baldart.config.yml`.
|
|
117
|
+
- Re-run safely. `recommend()`/`migrations()` are recomputed each time, configs
|
|
118
|
+
are skipped when present, and already-usable tools are left untouched —
|
|
119
|
+
additions / repairs are idempotent.
|
|
120
|
+
- `baldart doctor` is the unattended backfill: it installs missing tools
|
|
121
|
+
(`toolchain-install`) and restores missing default config (`toolchain-init-config`).
|
|
122
|
+
|
|
123
|
+
## See Also
|
|
124
|
+
|
|
125
|
+
- `framework/agents/toolchain-protocol.md` — runtime command resolution + fallback.
|
|
126
|
+
- `framework/docs/TOOLCHAIN-LAYER.md` — full plumbing + lifecycle.
|
|
127
|
+
- `src/utils/toolchain-adapters/` — per-tool install/verify recipes.
|
|
@@ -38,6 +38,14 @@ const cfg = a.config || {}
|
|
|
38
38
|
const highRisk = (cfg.paths && cfg.paths.high_risk_modules) || [] // security-domain hint
|
|
39
39
|
const protocolRef = '.claude/skills/new/references/review-cycle.md'
|
|
40
40
|
|
|
41
|
+
// Curated toolchain (since v4.41.0): when features.has_toolchain is on, the
|
|
42
|
+
// consumer records LITERAL gate commands in toolchain.commands.* — agents run
|
|
43
|
+
// THOSE instead of guessing (e.g. `npx biome check .` not `npm run lint`). Empty
|
|
44
|
+
// / absent → silent fallback to the project-standard default. Read from the
|
|
45
|
+
// config the skill already passes via args.config (never hardcoded project facts).
|
|
46
|
+
const tcCmds = (cfg.toolchain && cfg.toolchain.commands) || {}
|
|
47
|
+
const tc = (key, fallback) => (tcCmds[key] && String(tcCmds[key]).trim()) || fallback
|
|
48
|
+
|
|
41
49
|
// Per-card result accumulator — built up-front (so the early-return guards can return it) and
|
|
42
50
|
// populated with fixesApplied/residual in the Fix phase.
|
|
43
51
|
const perCard = {}
|
|
@@ -193,8 +201,15 @@ const codexPrompt =
|
|
|
193
201
|
`For each finding return: finding_id, title, severity (BLOCKER|HIGH|MEDIUM|LOW), confidence (0-100), evidence (exact file:line + code quote), minimal_fix_direction, and domain (doc|security|migration|code|perf|test). ` +
|
|
194
202
|
`Run the mandatory false-positive check on every finding and suppress the unconvincing ones (your findings are treated as already FP-validated). Set codexAvailable:true when the review ran.`
|
|
195
203
|
|
|
204
|
+
const tcGateLines = [
|
|
205
|
+
['lint', tcCmds.lint], ['typecheck', tcCmds.typecheck], ['test', tcCmds.test],
|
|
206
|
+
['build', tcCmds.build], ['audit', tcCmds.audit],
|
|
207
|
+
].filter(([, v]) => v && String(v).trim());
|
|
196
208
|
const qaPrompt =
|
|
197
|
-
`Run MECHANICAL GATES ONLY over the wave scope, per ${protocolRef} (Phase 3.5 qa-sentinel contract): lint, type-check (when stack uses typescript), the full test suite, build, dependency audit, and markdownlint as applicable. You are a GATE RUNNER: do NOT read source for code findings, do NOT emit severities — return only a PASS/FAIL/SKIP gate table.\n\nWorktree: ${a.worktreePath || '(cwd)'} — cd into it first.\nChanged files:\n${unionScope.join('\n')}`
|
|
209
|
+
`Run MECHANICAL GATES ONLY over the wave scope, per ${protocolRef} (Phase 3.5 qa-sentinel contract): lint, type-check (when stack uses typescript), the full test suite, build, dependency audit, and markdownlint as applicable. You are a GATE RUNNER: do NOT read source for code findings, do NOT emit severities — return only a PASS/FAIL/SKIP gate table.\n\nWorktree: ${a.worktreePath || '(cwd)'} — cd into it first.\nChanged files:\n${unionScope.join('\n')}` +
|
|
210
|
+
(tcGateLines.length
|
|
211
|
+
? `\n\nThis project configures a curated toolchain — run THESE EXACT commands for the corresponding gates (do not substitute):\n${tcGateLines.map(([k, v]) => ` • ${k}: ${String(v).trim()}`).join('\n')}`
|
|
212
|
+
: '')
|
|
198
213
|
|
|
199
214
|
function simplifyPrompt(c) {
|
|
200
215
|
return `Simplify analysis (read-only — you do NOT edit, the workflow applies fixes afterward) over ONE card's committed diff, per ${protocolRef} (Phase 2.55). Cover all THREE lenses and return findings:\n` +
|
|
@@ -342,7 +357,7 @@ async function applyFixPass(findings, writer, label, role) {
|
|
|
342
357
|
`You MAY edit ONLY these files (ownership map — touching anything else is a violation):\n${unionEditable.join('\n')}\n\n` +
|
|
343
358
|
`Findings to fix (fix the code, not the tests unless a test itself is wrong; do NOT expand scope beyond the finding):\n` +
|
|
344
359
|
findings.map((f) => `- [${f.finding_id}] (${f.card || '?'} / ${f.domain} / ${f.severity}) ${f.title}\n evidence: ${f.evidence}\n direction: ${f.minimal_fix_direction}`).join('\n') +
|
|
345
|
-
`\n\nAfter applying: run
|
|
360
|
+
`\n\nAfter applying: run \`${tc('lint', 'npm run lint')}\` and (when the project uses typescript) \`${tc('typecheck', 'npx tsc --noEmit')}\` and \`${tc('build', 'npm run build')}\` in the worktree. If a check fails because of an edit you made, fix the regression — at most 2 retries — staying within the allowed files. ` +
|
|
346
361
|
`Do NOT commit. Do NOT git stash (refs/stash is shared across worktrees). ` +
|
|
347
362
|
`Return: applied (finding_ids you fixed), unresolved (finding_ids you could NOT fix within the allowed files / 2 retries), and checks (PASS/FAIL/SKIP for lint, tsc, build).`
|
|
348
363
|
const r = await agent(fixBrief, { label, phase: 'Fix', agentType: writer, schema: FIX_SCHEMA })
|
|
@@ -215,6 +215,9 @@ const projectBrief = [
|
|
|
215
215
|
`Trunk: ${TRUNK}`,
|
|
216
216
|
`Reference modules (Read these for the EXACT /new semantics — this workflow only sequences them): ${REF}/`,
|
|
217
217
|
`Config facts: stack=${JSON.stringify(cfg.stack || {})}; features=${JSON.stringify(features)}; high_risk_modules=${JSON.stringify(highRisk)}; paths.backlog_dir=${paths.backlog_dir || '?'}; paths.references_dir=${paths.references_dir || '?'}.`,
|
|
218
|
+
(features.has_toolchain && cfg.toolchain && cfg.toolchain.commands)
|
|
219
|
+
? `Toolchain commands (run THESE verbatim for the baseline + any gate, per agents/toolchain-protocol.md; empty → project default): ${JSON.stringify(cfg.toolchain.commands)}.`
|
|
220
|
+
: '',
|
|
218
221
|
FLAGS.effort ? `Reasoning effort for this run: ${FLAGS.effort}.` : '',
|
|
219
222
|
].filter(Boolean).join('\n')
|
|
220
223
|
|
|
@@ -24,6 +24,7 @@ Route agents to the right module with minimal reading.
|
|
|
24
24
|
- If touching architecture, auth, or tech stack -> read `agents/architecture.md`.
|
|
25
25
|
- If touching workflow/process/commits/backlog -> read `agents/workflows.md`.
|
|
26
26
|
- If CREATING or MUTATING a backlog card (any prefix — `FEAT`/`CHORE`/`BUG`/`DOC`/`PERF`/`UI`), or consuming one type-blind (`/new`, `/new2`) -> read `agents/card-schema.md` (the universal, profile-aware baseline) before writing/validating fields.
|
|
27
|
+
- If running MECHANICAL GATES (lint, format, type-check, test, build, audit) and `features.has_toolchain: true` -> read `agents/toolchain-protocol.md` and run the command from `toolchain.commands.<gate>` verbatim, falling back to the project-standard default when a key is unset. A configured command that FAILS is a real gate failure (do not fall back).
|
|
27
28
|
- If touching testing or QA issues -> read `agents/testing.md` (also documents the scope-aware,
|
|
28
29
|
profile-driven test-selection strategy consumed by `qa-sentinel`).
|
|
29
30
|
- If touching GitHub issues or issue workflow -> read `agents/github-issue-subagent.md`.
|
|
@@ -65,6 +66,7 @@ When adding or updating agents, update REGISTRY.md — not this file.
|
|
|
65
66
|
- `agents/project-context.md` — Project context protocol: `baldart.config.yml` + overlays + missing-key handling (since v3.0.0)
|
|
66
67
|
- `agents/code-search-protocol.md` — Retrieval hierarchy for code search: LSP → Grep → Git (since v3.10.0, gated on `features.has_lsp_layer`)
|
|
67
68
|
- `agents/code-graph-protocol.md` — Structural/relational retrieval via the Graphify code knowledge graph (since v4.21.0, gated on `features.has_code_graph`)
|
|
69
|
+
- `agents/toolchain-protocol.md` — Mechanical-gate command resolution (lint/format/typecheck/test/build/audit) from `toolchain.commands.*` with silent project-standard fallback (since v4.41.0, gated on `features.has_toolchain`)
|
|
68
70
|
- `agents/design-system-protocol.md` — Registry-first discipline for UI work: BLOCKING cascade on `INDEX.md` + `tokens-reference.md` + `components/<Name>.md` (since v3.11.0, gated on `features.has_design_system`)
|
|
69
71
|
- `agents/card-schema.md` — Atomic Card Baseline Schema: the universal, profile-aware (epic/child/standalone) field contract every backlog card satisfies, plus the consumer HALT/BACK-FILL/WARN contract (since v4.35.0)
|
|
70
72
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Toolchain Protocol
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Define how agents/skills run the **mechanical quality gates** — lint, format,
|
|
6
|
+
type-check, test, build, audit — when a project has opted into the curated
|
|
7
|
+
toolchain. The commands are read from `toolchain.commands.*` in
|
|
8
|
+
`baldart.config.yml` and run **verbatim**, instead of each gate hard-coding
|
|
9
|
+
`eslint` / `tsc` / `jest` / `npm run build`. This lets a project standardize on
|
|
10
|
+
the best-in-class tools (Biome for format+lint+import, Vitest, tsc, Lefthook)
|
|
11
|
+
and have every gate flow use them consistently.
|
|
12
|
+
|
|
13
|
+
## Scope
|
|
14
|
+
|
|
15
|
+
**In**: which command to invoke for each gate; the resolution order; the silent
|
|
16
|
+
fallback. **Out**: code review for correctness/quality (that is the reviewer
|
|
17
|
+
agents' job, not a mechanical gate); installing the tools (that is
|
|
18
|
+
`baldart configure` / `/toolchain-bootstrap` / `baldart doctor`, see
|
|
19
|
+
`framework/docs/TOOLCHAIN-LAYER.md`).
|
|
20
|
+
|
|
21
|
+
## Gating
|
|
22
|
+
|
|
23
|
+
Conditional on `features.has_toolchain: true` in `baldart.config.yml`. The layer
|
|
24
|
+
degrades **silently and per-command**: for each gate, if
|
|
25
|
+
`toolchain.commands.<gate>` is a non-empty string, run it **exactly**; otherwise
|
|
26
|
+
fall back to the flow's built-in project-standard default (`npx eslint`,
|
|
27
|
+
`npx tsc --noEmit`, `npm test`, `npm run build`, `npm audit`, …). When the flag
|
|
28
|
+
is `false`/missing, every gate uses its default — identical to pre-toolchain
|
|
29
|
+
behavior. **Never block a task** because a command is unset or a tool is missing;
|
|
30
|
+
surface install gaps through `baldart doctor` (`toolchain-install` /
|
|
31
|
+
`toolchain-init-config` actions), not mid-task.
|
|
32
|
+
|
|
33
|
+
## Resolution hierarchy (per gate)
|
|
34
|
+
|
|
35
|
+
1. **Explicit config** — `toolchain.commands.<gate>` from `baldart.config.yml`,
|
|
36
|
+
run verbatim. This is the source of truth when set.
|
|
37
|
+
2. **Project-standard fallback** — the gate's existing default command, inferred
|
|
38
|
+
from the stack (eslint/tsc/jest/npm scripts). Used when the config key is
|
|
39
|
+
empty/absent.
|
|
40
|
+
3. **Skip** — when neither resolves (e.g. no build script in a library), report
|
|
41
|
+
`SKIP`, never fail.
|
|
42
|
+
|
|
43
|
+
## Command map
|
|
44
|
+
|
|
45
|
+
| Gate | Config key | Curated default (Biome/Vitest/tsc) | Fallback |
|
|
46
|
+
| --- | --- | --- | --- |
|
|
47
|
+
| Lint | `toolchain.commands.lint` | `npx biome check .` | `npx eslint --max-warnings=0 <files>` |
|
|
48
|
+
| Format | `toolchain.commands.format` | `npx biome format --write .` | `npx prettier --write <files>` |
|
|
49
|
+
| Type-check | `toolchain.commands.typecheck` | `npx tsc --noEmit` | `npx tsc --noEmit` |
|
|
50
|
+
| Test | `toolchain.commands.test` | `npx vitest run` | `npm test` |
|
|
51
|
+
| Test (related) | `toolchain.commands.test_related` | `npx vitest related --run <files>` | `npx jest --findRelatedTests <files>` |
|
|
52
|
+
| Build | `toolchain.commands.build` | `npm run build` | `npm run build` |
|
|
53
|
+
| Audit | `toolchain.commands.audit` | `npm audit --audit-level=high` | `npm audit` |
|
|
54
|
+
|
|
55
|
+
Biome's `check` runs lint + format-check + import-organize in one pass, so the
|
|
56
|
+
`lint` gate alone covers what a separate ESLint+Prettier+import-plugin trio
|
|
57
|
+
would; the `format` command only `--write`s.
|
|
58
|
+
|
|
59
|
+
## Consumers
|
|
60
|
+
|
|
61
|
+
`qa-sentinel` (gate runner), `/qa`, `/check`, the `coder` post-fix re-verify,
|
|
62
|
+
and the `/new` + `/new2` review workflows resolve gate commands through this
|
|
63
|
+
protocol. The `/new` workflow scripts receive the resolved config via their
|
|
64
|
+
`args.config` payload (the consuming skill passes `baldart.config.yml`) — they
|
|
65
|
+
must never hard-code project facts (see the workflows contamination contract).
|
|
66
|
+
|
|
67
|
+
## Fallback rules
|
|
68
|
+
|
|
69
|
+
- A configured command that EXITS NON-ZERO is a genuine gate **FAIL** — do not
|
|
70
|
+
silently fall back to the default (that would mask a real failure). Fallback
|
|
71
|
+
applies only when the command is **unset**, not when it fails.
|
|
72
|
+
- A configured command whose binary is missing (`command not found`) is a setup
|
|
73
|
+
gap → report it and fall back to the default for that single run, then let
|
|
74
|
+
`baldart doctor` repair the install. Never abort the task.
|
|
75
|
+
|
|
76
|
+
## See also
|
|
77
|
+
|
|
78
|
+
- `framework/docs/TOOLCHAIN-LAYER.md` — install lifecycle, adapters, plumbing.
|
|
79
|
+
- `agents/testing.md` — scope-aware, profile-driven test selection (the `test` /
|
|
80
|
+
`test_related` gates compose with it).
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Curated Toolchain Layer — Operator Guide
|
|
2
|
+
|
|
3
|
+
> Since v4.41.0. Opt-in, gated on `features.has_toolchain`. The **runtime**
|
|
4
|
+
> protocol (which command each gate runs) lives in
|
|
5
|
+
> [`framework/agents/toolchain-protocol.md`](../agents/toolchain-protocol.md);
|
|
6
|
+
> this document covers the *plumbing* — install, config, lifecycle, fallback.
|
|
7
|
+
|
|
8
|
+
## 1. Why this exists
|
|
9
|
+
|
|
10
|
+
BALDART has always been opinionated about *how* you work (workflows, review,
|
|
11
|
+
gates) but agnostic about the *tools* you work with. Every quality-gate flow
|
|
12
|
+
hard-coded `eslint` / `tsc` / `jest` / `npm run build`. This layer lets BALDART
|
|
13
|
+
also recommend and install a curated, best-in-class JS/TS toolchain — and, more
|
|
14
|
+
importantly, makes the agents **use it**: the gate flows read the literal
|
|
15
|
+
commands from `toolchain.commands.*` instead of guessing.
|
|
16
|
+
|
|
17
|
+
The curated set (JS/TS):
|
|
18
|
+
|
|
19
|
+
| Slot | Tool | Why |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| Format + Lint + Imports | **Biome** | One fast Rust binary replacing ESLint + Prettier + import plugins |
|
|
22
|
+
| Test | **Vitest** | Fast, ESM-native test runner |
|
|
23
|
+
| Type-check | **tsc** | The TypeScript compiler in `--noEmit` mode |
|
|
24
|
+
| Pre-commit | **Lefthook** | Fast, parallel git-hook runner (owns `pre-commit`) |
|
|
25
|
+
|
|
26
|
+
Other languages (Ruff for Python, gofmt for Go, …) plug in by adding an adapter —
|
|
27
|
+
no other layer changes.
|
|
28
|
+
|
|
29
|
+
## 2. Principles (non-negotiable)
|
|
30
|
+
|
|
31
|
+
- **Opinionated but askable** — on a JS/TS project with no incumbent, `configure`
|
|
32
|
+
PRESELECTS the tools (default Y); the user opts out.
|
|
33
|
+
- **Non-destructive** — config files are written only when absent; incumbent
|
|
34
|
+
tools (ESLint/Prettier/Jest/husky) are detected, **never installed or removed**.
|
|
35
|
+
A migration is only ever PROPOSED (with a preview), never automatic. Flipping
|
|
36
|
+
`features.has_toolchain` true→false does NOT uninstall anything — it just stops
|
|
37
|
+
agents from using the commands.
|
|
38
|
+
- **Never silent in CI** — `--non-interactive`/`--yes` installs nothing; it writes
|
|
39
|
+
the flag and `baldart doctor` backfills interactively.
|
|
40
|
+
- **Silent fallback, never abort** — for each gate, an unset command falls back to
|
|
41
|
+
the project-standard default; a missing tool is a doctor item, never a task
|
|
42
|
+
blocker. (A configured command that EXITS NON-ZERO is a real failure — fallback
|
|
43
|
+
applies only to *unset* commands, not failing ones.)
|
|
44
|
+
|
|
45
|
+
## 3. What BALDART adds vs what the tools ship
|
|
46
|
+
|
|
47
|
+
BALDART does not reimplement Biome/Vitest/tsc/Lefthook. It adds only:
|
|
48
|
+
|
|
49
|
+
- **Gating + config** (`features.has_toolchain` + the `toolchain:` block).
|
|
50
|
+
- **Opt-in install** (`configure` interactive branch, `/toolchain-bootstrap`,
|
|
51
|
+
`doctor` backfill) via per-tool adapters.
|
|
52
|
+
- **A command-resolution protocol** telling BALDART's agents which command each
|
|
53
|
+
gate runs.
|
|
54
|
+
- **Currency** — `baldart doctor` reports devDeps behind their npm latest
|
|
55
|
+
(non-blocking; devDep upgrades are user-run).
|
|
56
|
+
- **Fallback discipline** — silent degrade to project-standard defaults.
|
|
57
|
+
|
|
58
|
+
## 4. The moving parts
|
|
59
|
+
|
|
60
|
+
| Part | Where | Role |
|
|
61
|
+
|------|-------|------|
|
|
62
|
+
| Config flag + block | `framework/templates/baldart.config.template.yml` | `features.has_toolchain` + `toolchain.{installed_tools,commands.*,auto_verify}` |
|
|
63
|
+
| Curated adapters | `src/utils/toolchain-adapters/{biome,vitest,tsc,lefthook}.js` | `installCommand/verifyCommand/commands()/initConfig/static replaces/static detect` |
|
|
64
|
+
| Incumbent detectors | `src/utils/toolchain-adapters/{eslint,prettier,jest,husky}.js` | detection only (migration proposal) |
|
|
65
|
+
| Dispatcher | `src/utils/toolchain-adapters/index.js` | `REGISTRY` + `INCUMBENTS` + `detectAll` + `detectIncumbents` |
|
|
66
|
+
| Installer wrapper | `src/utils/toolchain-installer.js` | `recommend/migrations/install/initConfigs/commandsFor/certify/activeTools` |
|
|
67
|
+
| Configure | `src/commands/configure.js` | autodetect default + prompt + interactive install/migrate/write |
|
|
68
|
+
| Update detector | `src/commands/update.js` | diffs the `toolchain:` block (incl. nested `commands.*`) |
|
|
69
|
+
| Doctor | `src/commands/doctor.js` | `toolchain-install` / `toolchain-init-config` backfill + currency |
|
|
70
|
+
| Currency | `src/utils/tool-currency.js` | `_toolchainRecords` — installed (node_modules) vs npm latest |
|
|
71
|
+
| Retrieval protocol | `framework/agents/toolchain-protocol.md` | which command each gate runs; fallback |
|
|
72
|
+
| Consumers | `qa-sentinel`, `coder`, `/qa`, `new-card-review.js`, `new2.js` | run `toolchain.commands.*` with fallback |
|
|
73
|
+
| Bootstrap skill | `/toolchain-bootstrap` | explicit install path (CI-safe backfill) |
|
|
74
|
+
|
|
75
|
+
## 5. Install lifecycle
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
features.has_toolchain: true
|
|
79
|
+
│
|
|
80
|
+
├─ baldart configure (INTERACTIVE)
|
|
81
|
+
│ → recommend() clean set → npm install -D -E (devDeps)
|
|
82
|
+
│ → initConfigs() writes biome.json / lefthook.yml IF ABSENT
|
|
83
|
+
│ → Lefthook registers its pre-commit hook
|
|
84
|
+
│ → write toolchain.installed_tools + toolchain.commands.*
|
|
85
|
+
│ → certify() (each tool resolves via npx + config present)
|
|
86
|
+
│ └─ incumbent present → PROPOSE migration (never automatic)
|
|
87
|
+
│
|
|
88
|
+
├─ baldart configure --yes / CI
|
|
89
|
+
│ → writes the flag from autodetect; installs NOTHING
|
|
90
|
+
│ → doctor backfills the install
|
|
91
|
+
│
|
|
92
|
+
├─ /qa · /new · /new2 · qa-sentinel · coder
|
|
93
|
+
│ → resolve each gate from toolchain.commands.* (fallback to default)
|
|
94
|
+
│
|
|
95
|
+
└─ baldart doctor
|
|
96
|
+
→ toolchain-install (devDep missing)
|
|
97
|
+
→ toolchain-init-config (default config missing)
|
|
98
|
+
→ tool-upgrade:toolchain:<tool> (behind npm latest — non-blocking)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## 6. Fallback hierarchy (per gate)
|
|
102
|
+
|
|
103
|
+
1. **Explicit** — `toolchain.commands.<gate>`, run verbatim.
|
|
104
|
+
2. **Project-standard** — the flow's built-in default (`npx eslint`, `npx tsc
|
|
105
|
+
--noEmit`, `npm test`, `npm run build`, `npm audit`).
|
|
106
|
+
3. **Skip** — when neither resolves (e.g. no build script), report `SKIP`.
|
|
107
|
+
|
|
108
|
+
## 7. Edge cases
|
|
109
|
+
|
|
110
|
+
- **Non-JS project** — no adapter `detect()` fires; nothing is proposed.
|
|
111
|
+
- **Monorepo** — Biome/Vitest are root-scoped (one `biome.json` covers the
|
|
112
|
+
workspace); Lefthook is root-only (one `.git`).
|
|
113
|
+
- **Existing ESLint/Prettier/Jest/husky** — detected as incumbents; the matching
|
|
114
|
+
curated tool routes to the migration proposal, never an automatic install. husky
|
|
115
|
+
specifically: Lefthook is NOT installed over `.husky/` — the hook handoff is
|
|
116
|
+
manual.
|
|
117
|
+
- **`biome.json` / `lefthook.yml` already present** — kept, never overwritten.
|
|
118
|
+
- **No `package.json`** — the JS toolchain is skipped (cannot install a devDep);
|
|
119
|
+
the flag stays on so a later `configure`/`doctor` can complete it.
|
|
120
|
+
|
|
121
|
+
## 8. Adding a language / tool
|
|
122
|
+
|
|
123
|
+
1. Create `src/utils/toolchain-adapters/<tool>.js` shaped like `biome.js`
|
|
124
|
+
(`installCommand`, `verifyCommand`, `commands()`, `initConfig`, `static
|
|
125
|
+
replaces`, `static detect`). Add it to `REGISTRY` in `index.js`.
|
|
126
|
+
2. For an incumbent it supersedes, add a detection-only adapter to `INCUMBENTS`
|
|
127
|
+
and list it in the curated tool's `static replaces`.
|
|
128
|
+
3. Everything else (configure, doctor, currency, the protocol) iterates the
|
|
129
|
+
registry — no further wiring.
|
|
130
|
+
|
|
131
|
+
## See also
|
|
132
|
+
|
|
133
|
+
- `framework/agents/toolchain-protocol.md` — runtime command resolution.
|
|
134
|
+
- `framework/.claude/skills/toolchain-bootstrap/SKILL.md` — explicit install path.
|
|
135
|
+
- `src/utils/toolchain-adapters/` — per-tool install/verify recipes.
|
|
@@ -202,6 +202,19 @@ features:
|
|
|
202
202
|
# changed. See framework/.claude/skills/e2e-review/SKILL.md.
|
|
203
203
|
has_e2e_review: false
|
|
204
204
|
|
|
205
|
+
# Curated dev toolchain (since v4.41.0). When true, BALDART installs and
|
|
206
|
+
# enables an opinionated set of best-in-class JS/TS dev tools (Biome for
|
|
207
|
+
# format+lint+import; later Vitest, tsc, Lefthook) and the quality-gate flows
|
|
208
|
+
# (/new, /qa, /check, qa-sentinel) run the commands recorded in
|
|
209
|
+
# `toolchain.commands.*` below instead of hardcoding eslint/tsc/jest. Falls
|
|
210
|
+
# back SILENTLY to the project-standard defaults when a command is unset, so a
|
|
211
|
+
# consumer with its own toolchain (or a non-JS project) is unaffected.
|
|
212
|
+
# `baldart configure` / `/toolchain-bootstrap` install the tools; `baldart
|
|
213
|
+
# doctor` backfills. Existing ESLint/Prettier setups are never touched — a
|
|
214
|
+
# migration is only ever PROPOSED. See framework/agents/toolchain-protocol.md
|
|
215
|
+
# and framework/docs/TOOLCHAIN-LAYER.md.
|
|
216
|
+
has_toolchain: false
|
|
217
|
+
|
|
205
218
|
# ─── E2E REVIEW ──────────────────────────────────────────────────────────
|
|
206
219
|
# Tuning for the /e2e-review skill (only consulted when has_e2e_review: true).
|
|
207
220
|
e2e_review:
|
|
@@ -263,6 +276,33 @@ graph:
|
|
|
263
276
|
# without it, so this is an enhancement, not a requirement.
|
|
264
277
|
register_mcp: false
|
|
265
278
|
|
|
279
|
+
# ─── TOOLCHAIN ─────────────────────────────────────────────────────────────
|
|
280
|
+
# State of the curated dev toolchain. Populated by `baldart configure` / the
|
|
281
|
+
# `/toolchain-bootstrap` skill. Only meaningful when `features.has_toolchain:
|
|
282
|
+
# true`. The commands are LITERAL (run verbatim by agents) — an empty string
|
|
283
|
+
# means "fall back to the project-standard default for this gate".
|
|
284
|
+
toolchain:
|
|
285
|
+
# Curated tools BALDART has installed/verified locally. Identifiers map to
|
|
286
|
+
# adapters under src/utils/toolchain-adapters/ (biome — extend with vitest,
|
|
287
|
+
# tsc, lefthook, …).
|
|
288
|
+
installed_tools: []
|
|
289
|
+
|
|
290
|
+
# Literal gate commands read by the quality-gate flows (/new, /qa, /check,
|
|
291
|
+
# qa-sentinel). Empty string → the flow uses its built-in fallback (eslint /
|
|
292
|
+
# tsc / jest / npm run build / npm audit), so the layer degrades cleanly.
|
|
293
|
+
commands:
|
|
294
|
+
lint: "" # e.g. npx biome check .
|
|
295
|
+
format: "" # e.g. npx biome format --write .
|
|
296
|
+
typecheck: "" # e.g. npx tsc --noEmit
|
|
297
|
+
test: "" # e.g. npx vitest run
|
|
298
|
+
test_related: "" # e.g. npx vitest related --run
|
|
299
|
+
build: "" # e.g. npm run build
|
|
300
|
+
audit: "" # e.g. npm audit --audit-level=high
|
|
301
|
+
|
|
302
|
+
# When true, `baldart doctor` re-verifies the installed tools resolve and
|
|
303
|
+
# restores any missing default config. Disable on CI if too noisy.
|
|
304
|
+
auto_verify: true
|
|
305
|
+
|
|
266
306
|
# ─── GIT ─────────────────────────────────────────────────────────────────
|
|
267
307
|
# Controls how worktree-manager (`/mw`) integrates a worktree's feature
|
|
268
308
|
# branch back into the integration trunk.
|