slash-do 2.10.0 → 2.12.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/README.md CHANGED
@@ -24,7 +24,7 @@
24
24
  <p align="center">
25
25
  <img src="https://img.shields.io/npm/v/slash-do?style=flat-square&color=blue" alt="npm version" />
26
26
  <img src="https://img.shields.io/badge/environments-4-green?style=flat-square" alt="environments" />
27
- <img src="https://img.shields.io/badge/commands-14-orange?style=flat-square" alt="commands" />
27
+ <img src="https://img.shields.io/badge/commands-15-orange?style=flat-square" alt="commands" />
28
28
  <img src="https://img.shields.io/badge/license-MIT-lightgrey?style=flat-square" alt="license" />
29
29
  </p>
30
30
 
@@ -56,12 +56,14 @@ All commands live under the `do:` namespace:
56
56
  |:---|:---|
57
57
  | `/do:push` | Commit and push all work with changelog |
58
58
  | `/do:pr` | Open a PR with self-review and Copilot review loop |
59
+ | `/do:pr-better` | Run a full do:better audit on the current branch, commit fixes directly, then open a single PR |
59
60
  | `/do:fpr` | Fork PR -- push to fork, PR against upstream |
60
61
  | `/do:rpr` | Resolve PR review feedback with parallel agents |
61
62
  | `/do:release` | Create a release PR with version bump and changelog |
62
63
  | `/do:review` | Deep code review against best practices |
63
64
  | `/do:better` | Full DevSecOps audit with 8-agent scan and remediation |
64
65
  | `/do:better-swift` | SwiftUI DevSecOps audit with multi-platform coverage |
66
+ | `/do:scan` | Read-only safety audit of an unfamiliar directory — flags malware patterns, network calls, and vulnerable deps without executing code |
65
67
  | `/do:depfree` | Audit dependencies, remove unnecessary ones, write replacement code |
66
68
  | `/do:goals` | Generate GOALS.md from codebase analysis |
67
69
  | `/do:replan` | Review and clean up PLAN.md |
@@ -67,6 +67,7 @@ Key behavioral changes when `HEAVY_MODE` is `true`:
67
67
 
68
68
  When compacting during this workflow, always preserve:
69
69
  - The `DEPENDENCY_MAP` (complete classification of all dependencies)
70
+ - The `PRIOR_DECISIONS` map loaded from `./docs/DEPS.md`
70
71
  - All REMOVABLE findings with package names and usage details
71
72
  - The current phase number and what phases remain
72
73
  - All PR numbers and URLs created so far
@@ -111,6 +112,26 @@ Record as `BUILD_CMD` and `TEST_CMD`.
111
112
  - Record `DEFAULT_BRANCH` via `gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'` (or `glab` equivalent)
112
113
  - Record `IS_DIRTY` via `git status --porcelain`
113
114
 
115
+ ### 0e: Load Prior Decisions
116
+
117
+ Read `{REPO_DIR}/docs/DEPS.md` if it exists. This file records decisions from prior `/do:depfree` runs and is used to skip re-evaluation of dependencies that have already been audited.
118
+
119
+ Parse the file into `PRIOR_DECISIONS` — a map keyed by package name, with values:
120
+ - `decision`: one of `KEPT_TIER1`, `KEPT_AUDITED`, `KEPT_TRANSITIVE`, `REMOVED`, `REVERTED`, `SKIPPED_INFEASIBLE`
121
+ - `major_version`: the major version that was evaluated (e.g., `18` for react@18.x)
122
+ - `mode`: the mode the decision was made under (`default`, `heavy`, or `both`)
123
+ - `reason`: the rationale recorded
124
+ - `decision_date`: ISO date the decision was made
125
+
126
+ If the file does not exist, set `PRIOR_DECISIONS` to an empty map. The file will be created in Phase 4c only when remediation runs proceed past the scan-only phases (i.e., `--scan-only` was not passed).
127
+
128
+ A prior decision is **valid for skipping re-evaluation** when ALL of these are true:
129
+ 1. The package is still in the manifest at the same major version
130
+ 2. The recorded mode matches the current run mode (a `default` decision does NOT skip a `heavy` run; `both` skips either; `heavy` skips a `default` run)
131
+ 3. The decision is not `REMOVED` or `REVERTED` (those packages should not be in the manifest; if they are, treat as new)
132
+
133
+ Otherwise, the dependency is re-evaluated in Phase 1 normally.
134
+
114
135
 
