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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"test:unit": "bun test --parallel=4 --timeout=180000 ./scripts/tests/unit/*.test.mjs",
"test:observability": "bun scripts/tests/ci-observability.mjs",
"test:contracts": "bun scripts/tests/test-contracts.mjs",
"test:coverage": "node --test --experimental-test-coverage --test-coverage-include='plugins/plan-lifecycle/skills/productivity/plan-manager/scripts/plan.mjs' --test-coverage-exclude='**/scripts/tests/**' --test-coverage-exclude='**/plugins/**/test/**' scripts/tests/plan-cli.mjs"
"test:coverage": "node --test --experimental-test-coverage --test-coverage-include='plugins/plan-lifecycle/skills/productivity/plan-manager/scripts/plan.mjs' --test-coverage-exclude='**/scripts/tests/**' --test-coverage-exclude='**/plugins/**/test/**' scripts/tests/plan-cli/*.test.mjs"
},
"trustedDependencies": [],
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: "Use when a goal may need the six-phase plan flow: decide, draft, r
user-invocable: true
metadata:
pattern: tool-wrapper
updated: "2026-10-21"
updated: "2026-10-23"
content_hash: "37cfc75fba999189e56e877a1cb3ad02be4e26c5e3f289bd83e1d3e3f08a427b"
---

Expand Down
243 changes: 158 additions & 85 deletions plugins/plan-lifecycle/skills/productivity/plan-manager/scripts/plan.mjs

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions scripts/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ owned by `.github/AGENTS.md` (PR topology). The changed-path → shard mapping i

The root `AGENTS.md` (Plans) decides when a change needs a canonical plan.

The live plan author suite runs the helper smoke in `scripts/tests/plan-cli.mjs`
The live plan author suite is the set of plan-CLI case files in
`scripts/tests/plan-cli/`. The `scripts/tests/plan-cli.mjs` entry runs them
against the shipped
`plugins/plan-lifecycle/skills/productivity/plan-manager/scripts/plan.mjs`.
The canonical issue-body contract lives in
Expand Down Expand Up @@ -62,10 +63,10 @@ Plugin behavior stays registry-driven: extend descriptor capabilities rather tha
| `config/read-floor.mjs` | reads per-file floors from `scoring.json` | — |
| `tests/skill-trigger-collision.mjs` | cross-skill trigger-overlap audit — fails on a ≥5-token unrouted pair (`--report` prints the matrix) | pass/fail |
| `tests/idempotency.mjs` | content-hash determinism + every stored hash in sync | pass/fail |
| `tests/plan-cli.mjs` | smoke-tests the shipped plan helper (`plan.mjs`) | pass/fail |
| `tests/plan-cli.mjs` | runs the plan-CLI case files in `tests/plan-cli/` in parallel through Node's test runner against the shipped plan helper (`plan.mjs`) | pass/fail |
| `tests/ci-observability.mjs` | validates command timing records, wall-time reconstruction, and CI host metadata | pass/fail |
| `tests/test-contracts.mjs` | validates the closed test-contract registry and its discovered, registered, selected, and executed sets | pass/fail |
| `tests/author-tooling.mjs` | author-tool contracts: Biome rejects a syntax defect, combined skill validation, tree/guard operational failures, skills-guard spawn failure; this table lists every `scripts/**/*.mjs` outside `lib/`, `tests/unit/`, and the non-validator entry points `release.mjs`/`ci-target.mjs`/`capture-tdd-red.mjs`, and every first-column `.mjs` path resolves from `scripts/` or the repo root | pass/fail |
| `tests/author-tooling.mjs` | author-tool contracts: Biome rejects a syntax defect, combined skill validation, tree/guard operational failures, skills-guard spawn failure; this table lists every `scripts/**/*.mjs` outside `lib/`, `tests/unit/`, `tests/plan-cli/`, and the non-validator entry points `release.mjs`/`ci-target.mjs`/`capture-tdd-red.mjs`, and every first-column `.mjs` path resolves from `scripts/` or the repo root | pass/fail |
| `tests/ci-plugin-targeting.mjs` | CI targeting and release contracts: shard selection, `ci.yml` trigger block, release module and dry-run safety (`--unit` in the gate) | pass/fail |
| shellcheck (target-selected) | `-S warning` over selected plugins' `hooks/*.sh`, via `shellHooks(p)`; a full invocation selects every plugin | pass/warn |

