Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .mulch/expertise/cli.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,4 @@
{"type":"pattern","classification":"tactical","recorded_at":"2026-05-28T17:38:57.949Z","evidence":{"seeds":"mulch-a11b","commit":"968089263e0ba4007a82a67a2a7496b7a26a28cf"},"name":"l5-check-all-ci-wiring","description":"L5 check:all aggregator chains fail-fast: check:size && check:debt && check:dups && check:deps && check:agents && check:coverage. CI runs test:ci BEFORE check:all so check:coverage reads the freshly-written coverage/lcov.info. mulch's test:ci writes junit.xml at repo root (not test-results/), so upload-artifact paths are coverage/lcov.info and junit.xml. report:timing/report:quality self-append to $GITHUB_STEP_SUMMARY (no redirect needed).","files":[".seeds/issues.jsonl",".seeds/plans.jsonl"],"tags":["author:jayminwest"],"id":"mx-aeea73"}
{"type":"convention","classification":"tactical","recorded_at":"2026-05-28T18:57:29.972Z","evidence":{"commit":"9680892","seeds":"mulch-6048"},"content":"L5 check:all coverage ratchet runs at the very end of the chain (check:size→debt→dups→deps→agents→coverage) and is the gate most likely to fail: line coverage sits at 83.99% against an 83% floor (≈1% margin), so a single new under-tested file can break CI. When adding source files, add tests in the same commit or expect check:all/CI red. Floors live in scripts/coverage-budgets.json.","tags":["author:jayminwest"],"id":"mx-52f52d"}
{"type":"failure","classification":"tactical","recorded_at":"2026-06-02T19:23:18.124Z","evidence":{"seeds":"mulch-35c9","commit":"a82ceb059e64c18cb37adc6952305b97b6bb865f"},"description":"pino-pretty is a devDependency, so selecting the pino-pretty transport in src/log.ts whenever stderr.isTTY makes published consumers (npm i -g, bun add, prod installs) throw 'unable to determine transport target for pino-pretty' in interactive terminals.","resolution":"Gate the pretty path on isPinoPrettyAvailable() (createRequire(import.meta.url).resolve in try/catch); fall back to pino.destination(2) JSON-on-stderr when pino-pretty is absent. createLogger accepts a prettyAvailable override so tests can exercise the fallback without uninstalling the dep.","tags":["author:jayminwest"],"id":"mx-c59e1e"}
{"type":"convention","classification":"tactical","recorded_at":"2026-06-15T10:17:41.198Z","evidence":{"commit":"49f3aef108e18241f0459d9b94774648078fc935"},"content":"All ml subcommands emit snake_case JSON keys (up_to_date, not_installed, default_mode, extracts_files, etc.). When adding a new --json field, use snake_case. ml upgrade --json originally used camelCase upToDate; it was renamed to up_to_date in mulch-4ca6 to match ml onboard --json and the rest of the codebase. Mixed-case JSON for the same concept across commands is a defect, not a style choice.","id":"mx-ab3155"}
6 changes: 3 additions & 3 deletions .seeds/issues.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -332,11 +332,11 @@
{"id":"mulch-ab79","title":"Add the canonical scripts/check-all.ts quiet runner copied byte-identical from templates/l5-toolkit/scripts/check-all.ts, with mulch's exported GATES manifest in the standard's order: lint, typecheck, check:agents, check:dups, check:deps, check:size, check:debt, check:coverage, check:ci-parity (last) -- note lint and typecheck must be ADDED to the manifest (they exist as scripts but are absent from the current && chain). Replace package.json check:all with `bun scripts/check-all.ts`, add `verify`: `bun run check:all`, and add scripts/check-all.test.ts. Confirm the quiet-output contract.","status":"closed","type":"task","priority":2,"plan_step_index":0,"description":"<!-- seeds:plan-backref:start -->\nStep 1 of plan pl-237d.\n\nParent seed: mulch-f16f — Adopt canonical check:all standard\nPlan template: feature\nPlan approach: Swap the && chain for the canonical quiet runner with a GATES manifest in the standard's order (folding in the already-present lint and typecheck scripts), then add the generalized ci-parity gate and the verify alias. mulch has no UI…\n\nRun `sd plan show pl-237d` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-12T04:53:28.928Z","updatedAt":"2026-06-12T05:56:59.979Z","plan_id":"pl-237d","blocks":["mulch-c658","mulch-f16f"],"closedAt":"2026-06-12T05:56:59.979Z"}
{"id":"mulch-c658","title":"Add scripts/check-ci-parity.ts (with test) copied from templates/l5-toolkit/scripts, importing the GATES array from check-all.ts; add the check:ci-parity script as the final gate in the manifest. Reconcile any residual non-canonical gate name. Verify check:ci-parity passes against .github/workflows/ci.yml.","status":"closed","type":"task","priority":2,"plan_step_index":1,"description":"<!-- seeds:plan-backref:start -->\nStep 2 of plan pl-237d.\n\nParent seed: mulch-f16f — Adopt canonical check:all standard\nPlan template: feature\nPlan approach: Swap the && chain for the canonical quiet runner with a GATES manifest in the standard's order (folding in the already-present lint and typecheck scripts), then add the generalized ci-parity gate and the verify alias. mulch has no UI…\n\nRun `sd plan show pl-237d` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-12T04:53:28.928Z","updatedAt":"2026-06-12T05:57:00.030Z","plan_id":"pl-237d","blocks":["mulch-c6f8","mulch-f16f"],"closedAt":"2026-06-12T05:57:00.030Z"}
{"id":"mulch-c6f8","title":"Wire .github/workflows/ci.yml to invoke the canonical gates (or `bun run check:all`) so the local manifest matches CI. Run `bun run check:all` and `bun run verify` green end-to-end with the quiet-output contract and a passing check:ci-parity.","status":"closed","type":"task","priority":2,"plan_step_index":2,"description":"<!-- seeds:plan-backref:start -->\nStep 3 of plan pl-237d.\n\nParent seed: mulch-f16f — Adopt canonical check:all standard\nPlan template: feature\nPlan approach: Swap the && chain for the canonical quiet runner with a GATES manifest in the standard's order (folding in the already-present lint and typecheck scripts), then add the generalized ci-parity gate and the verify alias. mulch has no UI…\n\nRun `sd plan show pl-237d` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-12T04:53:28.928Z","updatedAt":"2026-06-12T05:57:00.083Z","plan_id":"pl-237d","blocks":["mulch-f16f"],"closedAt":"2026-06-12T05:57:00.083Z"}
{"id":"mulch-e3e9","title":"nightwatch patrol: 2026-06-15","status":"open","type":"task","priority":3,"createdAt":"2026-06-15T10:08:07.957Z","updatedAt":"2026-06-15T10:08:46.513Z","labels":["patrol","nightwatch"],"plan_id":"pl-b637","blockedBy":["mulch-4ca6","mulch-fed1","mulch-4bd0","mulch-9465","mulch-a424","mulch-4dc4","mulch-0768"]}
{"id":"mulch-4ca6","title":"Canonicalize JSON `up_to_date` vs `upToDate` across upgrade/onboard output","status":"open","type":"task","priority":3,"plan_step_index":0,"description":"<!-- seeds:plan-backref:start -->\nStep 1 of plan pl-b637.\n\nParent seed: mulch-e3e9 — nightwatch patrol: 2026-06-15\nPlan template: refactor\nPlan approach: One step per finding so each lands as an isolated PR. Independent steps (1, 2, 3, 4, 5, 6) run in parallel; the release step (7) batches them. Step 1 (JSON key canonicalization) and step 4 (suffix-boundary fix) are the only…\n\nRun `sd plan show pl-b637` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-15T10:08:46.513Z","updatedAt":"2026-06-15T10:08:46.513Z","labels":["nightwatch"],"plan_id":"pl-b637","blocks":["mulch-0768","mulch-e3e9"]}
{"id":"mulch-e3e9","title":"nightwatch patrol: 2026-06-15","status":"open","type":"task","priority":3,"createdAt":"2026-06-15T10:08:07.957Z","updatedAt":"2026-06-15T10:18:09.429Z","labels":["patrol","nightwatch"],"plan_id":"pl-b637","blockedBy":["mulch-fed1","mulch-4bd0","mulch-9465","mulch-a424","mulch-4dc4","mulch-0768"]}
{"id":"mulch-4ca6","title":"Canonicalize JSON `up_to_date` vs `upToDate` across upgrade/onboard output","status":"closed","type":"task","priority":3,"plan_step_index":0,"description":"<!-- seeds:plan-backref:start -->\nStep 1 of plan pl-b637.\n\nParent seed: mulch-e3e9 — nightwatch patrol: 2026-06-15\nPlan template: refactor\nPlan approach: One step per finding so each lands as an isolated PR. Independent steps (1, 2, 3, 4, 5, 6) run in parallel; the release step (7) batches them. Step 1 (JSON key canonicalization) and step 4 (suffix-boundary fix) are the only…\n\nRun `sd plan show pl-b637` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-15T10:08:46.513Z","updatedAt":"2026-06-15T10:18:09.429Z","labels":["nightwatch"],"plan_id":"pl-b637","blocks":["mulch-0768","mulch-e3e9"],"closedAt":"2026-06-15T10:18:09.429Z","closeReason":"Landed in 49f3aef: ml upgrade --json now emits up_to_date (snake_case) to match ml onboard --json. Test + CHANGELOG updated. bun run verify 9/9 green."}
{"id":"mulch-fed1","title":"Dedupe local parseStrictPositiveInt/parseStrictNonNegativeNumber copies; import from src/utils/numeric-flags.ts","status":"open","type":"task","priority":3,"plan_step_index":1,"description":"<!-- seeds:plan-backref:start -->\nStep 2 of plan pl-b637.\n\nParent seed: mulch-e3e9 — nightwatch patrol: 2026-06-15\nPlan template: refactor\nPlan approach: One step per finding so each lands as an isolated PR. Independent steps (1, 2, 3, 4, 5, 6) run in parallel; the release step (7) batches them. Step 1 (JSON key canonicalization) and step 4 (suffix-boundary fix) are the only…\n\nRun `sd plan show pl-b637` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-15T10:08:46.513Z","updatedAt":"2026-06-15T10:08:46.513Z","labels":["nightwatch"],"plan_id":"pl-b637","blocks":["mulch-0768","mulch-e3e9"]}
{"id":"mulch-4bd0","title":"Replace `(err as Error).message` with `err instanceof Error ? err.message : String(err)` across src/commands and src/utils","status":"open","type":"task","priority":3,"plan_step_index":2,"description":"<!-- seeds:plan-backref:start -->\nStep 3 of plan pl-b637.\n\nParent seed: mulch-e3e9 — nightwatch patrol: 2026-06-15\nPlan template: refactor\nPlan approach: One step per finding so each lands as an isolated PR. Independent steps (1, 2, 3, 4, 5, 6) run in parallel; the release step (7) batches them. Step 1 (JSON key canonicalization) and step 4 (suffix-boundary fix) are the only…\n\nRun `sd plan show pl-b637` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-15T10:08:46.513Z","updatedAt":"2026-06-15T10:08:46.513Z","labels":["nightwatch"],"plan_id":"pl-b637","blocks":["mulch-0768","mulch-e3e9"]}
{"id":"mulch-9465","title":"Fix path-segment boundary in src/utils/git.ts fileMatchesAny + add false-positive coverage","status":"open","type":"task","priority":2,"plan_step_index":3,"description":"<!-- seeds:plan-backref:start -->\nStep 4 of plan pl-b637.\n\nParent seed: mulch-e3e9 — nightwatch patrol: 2026-06-15\nPlan template: refactor\nPlan approach: One step per finding so each lands as an isolated PR. Independent steps (1, 2, 3, 4, 5, 6) run in parallel; the release step (7) batches them. Step 1 (JSON key canonicalization) and step 4 (suffix-boundary fix) are the only…\n\nRun `sd plan show pl-b637` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-15T10:08:46.513Z","updatedAt":"2026-06-15T10:08:46.513Z","labels":["nightwatch"],"plan_id":"pl-b637","blocks":["mulch-0768","mulch-e3e9"]}
{"id":"mulch-a424","title":"Unify JSON vs human error wording in src/commands/ready.ts unknown-domain branch","status":"open","type":"task","priority":3,"plan_step_index":4,"description":"<!-- seeds:plan-backref:start -->\nStep 5 of plan pl-b637.\n\nParent seed: mulch-e3e9 — nightwatch patrol: 2026-06-15\nPlan template: refactor\nPlan approach: One step per finding so each lands as an isolated PR. Independent steps (1, 2, 3, 4, 5, 6) run in parallel; the release step (7) batches them. Step 1 (JSON key canonicalization) and step 4 (suffix-boundary fix) are the only…\n\nRun `sd plan show pl-b637` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-15T10:08:46.513Z","updatedAt":"2026-06-15T10:08:46.513Z","labels":["nightwatch"],"plan_id":"pl-b637","blocks":["mulch-0768","mulch-e3e9"]}
{"id":"mulch-4dc4","title":"Backfill direct unit tests for src/utils/domain-rules.ts and src/utils/format-helpers.ts","status":"open","type":"task","priority":3,"plan_step_index":5,"description":"<!-- seeds:plan-backref:start -->\nStep 6 of plan pl-b637.\n\nParent seed: mulch-e3e9 — nightwatch patrol: 2026-06-15\nPlan template: refactor\nPlan approach: One step per finding so each lands as an isolated PR. Independent steps (1, 2, 3, 4, 5, 6) run in parallel; the release step (7) batches them. Step 1 (JSON key canonicalization) and step 4 (suffix-boundary fix) are the only…\n\nRun `sd plan show pl-b637` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-15T10:08:46.513Z","updatedAt":"2026-06-15T10:08:46.513Z","labels":["nightwatch"],"plan_id":"pl-b637","blocks":["mulch-0768","mulch-e3e9"]}
{"id":"mulch-0768","title":"Release: run /release per .claude/commands/release.md","status":"open","type":"task","priority":3,"plan_step_index":6,"description":"<!-- seeds:plan-backref:start -->\nStep 7 of plan pl-b637.\n\nParent seed: mulch-e3e9 — nightwatch patrol: 2026-06-15\nPlan template: refactor\nPlan approach: One step per finding so each lands as an isolated PR. Independent steps (1, 2, 3, 4, 5, 6) run in parallel; the release step (7) batches them. Step 1 (JSON key canonicalization) and step 4 (suffix-boundary fix) are the only…\n\nRun `sd plan show pl-b637` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-15T10:08:46.513Z","updatedAt":"2026-06-15T10:08:46.513Z","labels":["nightwatch"],"plan_id":"pl-b637","blockedBy":["mulch-4ca6","mulch-fed1","mulch-4bd0","mulch-9465","mulch-a424","mulch-4dc4"],"blocks":["mulch-e3e9"]}
{"id":"mulch-0768","title":"Release: run /release per .claude/commands/release.md","status":"open","type":"task","priority":3,"plan_step_index":6,"description":"<!-- seeds:plan-backref:start -->\nStep 7 of plan pl-b637.\n\nParent seed: mulch-e3e9 — nightwatch patrol: 2026-06-15\nPlan template: refactor\nPlan approach: One step per finding so each lands as an isolated PR. Independent steps (1, 2, 3, 4, 5, 6) run in parallel; the release step (7) batches them. Step 1 (JSON key canonicalization) and step 4 (suffix-boundary fix) are the only…\n\nRun `sd plan show pl-b637` for the full plan (context, alternatives, sibling steps, acceptance criteria).\n<!-- seeds:plan-backref:end -->","createdAt":"2026-06-15T10:08:46.513Z","updatedAt":"2026-06-15T10:18:09.429Z","labels":["nightwatch"],"plan_id":"pl-b637","blockedBy":["mulch-fed1","mulch-4bd0","mulch-9465","mulch-a424","mulch-4dc4"],"blocks":["mulch-e3e9"]}
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- **`ml upgrade --json` key canonicalized to `up_to_date`** (closes mulch-4ca6): the `upgrade` JSON output previously emitted `upToDate` (camelCase) while `ml onboard --json` emitted the same concept as the snake_case action value `up_to_date`. The `upgrade` payload now uses `up_to_date` to match the rest of mulch's snake_case JSON convention (e.g. `not_installed`, `default_mode`, `extracts_files`). Consumers that read `parsed.upToDate` must switch to `parsed.up_to_date`; the boolean semantics are unchanged.