115
136
  ## Phase 1: Dependency Inventory
116
137
 
@@ -138,7 +159,15 @@ Based on `PROJECT_TYPE`, extract the full dependency list:
138
159
 
139
160
  ### 1b: Classify Dependencies
140
161
 
141
- For each dependency, classify it into one of three tiers:
162
+ For each dependency, first check `PRIOR_DECISIONS` (from Phase 0e). If a valid prior decision exists for the package + major version + mode, carry it forward:
163
+ - `KEPT_TIER1` → classify as **Tier 1** (skip further audit)
164
+ - `KEPT_AUDITED` → classify as **Tier 2** with recommendation **KEEP** (skip Phase 1c usage analysis)
165
+ - `KEPT_TRANSITIVE` → classify as **Tier 2** with recommendation **KEEP (transitive)** (skip Phase 1c usage analysis and Phase 1d transitive check; the prior `Kept Via` chain is recorded)
166
+ - `SKIPPED_INFEASIBLE` → classify as **Tier 2** with recommendation **KEEP** (skip Phase 1c usage analysis)
167
+
168
+ Record carried-forward decisions in `DEPENDENCY_MAP` with a `from_prior: true` flag. Print one line per skipped dependency: `↻ {package}@{major} — carrying forward prior {decision} ({decision_date})`.
169
+
170
+ For all other dependencies (no prior decision, major version bump, or mode escalation from default → heavy), classify it into one of three tiers:
142
171
 
143
172
  **Tier 1 — ACCEPTABLE (keep without question):**
144
173
  Large, widely-audited, foundational libraries. Examples by ecosystem:
@@ -217,7 +246,7 @@ Record the full classification as `DEPENDENCY_MAP`.
217
246
 
218
247
  ### 1c: Usage Analysis (Tier 2 & 3 only)
219
248
 
220
- For each Tier 2 and Tier 3 dependency, launch parallel Explore agents (using `AUDIT_MODEL`) to determine actual usage:
249
+ Skip any dependency with `from_prior: true` (carried forward from Phase 1b). For all remaining Tier 2 and Tier 3 dependencies, launch parallel Explore agents (using `AUDIT_MODEL`) to determine actual usage:
221
250
 
222
251
  Each agent should:
223
252
  1. Search all source files for imports/requires of the package
@@ -455,7 +484,75 @@ After all replacement agents complete:
455
484
  - Correct error handling at system boundaries
456
485
  3. Fix any issues found, commit each fix separately
457
486
 