Expand Down
38 changes: 38 additions & 0 deletions scripts/config/test-contracts.json
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,44 @@
"selection": {
"kind": "node-test-file",
"selector": "scripts/tests/unit/ci-background-task.test.mjs",
"expected_min": 4
},
"platforms": ["linux", "macos"],
"toolchains": ["node-24"],
"release_role": "gate",
"replaces": [],
"skips": []
},
{
"id": "unit-ci-background-task-blocked-lifetime",
"version": 1,
"title": "Ci Background Task blocked lifetime unit contracts",
"owner": {
"suite": "scripts/tests/unit/ci-background-task-blocked-lifetime.test.mjs",
"layer": "unit"
},
"selection": {
"kind": "node-test-file",
"selector": "scripts/tests/unit/ci-background-task-blocked-lifetime.test.mjs",
"expected_min": 1
},
"platforms": ["linux", "macos"],
"toolchains": ["node-24"],
"release_role": "gate",
"replaces": [],
"skips": []
},
{
"id": "unit-ci-background-task-pipe-backpressure",
"version": 1,
"title": "Ci Background Task pipe backpressure unit contracts",
"owner": {
"suite": "scripts/tests/unit/ci-background-task-pipe-backpressure.test.mjs",
"layer": "unit"
},
"selection": {
"kind": "node-test-file",
"selector": "scripts/tests/unit/ci-background-task-pipe-backpressure.test.mjs",
"expected_min": 1
},
"platforms": ["linux", "macos"],
Expand Down
4 changes: 2 additions & 2 deletions scripts/lib/ci-background-task.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export const RUN_ORIGIN_NS = process.hrtime.bigint();
// runs, which is the same defect with a smaller error bar. The launcher below is a separate OS
// process, so the kernel schedules it independently of this loop. It measures its own child with one
// monotonic clock and reports the lifetime; the parent only has to place that interval on its own
// timeline. Verify: run a 1 s child behind a 2.5 s blocking `spawnSync` and read the recorded
// duration (`bun test ./scripts/tests/unit/ci-background-task.test.mjs`).
// timeline. Verify: run a 300 ms child behind a 1 s blocking `spawnSync` and read the recorded
// duration (`bun test ./scripts/tests/unit/ci-background-task-blocked-lifetime.test.mjs`).
const LAUNCHER_SOURCE = [
"import { spawn } from 'node:child_process';",
"import fs from 'node:fs';",
Expand Down
6 changes: 4 additions & 2 deletions scripts/tests/author-tooling.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ function testTreeGuardOperationalFailures() {

// scripts/AGENTS.md validator table: every validator script has a row, every row resolves.
// lib/ holds shared modules (a lib validator may still have a row); tests/unit/ runs as one
// suite; the allowlist names entry points that are not validators.
// suite, and the tests/plan-cli/ case files run as one suite through the tests/plan-cli.mjs row;
// the allowlist names entry points that are not validators.
const NON_VALIDATOR_SCRIPTS = new Set(['release.mjs', 'ci-target.mjs', 'capture-tdd-red.mjs']);

function validatorTableErrors(root) {
Expand All @@ -199,7 +200,8 @@ function validatorTableErrors(root) {
const full = path.join(dir, e.name);
const rel = path.relative(scriptsDir, full).split(path.sep).join('/');
if (e.isDirectory()) {
if (e.name !== 'node_modules' && rel !== 'lib' && rel !== 'tests/unit') walkScripts(full);
if (e.name !== 'node_modules' && rel !== 'lib' && rel !== 'tests/unit' && rel !== 'tests/plan-cli')
walkScripts(full);
} else if (e.isFile() && e.name.endsWith('.mjs') && !NON_VALIDATOR_SCRIPTS.has(rel)) onDisk.push(rel);
}
})(scriptsDir);
Expand Down
Loading
Loading