@simplysm/sd-claude 13.0.78 → 13.0.81
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/claude/rules/sd-claude-rules.md +4 -63
- package/claude/rules/sd-simplysm-usage.md +7 -0
- package/claude/sd-session-start.sh +10 -0
- package/claude/sd-statusline.py +249 -0
- package/claude/skills/sd-api-review/SKILL.md +89 -0
- package/claude/skills/sd-check/SKILL.md +55 -57
- package/claude/skills/sd-commit/SKILL.md +37 -42
- package/claude/skills/sd-debug/SKILL.md +75 -265
- package/claude/skills/sd-document/SKILL.md +63 -53
- package/claude/skills/sd-document/_common.py +94 -0
- package/claude/skills/sd-document/extract_docx.py +19 -48
- package/claude/skills/sd-document/extract_pdf.py +22 -50
- package/claude/skills/sd-document/extract_pptx.py +17 -40
- package/claude/skills/sd-document/extract_xlsx.py +19 -40
- package/claude/skills/sd-email-analyze/SKILL.md +23 -31
- package/claude/skills/sd-email-analyze/email-analyzer.py +79 -65
- package/claude/skills/sd-init/SKILL.md +133 -0
- package/claude/skills/sd-plan/SKILL.md +69 -120
- package/claude/skills/sd-readme/SKILL.md +106 -131
- package/claude/skills/sd-review/SKILL.md +38 -155
- package/claude/skills/sd-simplify/SKILL.md +59 -0
- package/dist/commands/install.js +20 -6
- package/dist/commands/install.js.map +1 -1
- package/package.json +3 -2
- package/src/commands/install.ts +29 -7
- package/README.md +0 -297
- package/claude/refs/sd-angular.md +0 -127
- package/claude/refs/sd-code-conventions.md +0 -155
- package/claude/refs/sd-directories.md +0 -7
- package/claude/refs/sd-library-issue.md +0 -7
- package/claude/refs/sd-migration.md +0 -7
- package/claude/refs/sd-orm-v12.md +0 -81
- package/claude/refs/sd-orm.md +0 -23
- package/claude/refs/sd-service.md +0 -5
- package/claude/refs/sd-simplysm-docs.md +0 -52
- package/claude/refs/sd-solid.md +0 -68
- package/claude/refs/sd-workflow.md +0 -25
- package/claude/rules/sd-refs-linker.md +0 -52
- package/claude/sd-statusline.js +0 -296
- package/claude/skills/sd-api-name-review/SKILL.md +0 -154
- package/claude/skills/sd-brainstorm/SKILL.md +0 -215
- package/claude/skills/sd-debug/condition-based-waiting-example.ts +0 -158
- package/claude/skills/sd-debug/condition-based-waiting.md +0 -114
- package/claude/skills/sd-debug/defense-in-depth.md +0 -128
- package/claude/skills/sd-debug/find-polluter.sh +0 -64
- package/claude/skills/sd-debug/root-cause-tracing.md +0 -168
- package/claude/skills/sd-discuss/SKILL.md +0 -91
- package/claude/skills/sd-explore/SKILL.md +0 -118
- package/claude/skills/sd-plan-dev/SKILL.md +0 -294
- package/claude/skills/sd-plan-dev/code-quality-reviewer-prompt.md +0 -49
- package/claude/skills/sd-plan-dev/final-review-prompt.md +0 -50
- package/claude/skills/sd-plan-dev/implementer-prompt.md +0 -60
- package/claude/skills/sd-plan-dev/spec-reviewer-prompt.md +0 -45
- package/claude/skills/sd-review/api-reviewer-prompt.md +0 -75
- package/claude/skills/sd-review/code-reviewer-prompt.md +0 -82
- package/claude/skills/sd-review/convention-checker-prompt.md +0 -61
- package/claude/skills/sd-review/refactoring-analyzer-prompt.md +0 -92
- package/claude/skills/sd-skill/SKILL.md +0 -417
- package/claude/skills/sd-skill/anthropic-best-practices.md +0 -156
- package/claude/skills/sd-skill/cso-guide.md +0 -161
- package/claude/skills/sd-skill/examples/CLAUDE_MD_TESTING.md +0 -200
- package/claude/skills/sd-skill/persuasion-principles.md +0 -220
- package/claude/skills/sd-skill/testing-skills-with-subagents.md +0 -408
- package/claude/skills/sd-skill/writing-guide.md +0 -159
- package/claude/skills/sd-tdd/SKILL.md +0 -385
- package/claude/skills/sd-tdd/testing-anti-patterns.md +0 -317
- package/claude/skills/sd-use/SKILL.md +0 -67
- package/claude/skills/sd-worktree/SKILL.md +0 -78
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
# Defense-in-Depth Validation
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
When you fix a bug caused by invalid data, adding validation at one place feels sufficient. But that single check can be bypassed by different code paths, refactoring, or mocks.
|
|
6
|
-
|
|
7
|
-
**Core principle:** Validate at EVERY layer data passes through. Make the bug structurally impossible.
|
|
8
|
-
|
|
9
|
-
## Why Multiple Layers
|
|
10
|
-
|
|
11
|
-
Single validation: "We fixed the bug"
|
|
12
|
-
Multiple layers: "We made the bug impossible"
|
|
13
|
-
|
|
14
|
-
Different layers catch different cases:
|
|
15
|
-
|
|
16
|
-
- Entry validation catches most bugs
|
|
17
|
-
- Business logic catches edge cases
|
|
18
|
-
- Environment guards prevent context-specific dangers
|
|
19
|
-
- Debug logging helps when other layers fail
|
|
20
|
-
|
|
21
|
-
## The Four Layers
|
|
22
|
-
|
|
23
|
-
### Layer 1: Entry Point Validation
|
|
24
|
-
|
|
25
|
-
**Purpose:** Reject obviously invalid input at API boundary
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
function createProject(name: string, workingDirectory: string) {
|
|
29
|
-
if (!workingDirectory || workingDirectory.trim() === "") {
|
|
30
|
-
throw new Error("workingDirectory cannot be empty");
|
|
31
|
-
}
|
|
32
|
-
if (!existsSync(workingDirectory)) {
|
|
33
|
-
throw new Error(`workingDirectory does not exist: ${workingDirectory}`);
|
|
34
|
-
}
|
|
35
|
-
if (!statSync(workingDirectory).isDirectory()) {
|
|
36
|
-
throw new Error(`workingDirectory is not a directory: ${workingDirectory}`);
|
|
37
|
-
}
|
|
38
|
-
// ... proceed
|
|
39
|
-
}
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### Layer 2: Business Logic Validation
|
|
43
|
-
|
|
44
|
-
**Purpose:** Ensure data makes sense for this operation
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
function initializeWorkspace(projectDir: string, sessionId: string) {
|
|
48
|
-
if (!projectDir) {
|
|
49
|
-
throw new Error("projectDir required for workspace initialization");
|
|
50
|
-
}
|
|
51
|
-
// ... proceed
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### Layer 3: Environment Guards
|
|
56
|
-
|
|
57
|
-
**Purpose:** Prevent dangerous operations in specific contexts
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
async function gitInit(directory: string) {
|
|
61
|
-
// In tests, refuse git init outside temp directories
|
|
62
|
-
if (process.env.NODE_ENV === "test") {
|
|
63
|
-
const normalized = normalize(resolve(directory));
|
|
64
|
-
const tmpDir = normalize(resolve(tmpdir()));
|
|
65
|
-
|
|
66
|
-
if (!normalized.startsWith(tmpDir)) {
|
|
67
|
-
throw new Error(`Refusing git init outside temp dir during tests: ${directory}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
// ... proceed
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
### Layer 4: Debug Instrumentation
|
|
75
|
-
|
|
76
|
-
**Purpose:** Capture context for forensics
|
|
77
|
-
|
|
78
|
-
```typescript
|
|
79
|
-
async function gitInit(directory: string) {
|
|
80
|
-
const stack = new Error().stack;
|
|
81
|
-
logger.debug("About to git init", {
|
|
82
|
-
directory,
|
|
83
|
-
cwd: process.cwd(),
|
|
84
|
-
stack,
|
|
85
|
-
});
|
|
86
|
-
// ... proceed
|
|
87
|
-
}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## Applying the Pattern
|
|
91
|
-
|
|
92
|
-
When you find a bug:
|
|
93
|
-
|
|
94
|
-
1. **Trace the data flow** - Where does bad value originate? Where used?
|
|
95
|
-
2. **Map all checkpoints** - List every point data passes through
|
|
96
|
-
3. **Add validation at each layer** - Entry, business, environment, debug
|
|
97
|
-
4. **Test each layer** - Try to bypass layer 1, verify layer 2 catches it
|
|
98
|
-
|
|
99
|
-
## Example from Session
|
|
100
|
-
|
|
101
|
-
Bug: Empty `projectDir` caused `git init` in source code
|
|
102
|
-
|
|
103
|
-
**Data flow:**
|
|
104
|
-
|
|
105
|
-
1. Test setup → empty string
|
|
106
|
-
2. `Project.create(name, '')`
|
|
107
|
-
3. `WorkspaceManager.createWorkspace('')`
|
|
108
|
-
4. `git init` runs in `process.cwd()`
|
|
109
|
-
|
|
110
|
-
**Four layers added:**
|
|
111
|
-
|
|
112
|
-
- Layer 1: `Project.create()` validates not empty/exists/writable
|
|
113
|
-
- Layer 2: `WorkspaceManager` validates projectDir not empty
|
|
114
|
-
- Layer 3: `WorktreeManager` refuses git init outside tmpdir in tests
|
|
115
|
-
- Layer 4: Stack trace logging before git init
|
|
116
|
-
|
|
117
|
-
**Result:** All 1847 tests passed, bug impossible to reproduce
|
|
118
|
-
|
|
119
|
-
## Key Insight
|
|
120
|
-
|
|
121
|
-
All four layers were necessary. During testing, each layer caught bugs the others missed:
|
|
122
|
-
|
|
123
|
-
- Different code paths bypassed entry validation
|
|
124
|
-
- Mocks bypassed business logic checks
|
|
125
|
-
- Edge cases on different platforms needed environment guards
|
|
126
|
-
- Debug logging identified structural misuse
|
|
127
|
-
|
|
128
|
-
**Don't stop at one validation point.** Add checks at every layer.
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# Bisection script for finding which test creates unwanted files/directories
|
|
3
|
-
# Usage: ./find-polluter.sh <file_or_dir_to_check> <test_pattern>
|
|
4
|
-
# Example: ./find-polluter.sh '.git' 'src/**/*.test.ts'
|
|
5
|
-
|
|
6
|
-
set -e
|
|
7
|
-
|
|
8
|
-
if [ "$#" -ne 2 ]; then
|
|
9
|
-
echo "Usage: $0 <file_or_dir_to_check> <test_pattern>"
|
|
10
|
-
echo "Example: $0 '.git' 'src/**/*.test.ts'"
|
|
11
|
-
exit 1
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
CHECK_PATH="$1"
|
|
15
|
-
TEST_PATTERN="$2"
|
|
16
|
-
|
|
17
|
-
# Detect package manager: pnpm -> yarn -> npm (default)
|
|
18
|
-
if [ -f "pnpm-lock.yaml" ]; then PM="pnpm"
|
|
19
|
-
elif [ -f "yarn.lock" ]; then PM="yarn"
|
|
20
|
-
else PM="npm"
|
|
21
|
-
fi
|
|
22
|
-
|
|
23
|
-
# Find all test files matching pattern
|
|
24
|
-
readarray -t TEST_FILES < <(find . -path "$TEST_PATTERN" -type f)
|
|
25
|
-
|
|
26
|
-
if [ ${#TEST_FILES[@]} -eq 0 ]; then
|
|
27
|
-
echo "No test files found matching pattern: $TEST_PATTERN"
|
|
28
|
-
exit 1
|
|
29
|
-
fi
|
|
30
|
-
|
|
31
|
-
echo "Found ${#TEST_FILES[@]} test files"
|
|
32
|
-
echo "Checking for pollution: $CHECK_PATH"
|
|
33
|
-
echo ""
|
|
34
|
-
|
|
35
|
-
for test_file in "${TEST_FILES[@]}"; do
|
|
36
|
-
# Skip if pollution already exists
|
|
37
|
-
if [ -e "$CHECK_PATH" ]; then
|
|
38
|
-
echo "⚠️ Pollution already exists, skipping to avoid false positive"
|
|
39
|
-
echo " Please remove $CHECK_PATH and re-run"
|
|
40
|
-
exit 1
|
|
41
|
-
fi
|
|
42
|
-
|
|
43
|
-
echo "Testing: $test_file"
|
|
44
|
-
|
|
45
|
-
# Run the test
|
|
46
|
-
$PM test "$test_file" > /dev/null 2>&1 || true
|
|
47
|
-
|
|
48
|
-
# Check if pollution appeared
|
|
49
|
-
if [ -e "$CHECK_PATH" ]; then
|
|
50
|
-
echo ""
|
|
51
|
-
echo "🔴 FOUND POLLUTER: $test_file"
|
|
52
|
-
echo ""
|
|
53
|
-
echo "This test created: $CHECK_PATH"
|
|
54
|
-
ls -la "$CHECK_PATH" 2>/dev/null || echo "(path exists but can't stat)"
|
|
55
|
-
echo ""
|
|
56
|
-
echo "Investigate with:"
|
|
57
|
-
echo " $PM test '$test_file' -- --reporter=verbose"
|
|
58
|
-
echo " git diff"
|
|
59
|
-
exit 0
|
|
60
|
-
fi
|
|
61
|
-
done
|
|
62
|
-
|
|
63
|
-
echo ""
|
|
64
|
-
echo "✅ No polluter found - all ${#TEST_FILES[@]} tests are clean"
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
# Root Cause Tracing
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Bugs often manifest deep in the call stack (git init in wrong directory, file created in wrong location, database opened with wrong path). Your instinct is to fix where the error appears, but that's treating a symptom.
|
|
6
|
-
|
|
7
|
-
**Core principle:** Trace backward through the call chain until you find the original trigger, then fix at the source.
|
|
8
|
-
|
|
9
|
-
## When to Use
|
|
10
|
-
|
|
11
|
-
```mermaid
|
|
12
|
-
flowchart TD
|
|
13
|
-
A{"Bug appears deep in stack?"} -->|yes| B{"Can trace backwards?"}
|
|
14
|
-
B -->|yes| C[Trace to original trigger]
|
|
15
|
-
B -->|"no - dead end"| D[Fix at symptom point]
|
|
16
|
-
C --> E["BETTER: Also add defense-in-depth"]
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
**Use when:**
|
|
20
|
-
|
|
21
|
-
- Error happens deep in execution (not at entry point)
|
|
22
|
-
- Stack trace shows long call chain
|
|
23
|
-
- Unclear where invalid data originated
|
|
24
|
-
- Need to find which test/code triggers the problem
|
|
25
|
-
|
|
26
|
-
## The Tracing Process
|
|
27
|
-
|
|
28
|
-
### 1. Observe the Symptom
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
Error: git init failed in /Users/jesse/project/packages/core
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
### 2. Find Immediate Cause
|
|
35
|
-
|
|
36
|
-
**What code directly causes this?**
|
|
37
|
-
|
|
38
|
-
```typescript
|
|
39
|
-
await execFileAsync("git", ["init"], { cwd: projectDir });
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
### 3. Ask: What Called This?
|
|
43
|
-
|
|
44
|
-
```typescript
|
|
45
|
-
WorktreeManager.createSessionWorktree(projectDir, sessionId)
|
|
46
|
-
→ called by Session.initializeWorkspace()
|
|
47
|
-
→ called by Session.create()
|
|
48
|
-
→ called by test at Project.create()
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### 4. Keep Tracing Up
|
|
52
|
-
|
|
53
|
-
**What value was passed?**
|
|
54
|
-
|
|
55
|
-
- `projectDir = ''` (empty string!)
|
|
56
|
-
- Empty string as `cwd` resolves to `process.cwd()`
|
|
57
|
-
- That's the source code directory!
|
|
58
|
-
|
|
59
|
-
### 5. Find Original Trigger
|
|
60
|
-
|
|
61
|
-
**Where did empty string come from?**
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
const context = setupCoreTest(); // Returns { tempDir: '' }
|
|
65
|
-
Project.create("name", context.tempDir); // Accessed before beforeEach!
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
## Adding Stack Traces
|
|
69
|
-
|
|
70
|
-
When you can't trace manually, add instrumentation:
|
|
71
|
-
|
|
72
|
-
```typescript
|
|
73
|
-
// Before the problematic operation
|
|
74
|
-
async function gitInit(directory: string) {
|
|
75
|
-
const stack = new Error().stack;
|
|
76
|
-
console.error("DEBUG git init:", {
|
|
77
|
-
directory,
|
|
78
|
-
cwd: process.cwd(),
|
|
79
|
-
nodeEnv: process.env.NODE_ENV,
|
|
80
|
-
stack,
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
await execFileAsync("git", ["init"], { cwd: directory });
|
|
84
|
-
}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
**Critical:** Use `console.error()` in tests (not logger - may not show)
|
|
88
|
-
|
|
89
|
-
**Run and capture** (detect PM: `pnpm-lock.yaml` → pnpm, `yarn.lock` → yarn, otherwise → npm):
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
$PM test 2>&1 | grep 'DEBUG git init'
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
**Analyze stack traces:**
|
|
96
|
-
|
|
97
|
-
- Look for test file names
|
|
98
|
-
- Find the line number triggering the call
|
|
99
|
-
- Identify the pattern (same test? same parameter?)
|
|
100
|
-
|
|
101
|
-
## Finding Which Test Causes Pollution
|
|
102
|
-
|
|
103
|
-
If something appears during tests but you don't know which test:
|
|
104
|
-
|
|
105
|
-
Use the bisection script `find-polluter.sh` in this directory:
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
./find-polluter.sh '.git' 'src/**/*.test.ts'
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
Runs tests one-by-one, stops at first polluter. See script for usage.
|
|
112
|
-
|
|
113
|
-
## Real Example: Empty projectDir
|
|
114
|
-
|
|
115
|
-
**Symptom:** `.git` created in `packages/core/` (source code)
|
|
116
|
-
|
|
117
|
-
**Trace chain:**
|
|
118
|
-
|
|
119
|
-
1. `git init` runs in `process.cwd()` ← empty cwd parameter
|
|
120
|
-
2. WorktreeManager called with empty projectDir
|
|
121
|
-
3. Session.create() passed empty string
|
|
122
|
-
4. Test accessed `context.tempDir` before beforeEach
|
|
123
|
-
5. setupCoreTest() returns `{ tempDir: '' }` initially
|
|
124
|
-
|
|
125
|
-
**Root cause:** Top-level variable initialization accessing empty value
|
|
126
|
-
|
|
127
|
-
**Fix:** Made tempDir a getter that throws if accessed before beforeEach
|
|
128
|
-
|
|
129
|
-
**Also added defense-in-depth:**
|
|
130
|
-
|
|
131
|
-
- Layer 1: Project.create() validates directory
|
|
132
|
-
- Layer 2: WorkspaceManager validates not empty
|
|
133
|
-
- Layer 3: NODE_ENV guard refuses git init outside tmpdir
|
|
134
|
-
- Layer 4: Stack trace logging before git init
|
|
135
|
-
|
|
136
|
-
## Key Principle
|
|
137
|
-
|
|
138
|
-
```mermaid
|
|
139
|
-
flowchart TD
|
|
140
|
-
A(["Found immediate cause"]) --> B{"Can trace one level up?"}
|
|
141
|
-
B -->|yes| C["Trace backwards"]
|
|
142
|
-
B -->|no| D["NEVER fix just the symptom"]:::danger
|
|
143
|
-
C --> E{"Is this the source?"}
|
|
144
|
-
E -->|"no - keeps going"| C
|
|
145
|
-
E -->|yes| F["Fix at source"]
|
|
146
|
-
F --> G["Add validation at each layer"]
|
|
147
|
-
G --> H(("Bug impossible"))
|
|
148
|
-
|
|
149
|
-
classDef danger fill:#f00,color:#fff
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
**NEVER fix just where the error appears.** Trace back to find the original trigger.
|
|
153
|
-
|
|
154
|
-
## Stack Trace Tips
|
|
155
|
-
|
|
156
|
-
**In tests:** Use `console.error()` not logger - logger may be suppressed
|
|
157
|
-
**Before operation:** Log before the dangerous operation, not after it fails
|
|
158
|
-
**Include context:** Directory, cwd, environment variables, timestamps
|
|
159
|
-
**Capture stack:** `new Error().stack` shows complete call chain
|
|
160
|
-
|
|
161
|
-
## Real-World Impact
|
|
162
|
-
|
|
163
|
-
From debugging session (2025-10-03):
|
|
164
|
-
|
|
165
|
-
- Found root cause through 5-level trace
|
|
166
|
-
- Fixed at source (getter validation)
|
|
167
|
-
- Added 4 layers of defense
|
|
168
|
-
- 1847 tests passed, zero pollution
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sd-discuss
|
|
3
|
-
description: "Technical discussion with industry research (explicit invocation only)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Standards-Based Technical Discussion
|
|
7
|
-
|
|
8
|
-
## Overview
|
|
9
|
-
|
|
10
|
-
Facilitate balanced, evidence-based technical discussions by researching industry standards and project conventions BEFORE forming opinions.
|
|
11
|
-
|
|
12
|
-
## The Process
|
|
13
|
-
|
|
14
|
-
### 1. Understand the Question
|
|
15
|
-
|
|
16
|
-
Ask ONE question to understand the user's motivation:
|
|
17
|
-
|
|
18
|
-
- What problem triggered this question?
|
|
19
|
-
- What constraints matter most?
|
|
20
|
-
|
|
21
|
-
### 2. Research Before Opinions
|
|
22
|
-
|
|
23
|
-
**MANDATORY before forming any opinion:**
|
|
24
|
-
|
|
25
|
-
**Project research** (Read/Grep tools):
|
|
26
|
-
|
|
27
|
-
- Read the actual source code related to the question
|
|
28
|
-
- Check CLAUDE.md for project conventions
|
|
29
|
-
- Find similar patterns in the codebase
|
|
30
|
-
|
|
31
|
-
**Industry research** (WebSearch tool):
|
|
32
|
-
|
|
33
|
-
- Search for current community consensus and trends
|
|
34
|
-
- Check relevant specifications (TC39, W3C, RFCs)
|
|
35
|
-
- Find recent benchmarks, migration case studies, or survey data
|
|
36
|
-
- Check how popular libraries/frameworks approach this
|
|
37
|
-
|
|
38
|
-
### 3. Present Balanced Arguments
|
|
39
|
-
|
|
40
|
-
Present each option as if you were **advocating FOR it**. Equal depth, equal effort.
|
|
41
|
-
|
|
42
|
-
For each option:
|
|
43
|
-
|
|
44
|
-
- **Industry support**: Libraries, standards, and projects that use this approach (with sources)
|
|
45
|
-
- **Technical advantages**: Concrete benefits with evidence
|
|
46
|
-
- **When this wins**: Specific scenarios where this is clearly better
|
|
47
|
-
|
|
48
|
-
### 4. Project Context Analysis
|
|
49
|
-
|
|
50
|
-
- How does the current codebase align with each option?
|
|
51
|
-
- What would migration cost look like?
|
|
52
|
-
- What existing patterns favor one approach?
|
|
53
|
-
|
|
54
|
-
### 5. Decision Criteria
|
|
55
|
-
|
|
56
|
-
Provide a decision matrix — NOT a single recommendation:
|
|
57
|
-
|
|
58
|
-
| Criteria | Option A | Option B |
|
|
59
|
-
| ------------------- | -------- | -------- |
|
|
60
|
-
| Industry alignment | ... | ... |
|
|
61
|
-
| Project consistency | ... | ... |
|
|
62
|
-
| Migration cost | ... | ... |
|
|
63
|
-
| Long-term trend | ... | ... |
|
|
64
|
-
|
|
65
|
-
Then ask: "Which criteria matter most to you?"
|
|
66
|
-
|
|
67
|
-
## Key Rules
|
|
68
|
-
|
|
69
|
-
1. **Research FIRST, opinion LAST** — No opinions before WebSearch + project code reading
|
|
70
|
-
2. **Equal advocacy** — Each option gets the same depth of analysis
|
|
71
|
-
3. **Evidence over intuition** — Cite sources, show data
|
|
72
|
-
4. **No "obvious" answers** — If it were obvious, there'd be no discussion
|
|
73
|
-
5. **Interactive** — Ask questions, don't monologue
|
|
74
|
-
6. **Project-aware** — Ground the discussion in the actual codebase
|
|
75
|
-
|
|
76
|
-
## Red Flags - STOP and Research More
|
|
77
|
-
|
|
78
|
-
- Presenting one side with more depth than the other
|
|
79
|
-
- Claiming "industry standard" without citing sources
|
|
80
|
-
- Recommending without checking the project's current patterns
|
|
81
|
-
- Giving a conclusion without asking user's priorities
|
|
82
|
-
|
|
83
|
-
## Common Mistakes
|
|
84
|
-
|
|
85
|
-
| Mistake | Fix |
|
|
86
|
-
| ---------------------------------------- | ------------------------------------------- |
|
|
87
|
-
| Jump to recommendation | Research first, present balanced options |
|
|
88
|
-
| "Industry standard is X" without sources | WebSearch for actual data and citations |
|
|
89
|
-
| Ignoring project context | Read codebase patterns before discussing |
|
|
90
|
-
| Monologue instead of discussion | Ask about user's priorities and constraints |
|
|
91
|
-
| Treating "modern" as "better" | Evaluate on actual trade-offs, not trends |
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sd-explore
|
|
3
|
-
description: "Use when analyzing a large codebase (30+ files) that must be read comprehensively. Splits files into groups and dispatches parallel sub-agents to avoid context compaction and information loss."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# sd-explore
|
|
7
|
-
|
|
8
|
-
## Overview
|
|
9
|
-
|
|
10
|
-
Split a large codebase into manageable groups and dispatch parallel sub-agents, each reading its assigned files and writing results to disk. The calling skill then reads result files instead of raw source — no context compaction, no information loss.
|
|
11
|
-
|
|
12
|
-
**Core principle:** Never read 30+ files in a single agent context. Split, parallelize, write to files.
|
|
13
|
-
|
|
14
|
-
**Important:** This is a workflow the **orchestrator (main agent)** follows directly. Do NOT delegate the entire sd-explore workflow to a sub-agent — only the orchestrator has `Agent` tool access to dispatch parallel sub-agents. The orchestrator globs files, splits groups, and dispatches `Agent(Explore)` calls itself.
|
|
15
|
-
|
|
16
|
-
## When to Use
|
|
17
|
-
|
|
18
|
-
- Codebase analysis covering 30+ source files
|
|
19
|
-
- Called by other skills (sd-review, sd-brainstorm, sd-debug, sd-plan) that need comprehensive file reading
|
|
20
|
-
- Any task where reading all files sequentially would risk context compaction
|
|
21
|
-
|
|
22
|
-
**When NOT to use:**
|
|
23
|
-
- < 30 files — a single agent can handle it directly
|
|
24
|
-
- Targeted search for a specific function/class — use Grep/Glob instead
|
|
25
|
-
|
|
26
|
-
## Input
|
|
27
|
-
|
|
28
|
-
The calling skill provides:
|
|
29
|
-
|
|
30
|
-
1. **Target path** — directory to explore (e.g., `packages/solid/src`)
|
|
31
|
-
2. **Name** — caller identifier for output filenames (e.g., `review`, `debug`, `brainstorm`)
|
|
32
|
-
3. **File patterns** — glob patterns to match (default: `**/*.ts`, `**/*.tsx`; exclude `node_modules`, `dist`)
|
|
33
|
-
4. **Analysis instructions** — free-form text describing what each sub-agent should do
|
|
34
|
-
|
|
35
|
-
The analysis instructions are passed verbatim to each sub-agent. They can request anything: tags, summaries, pattern searches, specific questions, etc.
|
|
36
|
-
|
|
37
|
-
## Workflow
|
|
38
|
-
|
|
39
|
-
### Step 1: Discover Files
|
|
40
|
-
|
|
41
|
-
Glob all matching files under the target path.
|
|
42
|
-
|
|
43
|
-
- **< 30 files**: Run a single `Agent(subagent_type=Explore)` with the analysis instructions. No splitting needed. Write result to `.tmp/explore/{dt}_{name}.md` (where `{dt}` is current datetime as `yyyyMMddHHmmss`).
|
|
44
|
-
- **>= 30 files**: Proceed to Step 2.
|
|
45
|
-
|
|
46
|
-
### Step 2: Split Into Groups
|
|
47
|
-
|
|
48
|
-
Split files into groups of **~30 files each**.
|
|
49
|
-
|
|
50
|
-
**Splitting strategy:**
|
|
51
|
-
|
|
52
|
-
1. List all subdirectories under target
|
|
53
|
-
2. Group files by subdirectory, keeping each group around 30 files
|
|
54
|
-
3. If the target is mostly flat (few subdirectories), group by file proximity (alphabetical chunks)
|
|
55
|
-
4. Adjacent small directories can be merged into one group
|
|
56
|
-
5. A single large directory (40+ files) should be split into multiple groups
|
|
57
|
-
|
|
58
|
-
**Goal:** Balanced groups where related files stay together.
|
|
59
|
-
|
|
60
|
-
### Step 3: Dispatch Parallel Agents
|
|
61
|
-
|
|
62
|
-
Launch one `Agent(subagent_type=Explore)` per group, **all in a single message** for true parallelism.
|
|
63
|
-
|
|
64
|
-
Each agent receives:
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
You are exploring a section of a codebase. Read ALL assigned files and write your analysis to the output file.
|
|
68
|
-
|
|
69
|
-
**Assigned files:**
|
|
70
|
-
[list of file paths for this group]
|
|
71
|
-
|
|
72
|
-
**Analysis instructions:**
|
|
73
|
-
[caller's free-form instructions, passed verbatim]
|
|
74
|
-
|
|
75
|
-
**Output file:** .tmp/explore/{dt}_{name}-{group_index}.md
|
|
76
|
-
|
|
77
|
-
Read every assigned file. Write your complete analysis to the output file. Do NOT skip files.
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Step 4: Return Result Paths
|
|
81
|
-
|
|
82
|
-
After all agents complete, return the list of output file paths to the calling skill.
|
|
83
|
-
|
|
84
|
-
The calling skill reads these files to get the analysis results — the main context stays clean.
|
|
85
|
-
|
|
86
|
-
## Output Format
|
|
87
|
-
|
|
88
|
-
Each sub-agent writes to its assigned output file. The format is determined by the caller's analysis instructions. If no specific format is requested, use:
|
|
89
|
-
|
|
90
|
-
```markdown
|
|
91
|
-
# Explore: [directory names]
|
|
92
|
-
|
|
93
|
-
## File Summaries
|
|
94
|
-
- `path/to/file.ts` — Brief description
|
|
95
|
-
|
|
96
|
-
## Analysis
|
|
97
|
-
[Results per the caller's instructions]
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
## Why Sub-Agents Matter
|
|
101
|
-
|
|
102
|
-
The value is **context isolation**, not just speed:
|
|
103
|
-
|
|
104
|
-
- **Without sub-agents**: Reading 100+ files in the main context causes compaction. Earlier file analyses get dropped, degrading quality of later analysis steps (review, planning, etc.)
|
|
105
|
-
- **With sub-agents**: Each sub-agent reads ~30 files in its own context, writes results to disk, and exits. The main context only reads the summary files — staying clean for subsequent work.
|
|
106
|
-
|
|
107
|
-
## Common Mistakes
|
|
108
|
-
|
|
109
|
-
| Mistake | Fix |
|
|
110
|
-
|---------|-----|
|
|
111
|
-
| Delegating the entire workflow to a sub-agent | The orchestrator follows sd-explore directly — only it can dispatch parallel `Agent` calls |
|
|
112
|
-
| Reading all files in one agent | Split into groups of ~30, dispatch parallel agents |
|
|
113
|
-
| Not writing results to files | Each agent MUST write to its output file — this is what prevents context bloat |
|
|
114
|
-
| Groups too large (50+) | Keep groups around 30 files for reliable coverage |
|
|
115
|
-
| Groups too small (5-10) | Wastes agent overhead — merge small directories |
|
|
116
|
-
| Not passing analysis instructions verbatim | The caller's instructions go to each agent as-is |
|
|
117
|
-
| Running agents sequentially | Launch all agents in a single message for parallelism |
|
|
118
|
-
| Skipping Step 1 threshold check | < 30 files don't need splitting — avoid unnecessary overhead |
|