458
- ### 4c: Verify No Phantom Dependencies
487
+ ### 4c: Update DEPS.md
488
+
489
+ Write the consolidated decision record to `{WORKTREE_DIR}/docs/DEPS.md`. Create the `docs/` directory if it does not exist.
490
+
491
+ Build the new file from:
492
+ 1. **All carried-forward entries** from `PRIOR_DECISIONS` whose packages are still in the manifest at the same major version (preserve `decision_date` and `mode`)
493
+ 2. **New decisions** from this run:
494
+ - Each Tier 1 package → `KEPT_TIER1`
495
+ - Each Tier 2 package with KEEP recommendation → `KEPT_AUDITED`
496
+ - Each Tier 2/3 package downgraded to KEEP (transitive) in Phase 1d → `KEPT_TRANSITIVE`
497
+ - Each successfully removed package → `REMOVED`
498
+ - Each reverted package (replacement failed in 4a) → `REVERTED`
499
+ - Each skipped package (replacement infeasible / >2x estimate / >300 lines in heavy) → `SKIPPED_INFEASIBLE`
500
+ 3. **Mode merging**: if a prior decision was `default` and this run is `heavy` (or vice versa) and both runs reached the same conclusion for the same package + major version, set `mode` to `both`. Otherwise the new run's mode overwrites.
501
+
502
+ Use this layout:
503
+
504
+ ```markdown
505
+ # Dependency Audit Decisions
506
+
507
+ Auto-maintained by `/do:depfree`. Records prior audit decisions so repeat runs
508
+ skip re-evaluation. Re-audit triggers: major version bump, heavy-mode run after
509
+ default-mode decision, or manual deletion of an entry.
510
+
511
+ Last updated: {YYYY-MM-DD}
512
+
513
+ ## Kept — Tier 1 (foundational)
514
+
515
+ | Package | Major | Mode | Reviewed | Reason |
516
+ |---------|-------|------|----------|--------|
517
+ | ... | ... | ... | ... | ... |
518
+
519
+ ## Kept — Tier 2 (audited)
520
+
521
+ | Package | Major | Mode | Reviewed | Reason |
522
+ |---------|-------|------|----------|--------|
523
+
524
+ ## Kept — Transitive
525
+
526
+ | Package | Major | Mode | Reviewed | Kept Via |
527
+ |---------|-------|------|----------|----------|
528
+
529
+ ## Removed
530
+
531
+ | Package | Major | Mode | Removed | Replacement |
532
+ |---------|-------|------|---------|-------------|
533
+
534
+ ## Reverted (replacement failed, kept in manifest)
535
+
536
+ | Package | Major | Mode | Reviewed | Reason |
537
+ |---------|-------|------|----------|--------|
538
+
539
+ ## Skipped (replacement infeasible)
540
+
541
+ | Package | Major | Mode | Reviewed | Reason |
542
+ |---------|-------|------|----------|--------|
543
+ ```
544
+
545
+ Sort each section alphabetically by package name.
546
+
547
+ Commit the change (only if the file actually changed):
548
+ ```bash
549
+ git -C {WORKTREE_DIR} add -- docs/DEPS.md
550
+ if ! git -C {WORKTREE_DIR} diff --cached --quiet -- docs/DEPS.md; then
551
+ git -C {WORKTREE_DIR} commit -m "docs: update DEPS.md with audit decisions"
552
+ fi
553
+ ```
554
+
555
+ ### 4d: Verify No Phantom Dependencies
459
556
 
460
557
  Confirm no source file still references a removed package:
