slash-do 1.9.0 → 2.1.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 +3 -2
- package/commands/do/better-swift.md +28 -10
- package/commands/do/better.md +59 -18
- package/commands/do/depfree.md +525 -0
- package/commands/do/goals.md +26 -15
- package/commands/do/help.md +1 -0
- package/commands/do/release.md +9 -4
- package/commands/do/replan.md +35 -10
- package/commands/do/review.md +30 -2
- package/commands/do/rpr.md +15 -5
- package/lib/code-review-checklist.md +19 -12
- package/lib/copilot-review-loop.md +10 -5
- package/package.json +1 -1
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Audit third-party dependencies and remove unnecessary ones by writing replacement code
|
|
3
|
+
argument-hint: "[--interactive] [--scan-only] [--no-merge] [specific packages to evaluate]"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Depfree — Dependency Freedom Audit
|
|
7
|
+
|
|
8
|
+
Audit all third-party dependencies, classify them as acceptable (large, widely-audited) or suspect (small, replaceable), analyze actual usage of suspect dependencies, and replace them with owned code where feasible.
|
|
9
|
+
|
|
10
|
+
Every small library is an attack surface. Supply chain compromises are real and common. Large, widely-audited libraries (express, react, d3, three.js, next, vue, fastify, lodash-es, etc.) are acceptable. But for smaller libraries or libraries where only one helper function is used, we should write the code ourselves.
|
|
11
|
+
|
|
12
|
+
**Default mode: fully autonomous.** Uses Balanced model profile, proceeds through all phases without prompting.
|
|
13
|
+
|
|
14
|
+
**`--interactive` mode:** Pauses for classification approval, replacement review, and merge confirmation.
|
|
15
|
+
|
|
16
|
+
Parse `$ARGUMENTS` for:
|
|
17
|
+
- **`--interactive`**: pause at each decision point for user approval
|
|
18
|
+
- **`--scan-only`**: run Phase 0 + 1 + 2 only (audit and plan), skip remediation
|
|
19
|
+
- **`--no-merge`**: run through PR creation, skip merge
|
|
20
|
+
- **Specific packages**: limit audit scope to named packages (e.g., "chalk dotenv")
|
|
21
|
+
|
|
22
|
+
## Configuration
|
|
23
|
+
|
|
24
|
+
### Default Mode (autonomous)
|
|
25
|
+
|
|
26
|
+
Use the **Balanced** model profile automatically (`AUDIT_MODEL=sonnet`, `REMEDIATION_MODEL=sonnet`).
|
|
27
|
+
|
|
28
|
+
### Interactive Mode (`--interactive`)
|
|
29
|
+
|
|
30
|
+
Present the user with configuration options using `AskUserQuestion`:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
AskUserQuestion([{
|
|
34
|
+
question: "Which model profile for audit and remediation agents?",
|
|
35
|
+
header: "Model",
|
|
36
|
+
multiSelect: false,
|
|
37
|
+
options: [
|
|
38
|
+
{ label: "Quality", description: "Opus for all agents — fewest false positives, best replacements (highest cost)" },
|
|
39
|
+
{ label: "Balanced (Recommended)", description: "Sonnet for audit and remediation — good quality at moderate cost" },
|
|
40
|
+
{ label: "Budget", description: "Haiku for audit, Sonnet for remediation — fastest and cheapest" }
|
|
41
|
+
]
|
|
42
|
+
}])
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Record the selection as `MODEL_PROFILE` and derive:
|
|
46
|
+
- `AUDIT_MODEL`: `opus` / `sonnet` / `haiku` based on profile
|
|
47
|
+
- `REMEDIATION_MODEL`: `opus` / `sonnet` / `sonnet` based on profile
|
|
48
|
+
|
|
49
|
+
When the resolved model is `opus`, **omit** the `model` parameter on the Agent call so the agent inherits the session's Opus version.
|
|
50
|
+
|
|
51
|
+
## Compaction Guidance
|
|
52
|
+
|
|
53
|
+
When compacting during this workflow, always preserve:
|
|
54
|
+
- The `DEPENDENCY_MAP` (complete classification of all dependencies)
|
|
55
|
+
- All REMOVABLE findings with package names and usage details
|
|
56
|
+
- The current phase number and what phases remain
|
|
57
|
+
- All PR numbers and URLs created so far
|
|
58
|
+
- `BUILD_CMD`, `TEST_CMD`, `PROJECT_TYPE`, `WORKTREE_DIR`, `REPO_DIR` values
|
|
59
|
+
- `VCS_HOST`, `CLI_TOOL`, `DEFAULT_BRANCH`, `CURRENT_BRANCH`
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
## Phase 0: Discovery & Setup
|
|
63
|
+
|
|
64
|
+
### 0a: VCS Host Detection
|
|
65
|
+
Run `gh auth status` to check GitHub CLI. If it fails, run `glab auth status` for GitLab.
|
|
66
|
+
- Set `VCS_HOST` to `github` or `gitlab`
|
|
67
|
+
- Set `CLI_TOOL` to `gh` or `glab`
|
|
68
|
+
- If neither is authenticated, warn the user and halt
|
|
69
|
+
|
|
70
|
+
### 0b: Project Type Detection
|
|
71
|
+
Check for project manifests to determine the tech stack:
|
|
72
|
+
- `package.json` → Node.js (check for `next`, `react`, `vue`, `express`, etc.)
|
|
73
|
+
- `Cargo.toml` → Rust
|
|
74
|
+
- `pyproject.toml` / `requirements.txt` / `setup.py` → Python
|
|
75
|
+
- `go.mod` → Go
|
|
76
|
+
- `pom.xml` / `build.gradle` → Java/Kotlin
|
|
77
|
+
- `Gemfile` → Ruby
|
|
78
|
+
- `*.csproj` / `*.sln` → .NET
|
|
79
|
+
|
|
80
|
+
Record the detected stack as `PROJECT_TYPE`.
|
|
81
|
+
|
|
82
|
+
### 0c: Build & Test Command Detection
|
|
83
|
+
Derive build and test commands from the project type:
|
|
84
|
+
- Node.js: check `package.json` scripts for `build`, `test`, `typecheck`, `lint`
|
|
85
|
+
- Rust: `cargo build`, `cargo test`
|
|
86
|
+
- Python: `pytest`, `python -m pytest`
|
|
87
|
+
- Go: `go build ./...`, `go test ./...`
|
|
88
|
+
- If ambiguous, check project conventions already in context
|
|
89
|
+
|
|
90
|
+
Record as `BUILD_CMD` and `TEST_CMD`.
|
|
91
|
+
|
|
92
|
+
### 0d: State Snapshot
|
|
93
|
+
- Record `REPO_DIR` via `git rev-parse --show-toplevel`
|
|
94
|
+
- Record `CURRENT_BRANCH` via `git rev-parse --abbrev-ref HEAD`
|
|
95
|
+
- Record `DEFAULT_BRANCH` via `gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'` (or `glab` equivalent)
|
|
96
|
+
- Record `IS_DIRTY` via `git status --porcelain`
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
## Phase 1: Dependency Inventory
|
|
100
|
+
|
|
101
|
+
### 1a: Extract All Dependencies
|
|
102
|
+
|
|
103
|
+
Based on `PROJECT_TYPE`, extract the full dependency list:
|
|
104
|
+
|
|
105
|
+
**Node.js:**
|
|
106
|
+
- Read `package.json` → `dependencies` and `devDependencies`
|
|
107
|
+
- Note: `devDependencies` used only in build/test are lower priority but still worth auditing
|
|
108
|
+
- Check for workspace packages (monorepo) in `workspaces` field
|
|
109
|
+
|
|
110
|
+
**Rust:**
|
|
111
|
+
- Read `Cargo.toml` → `[dependencies]`, `[dev-dependencies]`, `[build-dependencies]`
|
|
112
|
+
|
|
113
|
+
**Python:**
|
|
114
|
+
- Read `pyproject.toml` → `[project.dependencies]`, `[project.optional-dependencies]`
|
|
115
|
+
- Or `requirements.txt`, `setup.py`
|
|
116
|
+
|
|
117
|
+
**Go:**
|
|
118
|
+
- Read `go.mod` → `require` block
|
|
119
|
+
|
|
120
|
+
**Ruby:**
|
|
121
|
+
- Read `Gemfile`
|
|
122
|
+
|
|
123
|
+
### 1b: Classify Dependencies
|
|
124
|
+
|
|
125
|
+
For each dependency, classify it into one of three tiers:
|
|
126
|
+
|
|
127
|
+
**Tier 1 — ACCEPTABLE (keep without question):**
|
|
128
|
+
Large, widely-audited, foundational libraries. Examples by ecosystem:
|
|
129
|
+
- **Node.js**: react, next, vue, express, fastify, hono, typescript, eslint, prettier, webpack, vite, jest, vitest, mocha, d3, three, prisma, drizzle, @types/*, tailwindcss, postcss
|
|
130
|
+
- **Rust**: tokio, serde, clap, reqwest, hyper, tracing, sqlx, axum, actix-web
|
|
131
|
+
- **Python**: django, flask, fastapi, sqlalchemy, pandas, numpy, scipy, pytest, requests, httpx, pydantic
|
|
132
|
+
- **Go**: standard library (no third-party needed for most things)
|
|
133
|
+
- **Ruby**: rails, rspec, sidekiq, puma, devise
|
|
134
|
+
- Any dependency with >10M weekly downloads (npm) or equivalent popularity metric for the ecosystem
|
|
135
|
+
|
|
136
|
+
**Tier 2 — SUSPECT (audit usage):**
|
|
137
|
+
Smaller libraries that may be doing something we can write ourselves. Indicators:
|
|
138
|
+
- <1M weekly downloads (npm) or equivalent
|
|
139
|
+
- Single-purpose utility (does one thing)
|
|
140
|
+
- We only use 1-2 functions from it
|
|
141
|
+
- Wrapper libraries that add thin abstractions over built-in APIs
|
|
142
|
+
- Libraries that replicate functionality available in newer language/runtime versions
|
|
143
|
+
- Abandoned or unmaintained (no commits in 12+ months, open security issues)
|
|
144
|
+
|
|
145
|
+
**Tier 3 — REMOVABLE (strong candidate for replacement):**
|
|
146
|
+
Libraries where the cost of owning the code is clearly lower than the supply chain risk:
|
|
147
|
+
- We use a single function that's <50 lines to implement
|
|
148
|
+
- The library wraps a built-in API with minimal added value
|
|
149
|
+
- The library is unmaintained with known vulnerabilities
|
|
150
|
+
- The library's functionality is now available natively (e.g., `node:fs/promises` replacing `fs-extra` for most use cases, `structuredClone` replacing `lodash.cloneDeep`, `Array.prototype.flat` replacing `array-flatten`)
|
|
151
|
+
- Color/string utilities where we use 1-2 functions (e.g., using `chalk` just for `chalk.red()` when a 10-line ANSI wrapper suffices)
|
|
152
|
+
- UUID generation when `crypto.randomUUID()` is available
|
|
153
|
+
- Deep merge/clone when `structuredClone` suffices
|
|
154
|
+
- `dotenv` when the runtime supports `--env-file` natively
|
|
155
|
+
- `is-odd`, `is-number`, `left-pad` tier micro-packages
|
|
156
|
+
|
|
157
|
+
Record the full classification as `DEPENDENCY_MAP`.
|
|
158
|
+
|
|
159
|
+
### 1c: Usage Analysis (Tier 2 & 3 only)
|
|
160
|
+
|
|
161
|
+
For each Tier 2 and Tier 3 dependency, launch parallel Explore agents (using `AUDIT_MODEL`) to determine actual usage:
|
|
162
|
+
|
|
163
|
+
Each agent should:
|
|
164
|
+
1. Search all source files for imports/requires of the package
|
|
165
|
+
2. List every function, class, constant, or type imported from it
|
|
166
|
+
3. Count call sites per imported symbol
|
|
167
|
+
4. Assess complexity of replacement:
|
|
168
|
+
- **Trivial** (<20 lines): simple wrapper, single utility function, type alias
|
|
169
|
+
- **Moderate** (20-100 lines): multi-function utility, needs tests, edge cases to handle
|
|
170
|
+
- **Complex** (100-300 lines): significant logic, crypto, parsing, protocol implementation
|
|
171
|
+
- **Infeasible** (300+ lines or requires deep domain expertise): keep the dependency
|
|
172
|
+
5. Check if the package has known vulnerabilities: `npm audit`, `cargo audit`, `pip-audit`, etc.
|
|
173
|
+
6. Check last publish date and maintenance status
|
|
174
|
+
|
|
175
|
+
Report format:
|
|
176
|
+
```
|
|
177
|
+
- **{package-name}** — Tier {2|3}
|
|
178
|
+
- Imports: {list of imported symbols}
|
|
179
|
+
- Call sites: {count} across {N} files
|
|
180
|
+
- Functions used: {list with brief description of each}
|
|
181
|
+
- Replacement complexity: {Trivial|Moderate|Complex|Infeasible}
|
|
182
|
+
- Maintenance: {last publish date, open issues, known CVEs}
|
|
183
|
+
- Recommendation: **REMOVE** / **KEEP** / **EVALUATE**
|
|
184
|
+
- Replacement sketch: {brief description of how to replace, if REMOVE}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Wait for all agents to complete before proceeding.
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
## Phase 2: Replacement Plan
|
|
191
|
+
|
|
192
|
+
1. Read the existing `PLAN.md` (create if it doesn't exist)
|
|
193
|
+
2. Filter to only REMOVE recommendations from Phase 1c
|
|
194
|
+
3. For EVALUATE recommendations: **Default mode** — treat as KEEP (conservative). **Interactive mode** — present to user via `AskUserQuestion` for each
|
|
195
|
+
4. Group removable dependencies by replacement strategy:
|
|
196
|
+
- **Native replacement**: built-in API replaces the library (e.g., `crypto.randomUUID()`)
|
|
197
|
+
- **Inline replacement**: write a small utility function (e.g., ANSI color wrapper)
|
|
198
|
+
- **Consolidation**: multiple small deps replaced by one owned utility module
|
|
199
|
+
5. Estimate total lines of replacement code needed
|
|
200
|
+
6. Add a new section to PLAN.md:
|
|
201
|
+
|
|
202
|
+
```markdown
|
|
203
|
+
## Depfree Audit - {YYYY-MM-DD}
|
|
204
|
+
|
|
205
|
+
Summary: {N} total dependencies. {A} acceptable (Tier 1), {B} audited and kept (Tier 2), {C} to remove (Tier 3).
|
|
206
|
+
Estimated replacement code: ~{lines} lines across {files} new/modified files.
|
|
207
|
+
|
|
208
|
+
### Dependencies to Remove
|
|
209
|
+
| Package | Tier | Used Functions | Call Sites | Replacement | Complexity | Risk |
|
|
210
|
+
|---------|------|---------------|------------|-------------|------------|------|
|
|
211
|
+
| ... | ... | ... | ... | ... | ... | ... |
|
|
212
|
+
|
|
213
|
+
### Dependencies Kept (with rationale)
|
|
214
|
+
| Package | Tier | Reason Kept |
|
|
215
|
+
|---------|------|-------------|
|
|
216
|
+
| ... | ... | ... |
|
|
217
|
+
|
|
218
|
+
### Replacement Tasks
|
|
219
|
+
For each dependency to remove:
|
|
220
|
+
- [ ] **{package}** — {strategy}. Replace {N} call sites in {M} files. Write {utility name} ({est. lines} lines). Complexity: {level}.
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
7. Print summary table:
|
|
224
|
+
```
|
|
225
|
+
| Status | Count | Examples |
|
|
226
|
+
|------------|-------|-----------------------------------|
|
|
227
|
+
| Acceptable | ... | react, express, typescript, ... |
|
|
228
|
+
| Kept | ... | {packages kept with reasons} |
|
|
229
|
+
| Removable | ... | {packages to remove} |
|
|
230
|
+
| Total | ... | |
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**GATE: If `--scan-only` was passed, STOP HERE.** Print the summary and exit.
|
|
234
|
+
|
|
235
|
+
**GATE: If no removable dependencies were found, print "All dependencies are justified" and exit.**
|
|
236
|
+
|
|
237
|
+
**Interactive mode**: Present the removal plan via `AskUserQuestion`:
|
|
238
|
+
```
|
|
239
|
+
AskUserQuestion([{
|
|
240
|
+
question: "Dependency removal plan:\n{summary of packages to remove}\n\nProceed with replacement?",
|
|
241
|
+
options: [
|
|
242
|
+
{ label: "Proceed", description: "Remove all listed dependencies and write replacement code" },
|
|
243
|
+
{ label: "Review individually", description: "Let me approve/reject each removal" },
|
|
244
|
+
{ label: "Abort", description: "Stop here — I'll review the plan manually" }
|
|
245
|
+
]
|
|
246
|
+
}])
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
If "Review individually": present each dependency with REMOVE/KEEP options, then proceed with only approved removals.
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
## Phase 3: Worktree Remediation
|
|
253
|
+
|
|
254
|
+
### 3a: Setup
|
|
255
|
+
|
|
256
|
+
1. If `IS_DIRTY` is true: `git stash --include-untracked -m "depfree: pre-audit stash"`
|
|
257
|
+
2. Set `DATE` to today's date in YYYY-MM-DD format
|
|
258
|
+
3. Create the worktree:
|
|
259
|
+
```bash
|
|
260
|
+
git worktree add ../depfree-{DATE} -b depfree/{DATE}
|
|
261
|
+
```
|
|
262
|
+
4. Set `WORKTREE_DIR` to `../depfree-{DATE}`
|
|
263
|
+
|
|
264
|
+
### 3b: Write Replacement Code
|
|
265
|
+
|
|
266
|
+
For each dependency to remove, spawn a general-purpose agent (using `REMEDIATION_MODEL`) with these instructions:
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
<context>
|
|
270
|
+
Project type: {PROJECT_TYPE}
|
|
271
|
+
Build command: {BUILD_CMD}
|
|
272
|
+
Test command: {TEST_CMD}
|
|
273
|
+
Working directory: {WORKTREE_DIR} (this is a git worktree — all work happens here)
|
|
274
|
+
</context>
|
|
275
|
+
|
|
276
|
+
<task>
|
|
277
|
+
Remove the dependency on `{PACKAGE_NAME}` and replace with owned code.
|
|
278
|
+
|
|
279
|
+
Current usage:
|
|
280
|
+
{USAGE_DETAILS from Phase 1c — imported symbols, call sites, files}
|
|
281
|
+
|
|
282
|
+
Replacement strategy: {STRATEGY from Phase 2}
|
|
283
|
+
|
|
284
|
+
Steps:
|
|
285
|
+
1. Write the replacement code (utility function, inline replacement, or native API call)
|
|
286
|
+
2. Update ALL import/require statements across the codebase to use the new code
|
|
287
|
+
3. Remove the package from the manifest ({package.json, Cargo.toml, etc.})
|
|
288
|
+
4. Run `{BUILD_CMD}` to verify compilation
|
|
289
|
+
5. Run `{TEST_CMD}` to verify tests pass
|
|
290
|
+
6. If tests reference the removed package directly (mocking it, importing test helpers from it), update those tests too
|
|
291
|
+
</task>
|
|
292
|
+
|
|
293
|
+
<guardrails>
|
|
294
|
+
- The replacement must preserve behavior for all currently-used call sites and documented invariants
|
|
295
|
+
- You may omit handling for input shapes or edge cases that are provably unreachable based on {USAGE_DETAILS}, but do not narrow behavior for any actual call site
|
|
296
|
+
- Do NOT introduce new dependencies to replace old ones
|
|
297
|
+
- Do NOT use `git add -A` or `git add .` — stage specific files only
|
|
298
|
+
- Keep replacement code minimal
|
|
299
|
+
- If replacement is more complex than estimated (>2x the estimated lines), report back and skip — do not force a bad replacement
|
|
300
|
+
- Place shared utility replacements in a sensible location (e.g., `src/utils/`, `lib/`, `internal/`) following existing project conventions
|
|
301
|
+
- Commit each replacement independently: `refactor: replace {package} with owned {utility/code}`
|
|
302
|
+
</guardrails>
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**Parallelization**: Launch up to 5 agents in parallel. If >5 dependencies to remove, batch them. Assign each agent a non-overlapping set of dependencies (no two agents should modify the same files — if overlap exists, group those dependencies into one agent).
|
|
306
|
+
|
|
307
|
+
### 3c: Lock File Update
|
|
308
|
+
|
|
309
|
+
After all replacement agents complete:
|
|
310
|
+
1. Remove all replaced packages from the lock file:
|
|
311
|
+
```bash
|
|
312
|
+
cd {WORKTREE_DIR}
|
|
313
|
+
# Node.js: refresh lockfile only, without running lifecycle scripts
|
|
314
|
+
npm install --package-lock-only --ignore-scripts
|
|
315
|
+
# Or: yarn install --mode=update-lockfile --ignore-scripts
|
|
316
|
+
# Or: pnpm install --lockfile-only --ignore-scripts
|
|
317
|
+
# Rust: let a check refresh Cargo.lock to reflect manifest changes only
|
|
318
|
+
cargo check
|
|
319
|
+
# Python: use the project's lock tool to refresh
|
|
320
|
+
# poetry lock --no-update
|
|
321
|
+
# pip-compile requirements.in
|
|
322
|
+
```
|
|
323
|
+
2. Commit the lock file update:
|
|
324
|
+
```bash
|
|
325
|
+
git -C {WORKTREE_DIR} add {lock file}
|
|
326
|
+
git -C {WORKTREE_DIR} commit -m "chore: update lock file after dependency removal"
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
## Phase 4: Verification
|
|
331
|
+
|
|
332
|
+
### 4a: Build & Test
|
|
333
|
+
|
|
334
|
+
1. Run the full build:
|
|
335
|
+
```bash
|
|
336
|
+
cd {WORKTREE_DIR} && {BUILD_CMD}
|
|
337
|
+
```
|
|
338
|
+
2. Run all tests:
|
|
339
|
+
```bash
|
|
340
|
+
cd {WORKTREE_DIR} && {TEST_CMD}
|
|
341
|
+
```
|
|
342
|
+
3. If build or tests fail:
|
|
343
|
+
- Identify which replacement caused the failure
|
|
344
|
+
- Attempt to fix in a new commit
|
|
345
|
+
- If unfixable, revert the replacement commit AND re-add the dependency:
|
|
346
|
+
```bash
|
|
347
|
+
git -C {WORKTREE_DIR} revert <sha>
|
|
348
|
+
```
|
|
349
|
+
Note the reverted package as "kept — replacement failed"
|
|
350
|
+
|
|
351
|
+
### 4b: Internal Code Review
|
|
352
|
+
|
|
353
|
+
1. Generate the diff:
|
|
354
|
+
```bash
|
|
355
|
+
cd {WORKTREE_DIR} && git diff {DEFAULT_BRANCH}...HEAD
|
|
356
|
+
```
|
|
357
|
+
2. Review all replacement code for:
|
|
358
|
+
- Functional equivalence (does the replacement handle the same inputs/outputs?)
|
|
359
|
+
- Missing edge cases that the original library handled
|
|
360
|
+
- Security regressions (e.g., replacing a sanitization library with a naive regex)
|
|
361
|
+
- Performance regressions (e.g., replacing an optimized parser with O(n^2) code)
|
|
362
|
+
- Correct error handling at system boundaries
|
|
363
|
+
3. Fix any issues found, commit each fix separately
|
|
364
|
+
|
|
365
|
+
### 4c: Verify No Phantom Dependencies
|
|
366
|
+
|
|
367
|
+
Confirm no source file still references a removed package:
|
|
368
|
+
```bash
|
|
369
|
+
cd {WORKTREE_DIR}
|
|
370
|
+
for pkg in {REMOVED_PACKAGES}; do
|
|
371
|
+
grep -r "$pkg" \
|
|
372
|
+
--include='*.ts' \
|
|
373
|
+
--include='*.js' \
|
|
374
|
+
--include='*.tsx' \
|
|
375
|
+
--include='*.jsx' \
|
|
376
|
+
--include='*.py' \
|
|
377
|
+
--include='*.rs' \
|
|
378
|
+
--include='*.go' \
|
|
379
|
+
--include='*.rb' \
|
|
380
|
+
. && echo "WARN: $pkg still referenced"
|
|
381
|
+
done
|
|
382
|
+
```
|
|
383
|
+
Fix any remaining references.
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
## Phase 5: PR Creation
|
|
387
|
+
|
|
388
|
+
### 5a: Push & Create PR
|
|
389
|
+
|
|
390
|
+
```bash
|
|
391
|
+
cd {WORKTREE_DIR}
|
|
392
|
+
git push -u origin depfree/{DATE}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Create the PR:
|
|
396
|
+
|
|
397
|
+
**GitHub:**
|
|
398
|
+
```bash
|
|
399
|
+
gh pr create --head depfree/{DATE} --base {DEFAULT_BRANCH} \
|
|
400
|
+
--title "refactor: remove {N} unnecessary dependencies" \
|
|
401
|
+
--body "$(cat <<'EOF'
|
|
402
|
+
## Depfree Audit — Dependency Removal
|
|
403
|
+
|
|
404
|
+
### Summary
|
|
405
|
+
Removed {N} unnecessary third-party dependencies and replaced with owned code.
|
|
406
|
+
Estimated supply chain attack surface reduction: {N} packages ({transitive count} including transitive deps).
|
|
407
|
+
|
|
408
|
+
### Dependencies Removed
|
|
409
|
+
| Package | Replacement | Lines of Owned Code |
|
|
410
|
+
|---------|-------------|-------------------|
|
|
411
|
+
{table of removed packages}
|
|
412
|
+
|
|
413
|
+
### Dependencies Kept (audited)
|
|
414
|
+
{count} dependencies audited and kept with rationale. See PLAN.md for details.
|
|
415
|
+
|
|
416
|
+
### Replacement Code
|
|
417
|
+
{bulleted list of new utility files or inline changes}
|
|
418
|
+
|
|
419
|
+
### Verification
|
|
420
|
+
- [ ] Build passes
|
|
421
|
+
- [ ] All tests pass
|
|
422
|
+
- [ ] No phantom references to removed packages
|
|
423
|
+
- [ ] Lock file updated
|
|
424
|
+
EOF
|
|
425
|
+
)"
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
**GitLab:**
|
|
429
|
+
```bash
|
|
430
|
+
glab mr create --source-branch depfree/{DATE} --target-branch {DEFAULT_BRANCH} \
|
|
431
|
+
--title "refactor: remove {N} unnecessary dependencies" --description "..."
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
Record `PR_NUMBER` and `PR_URL`.
|
|
435
|
+
|
|
436
|
+
**GATE: If `--no-merge` was passed, STOP HERE.** Print the PR URL and summary.
|
|
437
|
+
|
|
438
|
+
### 5b: CI Verification
|
|
439
|
+
|
|
440
|
+
1. Wait 30 seconds for CI to start
|
|
441
|
+
2. Poll CI status:
|
|
442
|
+
```bash
|
|
443
|
+
gh pr checks {PR_NUMBER}
|
|
444
|
+
```
|
|
445
|
+
Poll every 30 seconds, max 10 minutes.
|
|
446
|
+
3. If CI fails:
|
|
447
|
+
- Fetch failure logs, diagnose, fix, commit, push
|
|
448
|
+
- Max 3 fix attempts before informing the user
|
|
449
|
+
|
|
450
|
+
### 5c: Copilot Review Loop (GitHub only)
|
|
451
|
+
|
|
452
|
+
If `VCS_HOST` is `github`, run the Copilot review loop using the shared template:
|
|
453
|
+
|
|
454
|
+
!`cat ~/.claude/lib/copilot-review-loop.md`
|
|
455
|
+
|
|
456
|
+
Pass: `{PR_NUMBER}`, `{OWNER}/{REPO}`, `depfree/{DATE}`, and `{BUILD_CMD}`.
|
|
457
|
+
|
|
458
|
+
### 5d: Merge
|
|
459
|
+
|
|
460
|
+
**Default mode**: Auto-merge if review is clean.
|
|
461
|
+
**Interactive mode**: Ask user for merge approval.
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
gh pr merge {PR_NUMBER} --merge
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
## Phase 6: Cleanup
|
|
469
|
+
|
|
470
|
+
1. Remove the worktree:
|
|
471
|
+
```bash
|
|
472
|
+
git worktree remove {WORKTREE_DIR}
|
|
473
|
+
```
|
|
474
|
+
2. Delete the local branch:
|
|
475
|
+
```bash
|
|
476
|
+
git checkout {DEFAULT_BRANCH}
|
|
477
|
+
git branch -D depfree/{DATE}
|
|
478
|
+
git push origin --delete depfree/{DATE}
|
|
479
|
+
```
|
|
480
|
+
3. Restore stashed changes if applicable:
|
|
481
|
+
```bash
|
|
482
|
+
git stash pop
|
|
483
|
+
```
|
|
484
|
+
4. Update PLAN.md:
|
|
485
|
+
- Mark completed removals with `[x]`
|
|
486
|
+
- Add PR link
|
|
487
|
+
- Note any packages that were reverted
|
|
488
|
+
5. Print the final summary:
|
|
489
|
+
|
|
490
|
+
```
|
|
491
|
+
| Package | Status | Replacement | Lines |
|
|
492
|
+
|------------------|----------|--------------------------|-------|
|
|
493
|
+
| {package} | Removed | {utility/native API} | {N} |
|
|
494
|
+
| {package} | Kept | {reason} | — |
|
|
495
|
+
| {package} | Reverted | {reason for failure} | — |
|
|
496
|
+
|
|
497
|
+
Total dependencies before: {before}
|
|
498
|
+
Total dependencies after: {after}
|
|
499
|
+
Packages removed: {count}
|
|
500
|
+
Owned replacement code: ~{lines} lines
|
|
501
|
+
Transitive deps eliminated: ~{count} (estimated)
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
## Error Recovery
|
|
506
|
+
|
|
507
|
+
- **Agent failure**: continue with remaining agents, note gaps in the summary
|
|
508
|
+
- **Build failure in worktree**: attempt fix; if unfixable, revert the problematic replacement and re-add the dependency
|
|
509
|
+
- **Push failure**: `git pull --rebase --autostash` then retry push
|
|
510
|
+
- **CI failure on PR**: investigate logs, fix, push (max 3 attempts)
|
|
511
|
+
- **Replacement too complex**: if an agent reports that replacement exceeds 2x estimated complexity, skip that dependency and keep it with a note
|
|
512
|
+
- **Test failure from replacement**: if tests fail and the fix isn't obvious, revert the replacement — a working dependency is better than broken owned code
|
|
513
|
+
- **Existing worktree found at startup**: ask user — resume or clean up
|
|
514
|
+
|
|
515
|
+
!`cat ~/.claude/lib/graphql-escaping.md`
|
|
516
|
+
|
|
517
|
+
## Notes
|
|
518
|
+
|
|
519
|
+
- This command complements `/do:better` — run `depfree` for dependency hygiene, `better` for code quality
|
|
520
|
+
- All remediation happens in an isolated worktree — the user's working directory is never modified
|
|
521
|
+
- The threshold for "acceptable" libraries is deliberately generous — the goal is to remove obvious attack surface, not to rewrite everything
|
|
522
|
+
- Replacement code should be minimal and focused — don't over-engineer utilities that replace single-purpose packages
|
|
523
|
+
- When in doubt, keep the dependency. A maintained library is better than a buggy reimplementation
|
|
524
|
+
- devDependencies are lower priority since they don't ship to production, but unmaintained build tools still pose supply chain risk
|
|
525
|
+
- For monorepos, audit the root manifest and each workspace package manifest
|
package/commands/do/goals.md
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Scan codebase to infer project goals
|
|
3
|
-
argument-hint: "[--refresh] [focus hint, e.g. 'just the CLI']"
|
|
2
|
+
description: Scan codebase to infer project goals and generate GOALS.md (default: fully autonomous; use --interactive to review with user)
|
|
3
|
+
argument-hint: "[--interactive] [--refresh] [focus hint, e.g. 'just the CLI']"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Goals — Generate a GOALS.md from Codebase Analysis
|
|
7
7
|
|
|
8
|
-
Scan the codebase to infer the project's goals, purpose, and direction, then
|
|
8
|
+
Scan the codebase to infer the project's goals, purpose, and direction, then generate a comprehensive `GOALS.md` at the repo root.
|
|
9
|
+
|
|
10
|
+
**Default mode: fully autonomous.** Scans the codebase, synthesizes goals, and writes GOALS.md without prompting. HIGH and MEDIUM confidence goals are included; LOW confidence goals are included but marked as inferred.
|
|
11
|
+
|
|
12
|
+
**`--interactive` mode:** Pauses after synthesis to validate purpose, prioritize goals, confirm non-goals, and refine wording with the user.
|
|
9
13
|
|
|
10
14
|
Parse `$ARGUMENTS` for:
|
|
15
|
+
- **`--interactive`**: pause after synthesis for user validation and refinement
|
|
11
16
|
- **`--refresh`**: re-scan and update an existing GOALS.md rather than creating from scratch
|
|
12
17
|
- **Focus hints**: e.g., "focus on API goals", "just the CLI"
|
|
13
18
|
|
|
@@ -94,29 +99,35 @@ For each goal, assign a confidence level:
|
|
|
94
99
|
- **MEDIUM** — strongly implied by patterns, architecture, or recent work
|
|
95
100
|
- **LOW** — inferred/speculative, needs user confirmation
|
|
96
101
|
|
|
97
|
-
## Phase 3:
|
|
102
|
+
## Phase 3: Validation
|
|
103
|
+
|
|
104
|
+
### Default Mode (autonomous)
|
|
105
|
+
|
|
106
|
+
Skip user clarification. Include all HIGH and MEDIUM confidence goals directly. Include LOW confidence goals but mark them with `(inferred)` so the user can review after generation. Proceed directly to Phase 4.
|
|
107
|
+
|
|
108
|
+
### Interactive Mode (`--interactive`)
|
|
98
109
|
|
|
99
110
|
Present the draft to the user and ask targeted questions to resolve uncertainty. Use `AskUserQuestion` for each area that needs input.
|
|
100
111
|
|
|
101
|
-
|
|
112
|
+
#### 3a: Purpose Validation
|
|
102
113
|
Show the inferred one-paragraph purpose statement. Ask if it's accurate or needs refinement.
|
|
103
114
|
|
|
104
|
-
|
|
115
|
+
#### 3b: Goal Prioritization
|
|
105
116
|
Present the inferred goals list. For each LOW or MEDIUM confidence goal, ask the user:
|
|
106
117
|
- Is this actually a goal?
|
|
107
118
|
- How would you rephrase it?
|
|
108
119
|
- What priority is it (primary, secondary, stretch)?
|
|
109
120
|
|
|
110
|
-
|
|
121
|
+
#### 3c: Missing Goals
|
|
111
122
|
Ask: "Are there any goals I missed that aren't yet reflected in the codebase?" Present 2-3 suggested possibilities based on common patterns for this type of project, to prompt the user's thinking.
|
|
112
123
|
|
|
113
|
-
|
|
124
|
+
#### 3d: Non-Goals Validation
|
|
114
125
|
Present the inferred non-goals. Ask: "Are these accurate? Anything to add or remove?"
|
|
115
126
|
|
|
116
|
-
|
|
127
|
+
#### 3e: Target Users
|
|
117
128
|
Present the inferred target user description. Ask if it's accurate.
|
|
118
129
|
|
|
119
|
-
|
|
130
|
+
#### 3f: Success Criteria (optional)
|
|
120
131
|
Ask: "Would you like to define measurable success criteria for any of these goals?" Offer examples relevant to the project type (e.g., "support N concurrent users", "< Xms response time", "100% test coverage on core module").
|
|
121
132
|
|
|
122
133
|
## Phase 4: Document Generation
|
|
@@ -190,9 +201,9 @@ If `--refresh` was passed and `GOALS.md` already exists:
|
|
|
190
201
|
1. Read the existing `GOALS.md`
|
|
191
202
|
2. Compare existing goals against current codebase state
|
|
192
203
|
3. Identify goals whose status has changed (new progress, completed, abandoned)
|
|
193
|
-
4.
|
|
194
|
-
|
|
195
|
-
|
|
204
|
+
4. **Default mode**: Update the document in-place automatically, preserving user-written content where possible. Print a summary of what changed.
|
|
205
|
+
**Interactive mode (`--interactive`)**: Present changes to the user for confirmation before updating.
|
|
206
|
+
5. If any checkbox task lists are found in the existing GOALS.md, move them to PLAN.md automatically (default) or offer to move them (interactive)
|
|
196
207
|
|
|
197
208
|
## Phase 5: Finalize
|
|
198
209
|
|
|
@@ -211,8 +222,8 @@ If `--refresh` was passed and `GOALS.md` already exists:
|
|
|
211
222
|
## Notes
|
|
212
223
|
|
|
213
224
|
- This command is project-agnostic — it reads whatever project signals exist
|
|
214
|
-
-
|
|
215
|
-
- LOW confidence inferences
|
|
225
|
+
- In default mode, scan and generate autonomously; in interactive mode, collaborate with the user
|
|
226
|
+
- LOW confidence inferences are included as `(inferred)` in default mode; validated with the user in interactive mode
|
|
216
227
|
- Preserve the user's voice — if they provide rephrased goals, use their wording verbatim
|
|
217
228
|
- If the project is brand new with minimal code, lean more heavily on user input and less on codebase inference
|
|
218
229
|
- If `gh` CLI is not authenticated, skip issue/PR scanning gracefully — don't halt
|
package/commands/do/help.md
CHANGED
|
@@ -14,6 +14,7 @@ List all available `/do:*` commands with their descriptions.
|
|
|
14
14
|
|---|---|
|
|
15
15
|
| `/do:better` | Unified DevSecOps audit, remediation, per-category PRs, CI verification, and Copilot review loop |
|
|
16
16
|
| `/do:better-swift` | SwiftUI-optimized DevSecOps audit with multi-platform coverage (iOS, macOS, watchOS, tvOS, visionOS) |
|
|
17
|
+
| `/do:depfree` | Audit third-party dependencies and remove unnecessary ones by writing replacement code |
|
|
17
18
|
| `/do:fpr` | Commit, push to fork, and open a PR against the upstream repo |
|
|
18
19
|
| `/do:goals` | Scan codebase to infer project goals, clarify with user, and generate GOALS.md |
|
|
19
20
|
| `/do:help` | List all available slashdo commands |
|
package/commands/do/release.md
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Create a release PR using the project's documented release workflow
|
|
3
|
+
argument-hint: "[--interactive]"
|
|
3
4
|
---
|
|
4
5
|
|
|
6
|
+
**Default mode: fully autonomous.** Auto-detects branches, determines version bump from commits, runs review, creates and merges the release PR without prompting.
|
|
7
|
+
|
|
8
|
+
**`--interactive` mode:** Pauses for branch confirmation, version approval, and merge confirmation.
|
|
9
|
+
|
|
5
10
|
## Detect Release Workflow
|
|
6
11
|
|
|
7
12
|
Before doing anything, determine the project's source and target branches for releases. Do NOT hardcode branch names. Instead, discover them:
|
|
@@ -11,7 +16,7 @@ Before doing anything, determine the project's source and target branches for re
|
|
|
11
16
|
- **GitHub Actions workflows** — check `.github/workflows/release.yml` (or similar) for `on: push: branches:` to find the branch that triggers the release pipeline
|
|
12
17
|
- **Project conventions** (already in context) — look for git workflow sections, branch descriptions, or release instructions
|
|
13
18
|
- **Versioning docs** — check `docs/VERSIONING.md`, `CONTRIBUTING.md`, or `RELEASING.md`
|
|
14
|
-
- **Branch convention** — if a `release` branch exists, the target is `release`; otherwise ask the user
|
|
19
|
+
- **Branch convention** — if a `release` branch exists, the target is `release`; otherwise create it from the last release tag (see step 3 below). In `--interactive` mode, ask the user to confirm
|
|
15
20
|
3. **Ensure the target branch exists** — if not, create it from the last release tag:
|
|
16
21
|
```bash
|
|
17
22
|
git branch release $(git describe --tags --abbrev=0)
|
|
@@ -21,7 +26,7 @@ Before doing anything, determine the project's source and target branches for re
|
|
|
21
26
|
|
|
22
27
|
Print the detected workflow: `Detected release flow: {source} → {target}`
|
|
23
28
|
|
|
24
|
-
If ambiguous,
|
|
29
|
+
**Default mode**: If ambiguous, use the most likely branch (prefer `release` if it exists). If the target branch does not exist, create it from the last release tag (see step 3 above). If detection still yields `target == source`, abort with an error — a release PR cannot merge a branch into itself. **Interactive mode (`--interactive`)**: Ask the user to confirm before proceeding.
|
|
25
30
|
|
|
26
31
|
**Important**: The PR direction is `{source}` → `{target}` (e.g., `main` → `release`). This gives Copilot the full diff of all changes since the last release for review. Do NOT create a branch from source and PR back into it — that only shows the version bump commit.
|
|
27
32
|
|
|
@@ -40,7 +45,7 @@ If ambiguous, ask the user to confirm before proceeding.
|
|
|
40
45
|
- `feat:` → **minor** bump
|
|
41
46
|
- `fix:`, `chore:`, `docs:`, `refactor:`, `perf:`, `style:`, `test:`, `ci:` → **patch** bump
|
|
42
47
|
- Use the **highest applicable level** across all commits
|
|
43
|
-
- Present the proposed version to the user for confirmation
|
|
48
|
+
- **Default mode**: Use the determined version automatically. **Interactive mode (`--interactive`)**: Present the proposed version to the user for confirmation
|
|
44
49
|
|
|
45
50
|
2. **Bump version**: Run `npm version <major|minor|patch> --no-git-tag-version` to update `package.json` and `package-lock.json`
|
|
46
51
|
|
|
@@ -82,7 +87,7 @@ Checklist to apply to each file:
|
|
|
82
87
|
|
|
83
88
|
!`cat ~/.claude/lib/code-review-checklist.md`
|
|
84
89
|
|
|
85
|
-
Verification —
|
|
90
|
+
Verification — self-check before proceeding (no user prompt needed):
|
|
86
91
|
- [ ] Read every changed file in full (not just diffs)
|
|
87
92
|
- [ ] Checked each file against the relevant checklist tiers
|
|
88
93
|
- [ ] Quoted specific code for each finding
|