opencodekit 0.23.3 → 0.23.4
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 +7 -14
- package/dist/index.js +1 -1
- package/dist/template/.opencode/AGENTS.md +89 -17
- package/dist/template/.opencode/README.md +43 -6
- package/dist/template/.opencode/artifacts/harness-workflows/plan.md +317 -0
- package/dist/template/.opencode/command/audit.md +65 -0
- package/dist/template/.opencode/command/init.md +19 -2
- package/dist/template/.opencode/command/research.md +67 -16
- package/dist/template/.opencode/command/ship.md +55 -5
- package/dist/template/.opencode/command/verify.md +5 -5
- package/dist/template/.opencode/opencode.json +12 -0
- package/dist/template/.opencode/plugin/README.md +0 -6
- package/dist/template/.opencode/skill/defense-in-depth/SKILL.md +0 -2
- package/dist/template/.opencode/skill/development-lifecycle/SKILL.md +11 -9
- package/dist/template/.opencode/skill/manifest.json +77 -0
- package/dist/template/.opencode/workflows/audit-pattern.md +51 -0
- package/dist/template/.opencode/workflows/batch-implement.md +82 -0
- package/dist/template/.opencode/workflows/deep-research.md +58 -0
- package/dist/template/.opencode/workflows/development-lifecycle-workflow.md +129 -0
- package/package.json +1 -1
- package/dist/template/.opencode/command/clarify.md +0 -46
- package/dist/template/.opencode/command/commit.md +0 -53
- package/dist/template/.opencode/command/design.md +0 -129
- package/dist/template/.opencode/command/explore.md +0 -169
- package/dist/template/.opencode/command/improve-architecture.md +0 -55
- package/dist/template/.opencode/command/pr.md +0 -148
- package/dist/template/.opencode/command/refactor.md +0 -65
- package/dist/template/.opencode/command/review-codebase.md +0 -128
- package/dist/template/.opencode/command/test.md +0 -66
- package/dist/template/.opencode/command/ui-review.md +0 -109
- package/dist/template/.opencode/opencodex-fast.jsonc +0 -3
- package/dist/template/.opencode/plugin/rtk.ts +0 -43
- package/dist/template/.opencode/skill/agent-teams/SKILL.md +0 -268
- package/dist/template/.opencode/skill/code-navigation/SKILL.md +0 -142
- package/dist/template/.opencode/skill/condition-based-waiting/SKILL.md +0 -135
- package/dist/template/.opencode/skill/condition-based-waiting/example.ts +0 -171
- package/dist/template/.opencode/skill/context-engineering/SKILL.md +0 -176
- package/dist/template/.opencode/skill/memory-system/SKILL.md +0 -147
- package/dist/template/.opencode/skill/structured-edit/SKILL.md +0 -191
- package/dist/template/.opencode/skill/ubiquitous-language/SKILL.md +0 -184
- package/dist/template/.opencode/skill/v0/SKILL.md +0 -158
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: agent-teams
|
|
3
|
-
description: >
|
|
4
|
-
Use when working with Claude Code-style agent teams for parallel research, review, competing hypotheses,
|
|
5
|
-
or any task that benefits from multiple agents working simultaneously under a lead coordinator.
|
|
6
|
-
Covers team configuration, task distribution, coordination patterns, and best practices.
|
|
7
|
-
version: "1.0.0"
|
|
8
|
-
license: MIT
|
|
9
|
-
tags: [agent-coordination, workflow]
|
|
10
|
-
dependencies: []
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
# Agent Teams - Multi-Agent Team Coordination
|
|
14
|
-
|
|
15
|
-
> **Replaces** single-agent sequential work when tasks benefit from parallel research, review, or competing hypotheses
|
|
16
|
-
|
|
17
|
-
## When to Use
|
|
18
|
-
|
|
19
|
-
- Parallel research, review, or competing approaches that need coordination
|
|
20
|
-
- Tasks benefit from shared findings and a lead coordinating teammates
|
|
21
|
-
|
|
22
|
-
## When NOT to Use
|
|
23
|
-
|
|
24
|
-
- Single-agent tasks or tightly coupled edits where coordination overhead is wasteful
|
|
25
|
-
- Simple parallel work that can use fire-and-forget subagents instead
|
|
26
|
-
|
|
27
|
-
## Overview
|
|
28
|
-
|
|
29
|
-
**Agent Teams = Lead + Teammates + Shared Task List + Messaging**
|
|
30
|
-
|
|
31
|
-
- **Lead agent**: Coordinates the team - distributes tasks, monitors progress, synthesizes results
|
|
32
|
-
- **Teammates**: Execute tasks independently but can message each other and the lead
|
|
33
|
-
- **Task list**: Shared work queue that the lead manages
|
|
34
|
-
- **Messaging**: Bidirectional communication between lead and teammates
|
|
35
|
-
|
|
36
|
-
## When to Use Agent Teams vs Subagents
|
|
37
|
-
|
|
38
|
-
| Criteria | Agent Teams | Subagents (Task tool) |
|
|
39
|
-
| --------------------- | -------------------------------------- | ----------------------------------- |
|
|
40
|
-
| **Coordination** | Lead coordinates, teammates message | Fire-and-forget, results return |
|
|
41
|
-
| **Communication** | Bidirectional messaging | One-way (result only) |
|
|
42
|
-
| **Task reassignment** | Dynamic - lead can reassign | Fixed - each subagent does its task |
|
|
43
|
-
| **Context sharing** | Shared through lead | Independent contexts |
|
|
44
|
-
| **Best for** | Research, review, competing approaches | Independent implementation tasks |
|
|
45
|
-
| **Overhead** | Higher - coordination cost | Lower - no coordination |
|
|
46
|
-
|
|
47
|
-
### Decision Matrix
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
Need coordination between workers? → Agent Teams
|
|
51
|
-
Workers are fully independent? → Subagents (Task tool)
|
|
52
|
-
Need competing hypotheses? → Agent Teams
|
|
53
|
-
Need shared findings? → Agent Teams
|
|
54
|
-
Simple parallel execution? → Subagents (Task tool)
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Parallel Skill Selection
|
|
58
|
-
|
|
59
|
-
| Scenario | Use This Skill |
|
|
60
|
-
| ------------------------------------------- | --------------------------- |
|
|
61
|
-
| 3+ independent bug investigations | dispatching-parallel-agents |
|
|
62
|
-
| Coordinated team (research + review + impl) | agent-teams |
|
|
63
|
-
| Large plan with dependency graph | swarm-coordination |
|
|
64
|
-
| 2 independent tasks | Just use 2 Task() calls |
|
|
65
|
-
|
|
66
|
-
## When to Use
|
|
67
|
-
|
|
68
|
-
- **Parallel research**: Multiple agents researching different aspects of a problem
|
|
69
|
-
- **Code review**: Multiple reviewers examining different files/concerns
|
|
70
|
-
- **Competing hypotheses**: Agents try different approaches, best one wins
|
|
71
|
-
- **Large refactors**: Agents handle different subsystems with coordination
|
|
72
|
-
- **Architecture exploration**: Agents explore different design options simultaneously
|
|
73
|
-
|
|
74
|
-
## When NOT to Use
|
|
75
|
-
|
|
76
|
-
- Single-agent tasks (overhead not worth it)
|
|
77
|
-
- Tightly coupled work where agents would constantly block each other
|
|
78
|
-
- Tasks under 3 independent units of work
|
|
79
|
-
- Simple file edits with no research needed
|
|
80
|
-
|
|
81
|
-
## Team Configuration Patterns
|
|
82
|
-
|
|
83
|
-
### Pattern 1: Research Team
|
|
84
|
-
|
|
85
|
-
```
|
|
86
|
-
Lead: build agent
|
|
87
|
-
├── Teammate 1 (explore): Search codebase for existing patterns
|
|
88
|
-
├── Teammate 2 (scout): Research external docs and best practices
|
|
89
|
-
└── Teammate 3 (review): Analyze current implementation for issues
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
**Use when**: Entering unfamiliar territory, evaluating new libraries, understanding complex systems.
|
|
93
|
-
|
|
94
|
-
### Pattern 2: Review Team
|
|
95
|
-
|
|
96
|
-
```
|
|
97
|
-
Lead: build agent
|
|
98
|
-
├── Teammate 1 (review): Security audit
|
|
99
|
-
├── Teammate 2 (review): Performance review
|
|
100
|
-
└── Teammate 3 (review): Architecture review
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
**Use when**: Pre-merge review of significant features, security-sensitive changes.
|
|
104
|
-
|
|
105
|
-
### Pattern 3: Competing Approaches
|
|
106
|
-
|
|
107
|
-
```
|
|
108
|
-
Lead: build agent
|
|
109
|
-
├── Teammate 1 (general): Implement approach A
|
|
110
|
-
├── Teammate 2 (general): Implement approach B
|
|
111
|
-
└── Teammate 3 (general): Implement approach C
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
**Use when**: Multiple valid solutions exist and you need to compare empirically.
|
|
115
|
-
|
|
116
|
-
### Pattern 4: Subsystem Team
|
|
117
|
-
|
|
118
|
-
```
|
|
119
|
-
Lead: build agent
|
|
120
|
-
├── Teammate 1 (general): Handle frontend changes
|
|
121
|
-
├── Teammate 2 (general): Handle backend changes
|
|
122
|
-
└── Teammate 3 (general): Handle database migrations
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
**Use when**: Large features spanning multiple subsystems with clear boundaries.
|
|
126
|
-
|
|
127
|
-
## Best Practices
|
|
128
|
-
|
|
129
|
-
### Task Distribution
|
|
130
|
-
|
|
131
|
-
1. **5-6 tasks per teammate maximum** - More than this degrades quality
|
|
132
|
-
2. **Clear boundaries** - Each teammate should own distinct files/modules
|
|
133
|
-
3. **Avoid file conflicts** - Never assign the same file to multiple teammates
|
|
134
|
-
4. **Include verification** - Each task should include its own verification step
|
|
135
|
-
|
|
136
|
-
### Coordination
|
|
137
|
-
|
|
138
|
-
1. **Lead synthesizes** - Don't let teammates make final decisions; lead integrates
|
|
139
|
-
2. **Regular check-ins** - Lead should review intermediate results, not just final
|
|
140
|
-
3. **Fail fast** - If a teammate hits a blocker, escalate to lead immediately
|
|
141
|
-
4. **Shared conventions** - Establish naming, formatting, and style before dispatching
|
|
142
|
-
|
|
143
|
-
### Communication
|
|
144
|
-
|
|
145
|
-
1. **Task descriptions should be self-contained** - Teammate shouldn't need to ask clarifying questions
|
|
146
|
-
2. **Include context** - What files to read, what patterns to follow, what constraints exist
|
|
147
|
-
3. **Specify output format** - What should the teammate report back?
|
|
148
|
-
4. **Include acceptance criteria** - How does the lead know the task is done?
|
|
149
|
-
|
|
150
|
-
## Implementation with OpenCode
|
|
151
|
-
|
|
152
|
-
### Using the Task Tool (Current)
|
|
153
|
-
|
|
154
|
-
```typescript
|
|
155
|
-
// Spawn research team
|
|
156
|
-
const codebaseAnalysis = Task({
|
|
157
|
-
subagent_type: "explore",
|
|
158
|
-
description: "Analyze auth patterns",
|
|
159
|
-
prompt: `Research authentication patterns in this codebase:
|
|
160
|
-
1. Find all auth-related files
|
|
161
|
-
2. Map the auth flow
|
|
162
|
-
3. Identify potential security issues
|
|
163
|
-
Report back: file list, flow diagram, issues found`,
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
const externalResearch = Task({
|
|
167
|
-
subagent_type: "scout",
|
|
168
|
-
description: "Research JWT best practices",
|
|
169
|
-
prompt: `Research current JWT best practices:
|
|
170
|
-
1. Token rotation patterns
|
|
171
|
-
2. Refresh token security
|
|
172
|
-
3. Common vulnerabilities
|
|
173
|
-
Report back: recommended patterns with code examples`,
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
const codeReview = Task({
|
|
177
|
-
subagent_type: "review",
|
|
178
|
-
description: "Review auth security",
|
|
179
|
-
prompt: `Security review of auth implementation:
|
|
180
|
-
1. Check token storage
|
|
181
|
-
2. Verify CSRF protection
|
|
182
|
-
3. Audit session management
|
|
183
|
-
Report back: vulnerabilities found with severity ratings`,
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
// Lead synthesizes all results into unified recommendation
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### Using Swarm Coordination (Advanced)
|
|
190
|
-
|
|
191
|
-
For more structured parallel work, combine with the `swarm-coordination` skill:
|
|
192
|
-
|
|
193
|
-
```typescript
|
|
194
|
-
// Load swarm for structured coordination
|
|
195
|
-
skill({ name: "swarm-coordination" });
|
|
196
|
-
|
|
197
|
-
// Analyze and plan
|
|
198
|
-
swarm({ op: "plan", task: "Implement auth overhaul across 3 subsystems" });
|
|
199
|
-
|
|
200
|
-
// Create delegation packets
|
|
201
|
-
swarm({
|
|
202
|
-
op: "delegate",
|
|
203
|
-
bead_id: "auth-frontend",
|
|
204
|
-
title: "Frontend auth components",
|
|
205
|
-
outcome: "All auth forms and guards updated",
|
|
206
|
-
must_do: "Follow existing component patterns, run component tests",
|
|
207
|
-
must_not: "Don't modify API contracts, don't add new dependencies",
|
|
208
|
-
});
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
## Anti-Patterns
|
|
212
|
-
|
|
213
|
-
### ❌ Too Many Teammates
|
|
214
|
-
|
|
215
|
-
```
|
|
216
|
-
Lead
|
|
217
|
-
├── T1: Button component ← Too granular
|
|
218
|
-
├── T2: Input component ← Too granular
|
|
219
|
-
├── T3: Form component ← Too granular
|
|
220
|
-
├── T4: Modal component ← Too granular
|
|
221
|
-
├── T5: Toast component ← Too granular
|
|
222
|
-
├── T6: Dialog component ← Too granular
|
|
223
|
-
├── T7: Dropdown component ← Too granular
|
|
224
|
-
└── T8: Tabs component ← Too granular
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
**Fix**: Group related work. 2-3 teammates handling related components each.
|
|
228
|
-
|
|
229
|
-
### ❌ Overlapping File Ownership
|
|
230
|
-
|
|
231
|
-
```
|
|
232
|
-
T1: Refactor auth service ← Both touch auth.ts!
|
|
233
|
-
T2: Add new auth endpoint ← Both touch auth.ts!
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
**Fix**: One teammate owns auth.ts changes. The other waits or works on different files.
|
|
237
|
-
|
|
238
|
-
### ❌ Missing Context
|
|
239
|
-
|
|
240
|
-
```
|
|
241
|
-
Task({ prompt: "Fix the auth bug" }) ← Which bug? What file? What behavior?
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
**Fix**: Include file paths, error messages, expected vs actual behavior, and reproduction steps.
|
|
245
|
-
|
|
246
|
-
### ❌ No Verification
|
|
247
|
-
|
|
248
|
-
```
|
|
249
|
-
Task({ prompt: "Implement feature X" }) ← No way to verify success
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
**Fix**: Include acceptance criteria: "Run `npm test auth`, ensure all pass. Run `npm run typecheck`."
|
|
253
|
-
|
|
254
|
-
## Checklist
|
|
255
|
-
|
|
256
|
-
Before dispatching a team:
|
|
257
|
-
|
|
258
|
-
- [ ] Identified 3+ independent tasks (otherwise use single agent)
|
|
259
|
-
- [ ] Each task has clear file ownership (no overlaps)
|
|
260
|
-
- [ ] Each task has self-contained context (files, patterns, constraints)
|
|
261
|
-
- [ ] Each task has acceptance criteria (verification commands)
|
|
262
|
-
- [ ] Lead has a synthesis plan (how to integrate results)
|
|
263
|
-
- [ ] Tasks are sized appropriately (5-6 per teammate max)
|
|
264
|
-
|
|
265
|
-
## See Also
|
|
266
|
-
|
|
267
|
-
- `dispatching-parallel-agents` — for independent debugging-focused parallel investigations
|
|
268
|
-
- `swarm-coordination` — for dependency-aware large-plan execution
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: code-navigation
|
|
3
|
-
description: Use when navigating unfamiliar code, tracing cross-file dependencies, or before editing — efficient code reading patterns that minimize tool calls and token waste
|
|
4
|
-
version: 1.0.0
|
|
5
|
-
tags: [workflow, code-quality, context]
|
|
6
|
-
dependencies: []
|
|
7
|
-
agent_types: [planner, worker, reviewer]
|
|
8
|
-
tools: []
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Code Navigation Skill
|
|
12
|
-
|
|
13
|
-
## When to Use
|
|
14
|
-
|
|
15
|
-
- Exploring an unfamiliar codebase or module
|
|
16
|
-
- Tracing a function call across multiple files
|
|
17
|
-
- Understanding blast radius before a breaking change
|
|
18
|
-
- Planning edits that touch multiple files
|
|
19
|
-
|
|
20
|
-
## When NOT to Use
|
|
21
|
-
|
|
22
|
-
- Simple single-file edits where you already know the location
|
|
23
|
-
- Reading config or documentation files
|
|
24
|
-
|
|
25
|
-
## Core Principle
|
|
26
|
-
|
|
27
|
-
> Collapse multiple tool calls into fewer, smarter ones. Every unnecessary read or search wastes tokens and turns.
|
|
28
|
-
|
|
29
|
-
## Choose The Right Navigation Tool
|
|
30
|
-
|
|
31
|
-
- Use `srcwalk_read`, `srcwalk_deps`, `grep`, `csearch` for file reading, blast-radius checks, pattern search, and multi-keyword chunk search
|
|
32
|
-
- Use `srcwalk_callers`, `srcwalk_callees`, `srcwalk_flow`, `srcwalk_impact`, `srcwalk_map` for call graphs, orientation slices, impact triage, and repo maps — these are first-class Pi tools, no separate skill load needed
|
|
33
|
-
- All tools are backed by the installed `srcwalk` binary via the `srcwalk.ts` extension
|
|
34
|
-
|
|
35
|
-
## Navigation Patterns
|
|
36
|
-
|
|
37
|
-
### Pattern 1: Search First, Read Second
|
|
38
|
-
|
|
39
|
-
**Wrong** (3-6 tool calls):
|
|
40
|
-
```
|
|
41
|
-
glob("*.ts") → read(file1) → "too big" → grep("functionName") → read(file2) → read(file3, section)
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
**Right** (1-2 tool calls):
|
|
45
|
-
```
|
|
46
|
-
grep("functionName", path: "src/") → read(exact_file, offset: line-10, limit: 30)
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Start with `grep` or `csearch` to locate, then read only what you need.
|
|
50
|
-
|
|
51
|
-
### Pattern 2: Multi-Symbol Search
|
|
52
|
-
|
|
53
|
-
When tracing a call chain (A calls B calls C), search for all symbols together:
|
|
54
|
-
```
|
|
55
|
-
grep({ pattern: "functionA|functionB|functionC", path: "src/" })
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
Or use `srcwalk_callers` for structural caller detection, or `srcwalk_flow` for a combined callers+callees+resolves slice.
|
|
59
|
-
|
|
60
|
-
### Pattern 3: Don't Re-Read What You've Already Seen
|
|
61
|
-
|
|
62
|
-
**Anti-pattern**: Search returns full function body, then agent reads the same file again.
|
|
63
|
-
|
|
64
|
-
If search results already show the code you need, work from that output. Only re-read when:
|
|
65
|
-
- You need surrounding context (lines above/below the match)
|
|
66
|
-
- You need the exact content for editing (verify before edit)
|
|
67
|
-
- The search result was truncated
|
|
68
|
-
|
|
69
|
-
### Pattern 4: Blast Radius Check (Before Breaking Changes)
|
|
70
|
-
|
|
71
|
-
**WHEN**: Before renaming, removing, or changing the signature of an export.
|
|
72
|
-
**SKIP**: When adding new code, fixing internal bugs, or reading.
|
|
73
|
-
|
|
74
|
-
Steps:
|
|
75
|
-
1. `srcwalk_deps(path: "src/file.ts")` — find importers and downstream users
|
|
76
|
-
2. `srcwalk_callers({ symbol: "symbolName", scope: "src" })` — find call sites with optional depth/filter
|
|
77
|
-
3. Review each caller to assess impact
|
|
78
|
-
4. Plan edits from leaf callers inward (furthest dependencies first)
|
|
79
|
-
|
|
80
|
-
### Pattern 5: Context Locality
|
|
81
|
-
|
|
82
|
-
When editing a file, search results from the same directory/package are more likely relevant. Use `path` to scope grep results:
|
|
83
|
-
- `grep({ pattern: "...", path: "src/same-module/" })`
|
|
84
|
-
|
|
85
|
-
### Pattern 6: Outline Before Deep Read
|
|
86
|
-
|
|
87
|
-
For large files (>200 lines), get the structure first:
|
|
88
|
-
```
|
|
89
|
-
srcwalk_read(path: "src/large-file.ts")
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
This gives you structure and line ranges. Then read only the section you need.
|
|
93
|
-
|
|
94
|
-
### Pattern 7: Follow the Call Chain (Not the File Tree)
|
|
95
|
-
|
|
96
|
-
**Wrong**: Read files top-to-bottom hoping to understand the flow.
|
|
97
|
-
**Right**: Start from the entry point, follow function calls:
|
|
98
|
-
|
|
99
|
-
```
|
|
100
|
-
1. `grep({ pattern: "entryPoint" })` → find where it is defined
|
|
101
|
-
2. `srcwalk_callees({ symbol: "entryPoint", scope: "src" })` or `srcwalk_flow` for call graph orientation
|
|
102
|
-
3. `srcwalk_read(section: "line-range")` → drill into the interesting callee
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## With Srcwalk Backend
|
|
106
|
-
|
|
107
|
-
All navigation tools are native srcwalk_* tools. Available tools:
|
|
108
|
-
|
|
109
|
-
| Task | Tool | Notes |
|
|
110
|
-
|---|---|---|
|
|
111
|
-
| Pattern search | `grep` | Exact/regex symbol search, multi-pattern, scoped |
|
|
112
|
-
| Multi-keyword chunk search | `csearch` | Find code by multiple keywords, returns ranked function/class chunks |
|
|
113
|
-
| Find files by glob | `glob` | Built-in glob file discovery |
|
|
114
|
-
| Large file read | `srcwalk_read` | Auto-outlines, shows structure |
|
|
115
|
-
| Direct callers | `srcwalk_callers` | Structural call-site evidence |
|
|
116
|
-
| Transitive callers | `srcwalk_callers(depth: N)` | Multi-hop BFS up to 5 |
|
|
117
|
-
| Forward call graph | `srcwalk_callees(detailed: true)` | Ordered sites with arg slots |
|
|
118
|
-
| Function orientation | `srcwalk_flow` | Callers + callees + resolves |
|
|
119
|
-
| Import + dependents | `srcwalk_deps` | File-scoped import evidence + heuristic |
|
|
120
|
-
| Heuristic triage | `srcwalk_impact` | Follow up with callers for proof |
|
|
121
|
-
| Repo shape | `srcwalk_map` | Token budgets + directory skeleton |
|
|
122
|
-
|
|
123
|
-
**IMPORTANT**: Use `grep` for exact-pattern searches, `csearch` for multi-keyword chunk discovery, and `srcwalk_*` tools for structural navigation (call graphs, deps, file reads).
|
|
124
|
-
|
|
125
|
-
## Cost Awareness
|
|
126
|
-
|
|
127
|
-
Every tool call has a token cost. Efficient navigation means:
|
|
128
|
-
- Fewer tool calls per task
|
|
129
|
-
- Less context consumed by redundant reads
|
|
130
|
-
- More budget available for actual implementation
|
|
131
|
-
|
|
132
|
-
**Target**: Find and understand any symbol in ≤3 tool calls, not 6+.
|
|
133
|
-
|
|
134
|
-
## Common Mistakes
|
|
135
|
-
|
|
136
|
-
| Mistake | Fix |
|
|
137
|
-
|---|---|
|
|
138
|
-
| Read entire large file | Use outline first, then section read |
|
|
139
|
-
| Search → read same code again | Work from search results directly |
|
|
140
|
-
| Trace calls one-by-one | `srcwalk_callers` / `srcwalk_callees` or multi-pattern `grep` |
|
|
141
|
-
| Explore randomly | Start from entry point, follow calls |
|
|
142
|
-
| Forget to check blast radius | Always check before signature changes |
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: condition-based-waiting
|
|
3
|
-
description: Use when tests have race conditions, timing dependencies, or inconsistent pass/fail behavior - replaces arbitrary timeouts with condition polling to wait for actual state changes, eliminating flaky tests from timing guesses
|
|
4
|
-
version: 1.0.0
|
|
5
|
-
tags: [testing, debugging]
|
|
6
|
-
dependencies: []
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Condition-Based Waiting
|
|
10
|
-
|
|
11
|
-
> **Replaces** arbitrary `sleep()` / `setTimeout()` calls and hardcoded delays that cause flaky tests and slow CI
|
|
12
|
-
|
|
13
|
-
## When to Use
|
|
14
|
-
|
|
15
|
-
- Tests are flaky due to arbitrary delays or timing guesses
|
|
16
|
-
- You need to wait for async state changes (events, file writes, state transitions)
|
|
17
|
-
|
|
18
|
-
## When NOT to Use
|
|
19
|
-
|
|
20
|
-
- You are explicitly testing timing behavior (debounce, throttle, intervals)
|
|
21
|
-
- A fixed, documented timeout is part of the requirement
|
|
22
|
-
|
|
23
|
-
## Common Rationalizations
|
|
24
|
-
|
|
25
|
-
| Rationalization | Rebuttal |
|
|
26
|
-
| --------------------------------------------- | ------------------------------------------------------------------------------ |
|
|
27
|
-
| "50ms is plenty of time" | It's plenty on YOUR machine. CI runners under load disagree |
|
|
28
|
-
| "The sleep worked in local testing" | Local = fast SSD, idle CPU. CI = shared resources, variable latency |
|
|
29
|
-
| "Adding a waitFor is more complex than sleep" | A 5-line waitFor is simpler than debugging a flaky test 10 times |
|
|
30
|
-
| "This operation is always fast" | "Always" until garbage collection, disk I/O, or network latency says otherwise |
|
|
31
|
-
| "I'll increase the timeout if it flakes" | Increasing timeouts slows the entire suite and masks the real problem |
|
|
32
|
-
| "It only fails sometimes" | "Sometimes" = race condition. Condition-based waiting eliminates it entirely |
|
|
33
|
-
|
|
34
|
-
## Overview
|
|
35
|
-
|
|
36
|
-
Flaky tests often guess at timing with arbitrary delays. This creates race conditions where tests pass on fast machines but fail under load or in CI.
|
|
37
|
-
|
|
38
|
-
**Core principle:** Wait for the actual condition you care about, not a guess about how long it takes.
|
|
39
|
-
|
|
40
|
-
## Core Pattern
|
|
41
|
-
|
|
42
|
-
```typescript
|
|
43
|
-
// ❌ BEFORE: Guessing at timing
|
|
44
|
-
await new Promise((r) => setTimeout(r, 50));
|
|
45
|
-
const result = getResult();
|
|
46
|
-
expect(result).toBeDefined();
|
|
47
|
-
|
|
48
|
-
// ✅ AFTER: Waiting for condition
|
|
49
|
-
await waitFor(() => getResult() !== undefined);
|
|
50
|
-
const result = getResult();
|
|
51
|
-
expect(result).toBeDefined();
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Quick Patterns
|
|
55
|
-
|
|
56
|
-
| Scenario | Pattern |
|
|
57
|
-
| ----------------- | ---------------------------------------------------- |
|
|
58
|
-
| Wait for event | `waitFor(() => events.find(e => e.type === 'DONE'))` |
|
|
59
|
-
| Wait for state | `waitFor(() => machine.state === 'ready')` |
|
|
60
|
-
| Wait for count | `waitFor(() => items.length >= 5)` |
|
|
61
|
-
| Wait for file | `waitFor(() => fs.existsSync(path))` |
|
|
62
|
-
| Complex condition | `waitFor(() => obj.ready && obj.value > 10)` |
|
|
63
|
-
|
|
64
|
-
## Implementation
|
|
65
|
-
|
|
66
|
-
Generic polling function:
|
|
67
|
-
|
|
68
|
-
```typescript
|
|
69
|
-
async function waitFor<T>(
|
|
70
|
-
condition: () => T | undefined | null | false,
|
|
71
|
-
description: string,
|
|
72
|
-
timeoutMs = 5000,
|
|
73
|
-
): Promise<T> {
|
|
74
|
-
const startTime = Date.now();
|
|
75
|
-
|
|
76
|
-
while (true) {
|
|
77
|
-
const result = condition();
|
|
78
|
-
if (result) return result;
|
|
79
|
-
|
|
80
|
-
if (Date.now() - startTime > timeoutMs) {
|
|
81
|
-
throw new Error(`Timeout waiting for ${description} after ${timeoutMs}ms`);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
await new Promise((r) => setTimeout(r, 10)); // Poll every 10ms
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
See @example.ts for complete implementation with domain-specific helpers (`waitForEvent`, `waitForEventCount`, `waitForEventMatch`) from actual debugging session.
|
|
90
|
-
|
|
91
|
-
## Common Mistakes
|
|
92
|
-
|
|
93
|
-
**❌ Polling too fast:** `setTimeout(check, 1)` - wastes CPU
|
|
94
|
-
**✅ Fix:** Poll every 10ms
|
|
95
|
-
|
|
96
|
-
**❌ No timeout:** Loop forever if condition never met
|
|
97
|
-
**✅ Fix:** Always include timeout with clear error
|
|
98
|
-
|
|
99
|
-
**❌ Stale data:** Cache state before loop
|
|
100
|
-
**✅ Fix:** Call getter inside loop for fresh data
|
|
101
|
-
|
|
102
|
-
## When Arbitrary Timeout IS Correct
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
// Tool ticks every 100ms - need 2 ticks to verify partial output
|
|
106
|
-
await waitForEvent(manager, "TOOL_STARTED"); // First: wait for condition
|
|
107
|
-
await new Promise((r) => setTimeout(r, 200)); // Then: wait for timed behavior
|
|
108
|
-
// 200ms = 2 ticks at 100ms intervals - documented and justified
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
**Requirements:**
|
|
112
|
-
|
|
113
|
-
1. First wait for triggering condition
|
|
114
|
-
2. Based on known timing (not guessing)
|
|
115
|
-
3. Comment explaining WHY
|
|
116
|
-
|
|
117
|
-
## Verification
|
|
118
|
-
|
|
119
|
-
- **After applying:** run the previously flaky test 5+ times — should pass consistently
|
|
120
|
-
- **Check:** no hardcoded sleep/delay values remain in the test file
|
|
121
|
-
- **Measure:** test execution time should decrease (no wasted wait time)
|
|
122
|
-
|
|
123
|
-
## Real-World Impact
|
|
124
|
-
|
|
125
|
-
From debugging session (2025-10-03):
|
|
126
|
-
|
|
127
|
-
- Fixed 15 flaky tests across 3 files
|
|
128
|
-
- Pass rate: 60% → 100%
|
|
129
|
-
- Execution time: 40% faster
|
|
130
|
-
- No more race conditions
|
|
131
|
-
|
|
132
|
-
## See Also
|
|
133
|
-
|
|
134
|
-
- `systematic-debugging`
|
|
135
|
-
- `test-driven-development`
|