461
558
  ```bash
@@ -518,7 +615,9 @@ Estimated supply chain attack surface reduction: {N} packages ({transitive count
518
615
  - [ ] Build passes
519
616
  - [ ] All tests pass
520
617
  - [ ] No phantom references to removed packages
521
- - [ ] Lock file updated"
618
+ - [ ] Lock file updated
619
+ - [ ] \`docs/DEPS.md\` updated with audit decisions
620
+ "
522
621
 
523
622
  gh pr create --head depfree/{DATE} --base {DEFAULT_BRANCH} \
524
623
  --title "$PR_TITLE" \
@@ -622,6 +721,7 @@ Transitive deps eliminated: ~{count} (estimated)
622
721
 
623
722
  - This command complements `/do:better` — run `depfree` for dependency hygiene, `better` for code quality
624
723
  - All remediation happens in an isolated worktree — the user's working directory is never modified
724
+ - `docs/DEPS.md` is the persistent decision log. It is read at the start of every run (Phase 0e) to skip re-evaluation of unchanged dependencies, and rewritten at the end of Phase 4c with the merged set of prior + current decisions. Major version bumps and heavy-mode escalations bypass the cache. Manually delete an entry to force re-audit on the next run
625
725
  - **Default mode**: the threshold for "acceptable" libraries is deliberately generous — the goal is to remove obvious attack surface, not to rewrite everything
626
726
  - **Heavy mode**: the threshold narrows to foundational frameworks only — the goal is to own as much code as feasibly possible, eliminating supply chain risk from individual maintainers and small projects
627
727
  - Replacement code should be minimal and focused — don't over-engineer utilities that replace single-purpose packages
@@ -20,11 +20,13 @@ List all available `/do:*` commands with their descriptions.
20
20
  | `/do:help` | List all available slashdo commands |
21
21
  | `/do:omd` | Audit and optimize markdown files (CLAUDE.md, README.md, etc.) against best practices |
22
22
  | `/do:pr` | Commit, push, and open a PR against the repo's default branch |
23
+ | `/do:pr-better` | Run a full do:better audit on the current branch, commit fixes directly, then open a single PR |
23
24
  | `/do:push` | Commit and push all work with changelog |
24
25
  | `/do:release` | Create a release PR using the project's documented release workflow |
25
26
  | `/do:replan` | Review and clean up PLAN.md, extract docs from completed work |
26
27
  | `/do:review` | Deep code review of changed files against best practices |
27
28
  | `/do:rpr` | Resolve PR review feedback with parallel agents |
29
+ | `/do:scan` | Read-only safety audit of an unfamiliar directory — flags malware patterns, network calls, and vulnerable deps without executing code |
28
30
  | `/do:update` | Update slashdo commands to the latest version |
29
31
 
30
32
  2. **Check for updates**: Run `npm view slash-do version` and compare to the installed version in `~/.claude/.slashdo-version`. If an update is available, mention it.
@@ -0,0 +1,94 @@
1
+ ---
2
+ description: Run a full do:better audit/remediation on the current branch, commit fixes directly to it, then open a single PR with do:pr
3
+ argument-hint: "[--interactive] [path filter or focus areas]"
4
+ ---
5
+
6
+ # PR-Better — Better Audit + Single PR
7
+
8
+ Run the full `do:better` DevSecOps audit and remediation, but **commit all fixes directly to the current branch** instead of creating per-category PRs. Then hand off to `do:pr` so the entire result ships as one cohesive PR (with self-review and the Copilot review loop).
9
+
10
+ This is the right command when:
11
+ - You want the full `do:better` quality bar on a feature branch you're about to ship
12
+ - You want a single PR (not 8 per-category PRs) so reviewers see one cohesive change
13
+ - You're already on a feature branch and want all audit fixes folded into the same PR as your feature work
14
+
15
+ ## Argument Forwarding
16
+
17
+ Pass `$ARGUMENTS` through to `do:better` verbatim, with these constraints applied automatically:
18
+ - **`--scan-only` is incompatible** — if the user passes it, refuse and explain that pr-better must remediate
19
+ - **`--no-merge` is incompatible** — pr-better always produces a PR, but as one combined PR via `do:pr`
20
+ - All other flags (`--interactive`, path filter, focus areas) pass through unchanged
21
+
22
+ ## Pre-flight
23
+
24
+ 1. Run `git branch --show-current` and `gh repo view --json defaultBranchRef -q '.defaultBranchRef.name'`
25
+ 2. If the current branch is the default branch, halt and tell the user: pr-better needs a feature branch — either create one first or run `/do:better` directly to produce per-category PRs from default
26
+ 3. Run `git status --porcelain` — if dirty, the do:better Phase 3a stash will handle it, but warn the user that uncommitted changes will be stashed and restored after the audit
27
+
28
+ ## Phase A: Run do:better (constrained to "Commit directly")
29
+
30
+ Execute the full `do:better` workflow defined in `~/.claude/commands/do/better.md` with these mandatory deviations:
31
+
32
+ ### Phase 0 → 4a: unchanged
33
+ Run discovery, audit (all 8 agents), plan generation, worktree setup, foundation utilities, parallel remediation, build/test verification, and internal code review exactly as specified in `do:better`.
34
+
35
+ ### Phase 4b: Force the "Commit directly" path
36
+
37
+ When you reach Phase 4b's decision point, **do not present the AskUserQuestion** and **do not proceed to per-category PR creation**. Instead, always take the "Commit directly" path:
38
+
39
+ - Ensure all worktree changes are committed in `better/{DATE}`
40
+ - Return to `{REPO_DIR}`, check out `{CURRENT_BRANCH}`, and merge `better/{DATE}` into it:
41
+ ```bash
42
+ cd {REPO_DIR}
43
+ git checkout {CURRENT_BRANCH}
44
+ if git merge better/{DATE}; then
45
+ git worktree remove {WORKTREE_DIR}
46
+ git branch -D better/{DATE}
47
+ else
48
+ echo "Merge conflict — resolve in {REPO_DIR}, then run:"
49
+ echo " git worktree remove {WORKTREE_DIR}"
50
+ echo " git branch -D better/{DATE}"
51
+ # halt and surface the conflict to the user
52
+ fi
53
+ ```
54
+ - If a merge conflict surfaces, stop here and ask the user to resolve before continuing to Phase B
55
+ - Restore the stash if Phase 3a stashed changes (`git stash pop`)
56
+
57
+ ### Phase 4c: Test Enhancement
58
+
59
+ Run Phase 4c (test enhancement) **before** the merge-back if the worktree is still active, so the new/fixed tests ship in the same merge. The Phase 4c.3 `FILE_OWNER_MAP` update is unnecessary in pr-better (we're not building per-category branches), so skip that step.
60
+
61
+ ### Phases 5, 6, 7: SKIP entirely
62
+
63
+ Do not create category branches. Do not bump the version (the user's PR is responsible for any version bump via the project's normal release flow). Do not run the Copilot review loop here — `do:pr` will run it once on the combined PR. Do not delete branches you didn't create.
64
+
65
+ The only Phase 7-equivalent housekeeping that applies:
66
+ - Update PLAN.md to mark completed findings as `[x]` and note any skipped findings with reasons. Stage these changes so the next phase commits them as part of the PR.
67
+ - Print the final summary table from Phase 7 (with PR fields blank — they'll be filled by Phase B).
68
+
69
+ ## Phase B: Run do:pr
70
+
71
+ After Phase A leaves all fixes committed on `{CURRENT_BRANCH}`, hand off to the workflow defined in `~/.claude/commands/do/pr.md`:
72
+
73
+ 1. **Detect branches** — already done in pre-flight, reuse those values
74
+ 2. **Commit and push** — commit any remaining staged changes (e.g., the PLAN.md update), then `git pull --rebase --autostash && git push -u origin {current_branch}`
75
+ 3. **Local Code Review (REQUIRED GATE)** — run the full review gate from `do:pr`. The do:better Phase 4b internal review covered the worktree diff against the default branch, but the do:pr review gate also covers any prior commits on the feature branch that predate this run. Do not skip it.
76
+ 4. **Open the PR** — create a single PR with a description that summarizes both:
77
+ - The original feature work on the branch (from prior commits)
78
+ - The do:better audit findings now folded in (categories, counts, severity)
79
+ 5. **Copilot review loop** — runs once on the combined PR via the standard `do:pr` flow
80
+
81
+ ## Final Report
82
+
83
+ Print:
84
+ - The do:better summary table (categories, findings fixed/skipped) — with the PR column populated by the single PR URL
85
+ - Test enhancement stats (vacuous fixed, weak strengthened, new cases, new files)
86
+ - The PR URL
87
+ - Final review status (clean / comments addressed / left open)
88
+
89
+ ## Notes
90
+
91
+ - This is **not** equivalent to running `/do:better --no-merge` then `/do:pr`. `--no-merge` still creates per-category branches and PRs (it just skips the Copilot/merge step). pr-better never creates per-category branches at all.
92
+ - Conflict-avoidance machinery from do:better Phase 5 (FILE_OWNER_MAP, backward-compatible re-exports across PRs) is unnecessary here — everything lands on one branch in one merge.
93
+ - The user's existing feature commits remain intact; do:better remediation is added as additional commits on top.
94
+ - If do:better finds zero actionable CRITICAL/HIGH/MEDIUM findings, skip Phase A's Phase 3-4 entirely and run only Phase B (`do:pr`) — the audit served as a quality gate even when nothing needed fixing.
@@ -22,7 +22,13 @@ CLAUDE.md is already loaded into your context. Use its rules (code style, error
22
22
  Before dispatching agents, understand what this change set claims to do:
23
23
 
24
24
  1. Read commit messages (`git log {base}...HEAD --oneline`)
25
- 2. Note the claims verify after agents return whether the code actually delivers them.
25
+ 2. Read PLAN.md, .changelog/NEXT.md (or equivalent), and the PR description for capability claims, test counts, and "deep-links to X" / "feature Y now works" assertions
26
+ 3. Note the claims — verify after agents return whether the code actually delivers them. Concrete drift to flag:
27
+ - Test counts in PLAN/changelog vs `find . -name '*.test.*' -exec grep -c '^\(it\|test\)(' {} +` (or project equivalent)
28
+ - "Deep-links to record X" claims vs whether the destination route handler actually consumes the encoded parameter
29
+ - "Auto-prune after N days" / "scans only the page returned" claims vs the listing implementation
30
+ - Comments in code claiming behavior the surrounding code doesn't perform
31
+ - Field names quoted in docs (request body shape, event payload shape) vs what the code actually reads/emits
26
32
 
27
33
  ## Dispatch Review Agents
28
34
 
@@ -87,12 +87,12 @@ Verify the request was accepted by checking that `Copilot` appears in the respon
87
87
 
88
88
  ### Poll for review completion
89
89
 
90
- Poll using GraphQL to check for a new review with a `submittedAt` timestamp after the request:
90
+ Poll using GraphQL to check for a new review with a `submittedAt` timestamp after the request. Use stdin JSON piping (per the GraphQL escaping guidance) to avoid shell-quoting fragility:
91
91
  ```bash
