From 0e62081417b8a1cf51cc39b9a0c54807e94ba419 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 26 Aug 2026 23:25:29 +0000 Subject: [PATCH] refactor(ce-packs): make ce-brainstorm the canonical packs-resolve copy Drive resolver unit tests from skills/ce-brainstorm/scripts/packs-resolve.py and record that path as the canonical copy in the packs plan. The five skill copies stay byte-identical. Co-authored-by: Kieran Klaassen --- .../2026-08-26-001-feat-ce-packs-config-sources-plan.md | 2 +- tests/skills/ce-packs-resolver.test.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/plans/2026-08-26-001-feat-ce-packs-config-sources-plan.md b/docs/plans/2026-08-26-001-feat-ce-packs-config-sources-plan.md index 931c4178f..d548d6559 100644 --- a/docs/plans/2026-08-26-001-feat-ce-packs-config-sources-plan.md +++ b/docs/plans/2026-08-26-001-feat-ce-packs-config-sources-plan.md @@ -204,7 +204,7 @@ U1 (script) first; U2 (script tests + parity) with it. U3 (ce-plan rewire) and U - **Goal:** One script turns the two config files into a validated, resolved pack-root list with per-entry warnings and errors. - **Requirements:** R1-R7, R11, R12 - **Dependencies:** none -- **Files:** `skills/ce-plan/scripts/packs-resolve.py` (canonical copy), `skills/ce-brainstorm/scripts/packs-resolve.py`, `skills/ce-setup/scripts/packs-resolve.py` (byte-identical duplicates) +- **Files:** `skills/ce-brainstorm/scripts/packs-resolve.py` (canonical copy), `skills/ce-plan/scripts/packs-resolve.py`, `skills/ce-setup/scripts/packs-resolve.py` (byte-identical duplicates) - **Approach:** Stdlib-only Python. Read `packs:` from `config.yaml` then `config.local.yaml` (missing files fine; both lists concatenate in that order, each entry tagged with its origin file for error messages). Per entry: classify source kind, normalizing a GitHub tree URL to url + ref + `path:` (conflict with explicit fields errors); enforce R3 ref rules; validate paths per KTD-4; resolve git sources through the KTD-3 cache (atomic temp-clone-then-rename on miss, reuse on hit; fetch/auth failure under the non-interactive git environment -> warning, entry skipped); scope the source root by `path:` when present; enumerate published packs per R6 (immediate children only); apply `pack:` selection and `id:` override; detect duplicate resolved ids across all entries (R7, both entries named, neither installs). Emit JSON to stdout: `{roots: [{id, dir}], warnings: [...], errors: [...]}` — exit 0 whenever a parse was possible (per-entry failures are data), nonzero only on catastrophic failure. No third-party YAML dependency: parse the `packs:` block with a minimal reader whose accepted subset is pinned — block-list entries, flow (`[a, b]`) and block lists for `pack:`, quoted and bare scalars, full-line and trailing comments — and any line under `packs:` the reader cannot classify is a loud error naming the file and line, never a silent skip. - **Patterns to follow:** `skills/ce-plan/scripts/peer-job-runner.py` (scratch-root preamble, non-interactive subprocess discipline, per-skill duplication, stdlib-only); the deleted `repo-profile-cache.py` remains in git history (`git show c184234b^:skills/ce-plan/scripts/repo-profile-cache.py`) for its cache-keying and JSON-out shape. - **Test scenarios:** covered in U2 (the script is exercised only through its tests and callers). diff --git a/tests/skills/ce-packs-resolver.test.ts b/tests/skills/ce-packs-resolver.test.ts index 91d14930e..06f92f128 100644 --- a/tests/skills/ce-packs-resolver.test.ts +++ b/tests/skills/ce-packs-resolver.test.ts @@ -6,12 +6,14 @@ import { afterAll, describe, expect, setDefaultTimeout, test } from "bun:test" // Deterministic proof for the CE Packs resolver (plan AE1-AE7): fixture repos // and file:// git sources built per test, cache isolated via CE_PACKS_CACHE_ROOT. +// Exercise the canonical ce-brainstorm copy; the other skill copies stay +// byte-identical via the parity test below. setDefaultTimeout(30000) -const RESOLVER = path.join(process.cwd(), "skills/ce-plan/scripts/packs-resolve.py") +const RESOLVER = path.join(process.cwd(), "skills/ce-brainstorm/scripts/packs-resolve.py") const COPIES = [ - "skills/ce-plan/scripts/packs-resolve.py", "skills/ce-brainstorm/scripts/packs-resolve.py", + "skills/ce-plan/scripts/packs-resolve.py", "skills/ce-setup/scripts/packs-resolve.py", "skills/ce-code-review/scripts/packs-resolve.py", "skills/ce-doc-review/scripts/packs-resolve.py",