## [0.10.7] - 2026-06-02

A targeted bug-fix release. Published consumers of `@os-eco/mulch-cli` running in an interactive TTY hit pino's pretty-transport path even though `pino-pretty` ships only as a devDependency, causing pino to throw `unable to determine transport target for "pino-pretty"`. The diagnostic logger now probes `pino-pretty` resolvability and degrades to JSON-on-stderr when it is absent, honoring the documented JSON-for-consumers promise. No schema, hook-event, config-key, or public CLI-command changes. 1497 tests across 71 files / 3854 expect() calls (up from 1494 / 71 / 3849 in 0.10.6).
Expand Down
6 changes: 3 additions & 3 deletions src/commands/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function registerUpgradeCommand(program: Command): void {
command: "upgrade",
current,
latest,
upToDate: true,
up_to_date: true,
updated: false,
});
} else {
Expand All @@ -53,7 +53,7 @@ export function registerUpgradeCommand(program: Command): void {
command: "upgrade",
current,
latest,
upToDate: false,
up_to_date: false,
updated: false,
});
} else {
Expand Down Expand Up @@ -83,7 +83,7 @@ export function registerUpgradeCommand(program: Command): void {
command: "upgrade",
current,
latest,
upToDate: false,
up_to_date: false,
updated: true,
});
} else {
Expand Down
2 changes: 1 addition & 1 deletion test/commands/upgrade.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe("upgrade command", () => {
expect(parsed.command).toBe("upgrade");
expect(typeof parsed.current).toBe("string");
expect(typeof parsed.latest).toBe("string");
expect(typeof parsed.upToDate).toBe("boolean");
expect(typeof parsed.up_to_date).toBe("boolean");
expect(parsed.updated).toBe(false);
}
});
Expand Down
Loading