92
- gh api graphql -f query='{ repository(owner: "OWNER", name: "REPO") { pullRequest(number: PR_NUM) { reviews(last: 3) { nodes { state body author { login } submittedAt } } reviewThreads(first: 100) { nodes { id isResolved comments(first: 3) { nodes { body path line author { login } } } } } } } }'
92
+ echo '{"query":"{ repository(owner: \"OWNER\", name: \"REPO\") { pullRequest(number: PR_NUM) { reviews(last: 3) { nodes { state body author { login } submittedAt } } reviewThreads(first: 100) { nodes { id isResolved comments(first: 3) { nodes { body path line author { login } } } } } } } }"}' | gh api graphql --input -
93
93
  ```
94
94
 
95
- **Dynamic poll timing**: Before your first poll, check how long the most recent Copilot review on this PR took by comparing consecutive Copilot review `submittedAt` timestamps (or PR creation time for the first review). Use that duration as your expected wait. If no prior review exists, default to 5 minutes. Use **progressive poll intervals**: 15s, 15s, 30s, 30s, then 60s thereafter — small diffs often complete in under a minute, so early frequent checks avoid wasting time. Set max wait to **2x the expected duration** (minimum 5 minutes, maximum 20 minutes). Copilot reviews can take **10-15 minutes** for large diffs do NOT give up early.
95
+ **Dynamic poll timing**: Before your first poll, check how long the most recent Copilot review on this PR took by comparing consecutive Copilot review `submittedAt` timestamps (or PR creation time for the first review). Use that duration as your expected wait. If no prior review exists, default to **60 seconds**. Use **progressive poll intervals**: 5s, 5s, 10s, 10s, then 15s thereafter — Copilot reviews on small diffs typically land in **30–90 seconds**, so an early first check avoids burning a full minute on a review that's already sitting in the API. Set max wait to **3x the expected duration** (minimum 90 seconds, maximum 5 minutes); only large diffs (200+ changed lines) should ever approach the max. If the review hasn't arrived by then, treat it as stuck rather than slow.
96
96
 
97
97
  The review is complete when a new `copilot-pull-request-reviewer` review node appears. If no review appears after max wait: **Default mode**: auto-skip and continue. **Interactive mode (`--interactive`)**: ask the user whether to continue waiting, re-request, or skip.
98
98