|
| 1 | +# `npx autoskills` recommender (v2.5.3) Implementation Plan |
| 2 | + |
| 3 | +> **For agentic workers:** REQUIRED SUB-SKILL: superpowers:test-driven-development for the toolkit task. |
| 4 | +
|
| 5 | +**Goal:** `/v:onboard` recommends `npx autoskills` (present-only) for a recognizable stack, previews it behind a gated `--dry-run`, and cautions about auto-trigger degradation — never auto-installs. |
| 6 | + |
| 7 | +**Architecture:** A small `recommend-autoskills` subcommand + `recommend_autoskills()` detector in `scripts/compound-v-onboard.py`; prose wiring in `onboarding.md` (DIAGNOSE + §11) and `v-onboard.md`. |
| 8 | + |
| 9 | +**Tech Stack:** Python 3.9 stdlib, Markdown docs, JSON version files. |
| 10 | + |
| 11 | +## Global Constraints |
| 12 | +- **Never auto-install** — onboarding runs at most `npx autoskills --dry-run`, only behind a human confirm; the real install is the user's action. |
| 13 | +- **External `npx` is untrusted** — any invocation goes through `compound-v-run-with-timeout.py` with `stdin </dev/null` (the v2.5.0 launch invariant). |
| 14 | +- **Auto-trigger caution always surfaced** (overlapping skills degrade triggering — onboarding §11). |
| 15 | +- **Deterministic + evidence-cited** — cite the marker file; unknown repo ⇒ `applicable: false`. |
| 16 | +- **Version lockstep:** `plugin.json` + `marketplace.json` → `2.5.3`. |
| 17 | + |
| 18 | +## File Partition |
| 19 | +| Task | Files | |
| 20 | +|---|---| |
| 21 | +| T1 | `scripts/compound-v-onboard.py` (detector + subcommand + selftest) | |
| 22 | +| T2 | `skills/compound-v/onboarding.md`, `commands/v-onboard.md` | |
| 23 | +| T3 | `.claude-plugin/plugin.json`, `.claude-plugin/marketplace.json`, `CHANGELOG.md` | |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +### Task 1: `recommend_autoskills()` detector + subcommand |
| 28 | +**Files:** Modify `scripts/compound-v-onboard.py` |
| 29 | + |
| 30 | +**Interfaces (Produces):** `recommend_autoskills(repo) -> {applicable: bool, evidence: str|None, command: str|None, caution: str|None}`; CLI `recommend-autoskills --repo .`. |
| 31 | + |
| 32 | +- [ ] Step 1: Add constants + function (near the MCP recommender helpers): |
| 33 | + |
| 34 | +```python |
| 35 | +AUTOSKILLS_MARKERS = ("package.json", "pyproject.toml", "requirements.txt", "Gemfile", |
| 36 | + "go.mod", "Cargo.toml", "composer.json", "pom.xml", "build.gradle") |
| 37 | +AUTOSKILLS_CAUTION = ("autoskills installs multiple stack skills; overlapping skill descriptions " |
| 38 | + "can degrade auto-triggering across your WHOLE skill set (onboarding Skills " |
| 39 | + "stance). Review the --dry-run and prefer a focused subset before installing.") |
| 40 | + |
| 41 | + |
| 42 | +def recommend_autoskills(repo): |
| 43 | + """`npx autoskills` applicability: any recognizable project manifest means it can match stack |
| 44 | + skills. Present-only — the gated --dry-run + the user-run install are the onboarding walk's job. |
| 45 | + Returns {applicable, evidence, command, caution}.""" |
| 46 | + ev = None |
| 47 | + for marker in AUTOSKILLS_MARKERS: |
| 48 | + if os.path.isfile(os.path.join(repo, marker)): |
| 49 | + ev = marker |
| 50 | + break |
| 51 | + if ev is None: |
| 52 | + try: |
| 53 | + if any(f.endswith(".tf") for f in os.listdir(repo)): |
| 54 | + ev = "*.tf" |
| 55 | + except OSError: |
| 56 | + pass |
| 57 | + if ev is None: |
| 58 | + return {"applicable": False, "evidence": None, "command": None, "caution": None} |
| 59 | + return {"applicable": True, "evidence": ev, |
| 60 | + "command": "npx autoskills --dry-run", "caution": AUTOSKILLS_CAUTION} |
| 61 | +``` |
| 62 | + |
| 63 | +- [ ] Step 2: Add the subcommand in `build_parser` (after `recommend-mcp`): |
| 64 | + |
| 65 | +```python |
| 66 | + sp = sub.add_parser("recommend-autoskills"); sp.add_argument("--repo", default=".") |
| 67 | + sp.add_argument("--json", action="store_true") |
| 68 | +``` |
| 69 | + |
| 70 | +and in `main` (before the help fallback): |
| 71 | + |
| 72 | +```python |
| 73 | + if args.cmd == "recommend-autoskills": |
| 74 | + print(json.dumps(recommend_autoskills(os.path.abspath(args.repo)), indent=2)) |
| 75 | + return 0 |
| 76 | +``` |
| 77 | + |
| 78 | +- [ ] Step 3: Selftest (append inside the recommend-mcp `try:` block or a fresh tempdir): |
| 79 | + |
| 80 | +```python |
| 81 | + # --- recommend-autoskills (v2.5.3) --- |
| 82 | + d8 = tempfile.mkdtemp() |
| 83 | + try: |
| 84 | + with open(os.path.join(d8, "package.json"), "w") as fh: |
| 85 | + fh.write("{}") |
| 86 | + r8 = recommend_autoskills(d8) |
| 87 | + check("autoskills: package.json -> applicable, evidence, --dry-run command", |
| 88 | + r8["applicable"] and r8["evidence"] == "package.json" |
| 89 | + and r8["command"] == "npx autoskills --dry-run" and r8["caution"]) |
| 90 | + finally: |
| 91 | + shutil.rmtree(d8, ignore_errors=True) |
| 92 | + d8b = tempfile.mkdtemp() |
| 93 | + try: |
| 94 | + with open(os.path.join(d8b, "pyproject.toml"), "w") as fh: |
| 95 | + fh.write("[project]\n") |
| 96 | + check("autoskills: pyproject.toml -> applicable", |
| 97 | + recommend_autoskills(d8b)["applicable"] is True) |
| 98 | + os.remove(os.path.join(d8b, "pyproject.toml")) |
| 99 | + check("autoskills: empty repo -> not applicable", |
| 100 | + recommend_autoskills(d8b)["applicable"] is False) |
| 101 | + finally: |
| 102 | + shutil.rmtree(d8b, ignore_errors=True) |
| 103 | +``` |
| 104 | + |
| 105 | +- [ ] Step 4: `python3 scripts/compound-v-onboard.py --selftest` → OK. CLI smoke on this repo → `applicable: false`. Commit. |
| 106 | + |
| 107 | +--- |
| 108 | + |
| 109 | +### Task 2: Onboarding wiring |
| 110 | +**Files:** Modify `skills/compound-v/onboarding.md`, `commands/v-onboard.md` |
| 111 | + |
| 112 | +- [ ] In `onboarding.md` DIAGNOSE (next to the MCP recommender): add the autoskills recommendation — run `recommend-autoskills`; if applicable, surface it + the caution, and **behind a human confirm** run `npx autoskills --dry-run` **through `compound-v-run-with-timeout.py` with `</dev/null`** to preview the skills; **never** the install form; decline ⇒ just recommend the user run it themselves. Add the §11 note that autoskills is the recommended third-party-skill path (present-only + cautioned). |
| 113 | +- [ ] In `v-onboard.md`: extend the finish-report line to mention the autoskills recommendation (present-only, gated `--dry-run`, never auto-installed). |
| 114 | +- [ ] `lint-frontmatter.py` clean. Commit. |
| 115 | + |
| 116 | +--- |
| 117 | + |
| 118 | +### Task 3: Version + CHANGELOG + release |
| 119 | +**Files:** `.claude-plugin/plugin.json`, `.claude-plugin/marketplace.json`, `CHANGELOG.md` |
| 120 | + |
| 121 | +- [ ] Full regression (all script selftests + lint + CI lockstep) green. |
| 122 | +- [ ] Dogfood `recommend-autoskills` on superpowers-v (→ `applicable: false`, the negative path). |
| 123 | +- [ ] Codex cross-model verify (detector + gated-runner invariants; supervised + `</dev/null`). |
| 124 | +- [ ] Both versions → `2.5.3`; `CHANGELOG.md` `[2.5.3]`. Commit, merge `--no-ff` to main, verify, push, CI green. |
| 125 | + |
| 126 | +## Self-Review |
| 127 | +Spec §4.1 → T1; §4.2/§4.3 → T2; §5 invariants → T1 (evidence, applicable-false) + T2 (supervisor/`</dev/null`, never-install, caution); §6 → T1 selftest + T3 dogfood/Codex; §7 out-of-scope respected. No placeholders. `recommend_autoskills` return shape consistent across T1/T2. |
0 commit comments