claude-all-config 2.0.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/LICENSE +21 -0
- package/LICENSE.md +70 -0
- package/README.md +133 -0
- package/VERSION +1 -0
- package/agents/accessibility-reviewer.md +96 -0
- package/agents/ai-prompt-optimizer.md +94 -0
- package/agents/api-tester.md +102 -0
- package/agents/code-generator.md +94 -0
- package/agents/code-reviewer.md +47 -0
- package/agents/component-generator.md +102 -0
- package/agents/doc-generator.md +91 -0
- package/agents/migration-generator.md +94 -0
- package/agents/performance-analyzer.md +90 -0
- package/agents/proactive-mode.md +91 -0
- package/agents/readme-generator.md +101 -0
- package/agents/security-auditor.md +86 -0
- package/agents/terraform-generator.md +94 -0
- package/agents/test-generator.md +76 -0
- package/bin/agentrouter.json +36 -0
- package/bin/ai-chat +20 -0
- package/bin/antigravity.json +76 -0
- package/bin/api-manager +340 -0
- package/bin/claude-launcher +19 -0
- package/bin/claude-master +15 -0
- package/bin/claude_master.py +295 -0
- package/bin/cohere.json +7 -0
- package/bin/deepseek.json +44 -0
- package/bin/gemini.json +56 -0
- package/bin/glm.json +21 -0
- package/bin/groq.json +41 -0
- package/bin/minimax.json +26 -0
- package/bin/mistral.json +7 -0
- package/bin/moonshot.json +7 -0
- package/bin/ollama.json +36 -0
- package/bin/openai.json +46 -0
- package/bin/openrouter.json +38 -0
- package/bin/perplexity.json +12 -0
- package/bin/qwen.json +7 -0
- package/bin/switch-provider +73 -0
- package/bin/test.json +7 -0
- package/bin/xai.json +41 -0
- package/claude-all +2707 -0
- package/claude-config.json +340 -0
- package/claude-suite/REFACTORING_SUMMARY.md +88 -0
- package/claude-suite/auth/.antigravity_proxy.py +78 -0
- package/claude-suite/auth/__pycache__/openai_auth.cpython-312.pyc +0 -0
- package/claude-suite/auth/gemini_auth.py +80 -0
- package/claude-suite/auth/openai_auth.py +138 -0
- package/claude-suite/backups/claude-all-before-refactor +1075 -0
- package/claude-suite/backups/claude-all.backup +840 -0
- package/claude-suite/backups/claude-all.original +840 -0
- package/claude-suite/models/add-model-manual.sh +588 -0
- package/claude-suite/models/add-model.sh +114 -0
- package/claude-suite/models/model-switcher.sh +69 -0
- package/claude-suite/providers/claude-glm +89 -0
- package/claude-suite/providers/claude-glm-wrapper.sh +55 -0
- package/claude-suite/providers/claude-minimax +12 -0
- package/claude-suite/providers/claude-smart +132 -0
- package/claude-suite/providers/xai_chat.sh +56 -0
- package/claude-suite/utils/__pycache__/claude_master.cpython-312.pyc +0 -0
- package/claude-suite/utils/antigravity_proxy_server.py +168 -0
- package/claude-suite/utils/claude-all-help.txt +83 -0
- package/claude-suite/utils/claude_master.py +408 -0
- package/commands/brainstorm.md +5 -0
- package/commands/execute-plan.md +5 -0
- package/commands/write-plan.md +5 -0
- package/docs/ANTIGRAVITY-SETUP.md +176 -0
- package/docs/AUTH_CREDENTIALS.md +54 -0
- package/docs/NPM-INSTALLATION.md +166 -0
- package/hooks/hooks.json +15 -0
- package/hooks/run-hook.cmd +19 -0
- package/hooks/session-start.sh +52 -0
- package/install.sh +155 -0
- package/mcp.json +34 -0
- package/model/perplexity.json +12 -0
- package/package.json +69 -0
- package/plugins/README.md +47 -0
- package/plugins/installed_plugins.json +317 -0
- package/plugins/known_marketplaces.json +10 -0
- package/plugins/marketplace-info/marketplace.json +517 -0
- package/postinstall.js +100 -0
- package/scripts/antigravity_proxy_server.py +168 -0
- package/scripts/get_gemini_api_key.py +96 -0
- package/scripts/setup_antigravity_auth.py +171 -0
- package/skills/api-development/SKILL.md +11 -0
- package/skills/api-development/openapi/api-documentation.yaml +108 -0
- package/skills/brainstorming/SKILL.md +54 -0
- package/skills/code-quality/SKILL.md +196 -0
- package/skills/condition-based-waiting/SKILL.md +120 -0
- package/skills/condition-based-waiting/example.ts +158 -0
- package/skills/database-development/SKILL.md +11 -0
- package/skills/database-development/migrations/migration.template.sql +49 -0
- package/skills/defense-in-depth/SKILL.md +127 -0
- package/skills/deployment/SKILL.md +11 -0
- package/skills/deployment/ci-cd/github-actions.yml +95 -0
- package/skills/deployment/docker/Dockerfile.template +39 -0
- package/skills/dispatching-parallel-agents/SKILL.md +180 -0
- package/skills/documentation-generation/SKILL.md +8 -0
- package/skills/documentation-generation/templates/README.template.md +60 -0
- package/skills/error-handling/SKILL.md +267 -0
- package/skills/executing-plans/SKILL.md +76 -0
- package/skills/finishing-a-development-branch/SKILL.md +200 -0
- package/skills/frontend-design/frontend-design/SKILL.md +42 -0
- package/skills/integration-testing/SKILL.md +13 -0
- package/skills/integration-testing/examples/contract-test.py +317 -0
- package/skills/integration-testing/examples/e2e-test.js +147 -0
- package/skills/integration-testing/examples/test-isolation.md +94 -0
- package/skills/logging-monitoring/SKILL.md +66 -0
- package/skills/mobile-development/SKILL.md +11 -0
- package/skills/mobile-development/responsive/responsive.css +80 -0
- package/skills/performance-optimization/SKILL.md +9 -0
- package/skills/performance-optimization/profiling/profile.template.js +21 -0
- package/skills/receiving-code-review/SKILL.md +209 -0
- package/skills/refactoring/SKILL.md +11 -0
- package/skills/refactoring/code-smells/common-smells.md +115 -0
- package/skills/requesting-code-review/SKILL.md +105 -0
- package/skills/requesting-code-review/code-reviewer.md +146 -0
- package/skills/root-cause-tracing/SKILL.md +174 -0
- package/skills/root-cause-tracing/find-polluter.sh +63 -0
- package/skills/security-review/SKILL.md +11 -0
- package/skills/security-review/checklists/owasp-checklist.md +31 -0
- package/skills/sharing-skills/SKILL.md +194 -0
- package/skills/subagent-driven-development/SKILL.md +240 -0
- package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +20 -0
- package/skills/subagent-driven-development/implementer-prompt.md +78 -0
- package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/skills/systematic-debugging/SKILL.md +295 -0
- package/skills/systematic-debugging/test-academic.md +14 -0
- package/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/skills/test-driven-development/SKILL.md +364 -0
- package/skills/testing-anti-patterns/SKILL.md +302 -0
- package/skills/testing-skills-with-subagents/SKILL.md +387 -0
- package/skills/testing-skills-with-subagents/examples/CLAUDE_MD_TESTING.md +189 -0
- package/skills/ui-ux-review/SKILL.md +13 -0
- package/skills/ui-ux-review/checklists/ux-heuristics.md +61 -0
- package/skills/using-git-worktrees/SKILL.md +213 -0
- package/skills/using-superpowers/SKILL.md +101 -0
- package/skills/verification-before-completion/SKILL.md +139 -0
- package/skills/writing-plans/SKILL.md +116 -0
- package/skills/writing-skills/SKILL.md +622 -0
- package/skills/writing-skills/anthropic-best-practices.md +1150 -0
- package/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/skills/writing-skills/persuasion-principles.md +187 -0
- package/update.sh +36 -0
- package/utils/check-superpowers.sh +114 -0
- package/utils/claude-branding.md +166 -0
- package/utils/config.js +185 -0
- package/utils/custom-claude-config.sh +89 -0
- package/utils/custom-claude-hooks.md +129 -0
- package/utils/custom-claude-lib.js +222 -0
- package/utils/customize-claude-ui.sh +162 -0
- package/utils/fix-claude-integration.sh +133 -0
- package/utils/help.js +125 -0
- package/utils/install-curl.ps1 +135 -0
- package/utils/install-curl.sh +525 -0
- package/utils/install-superpowers.js +411 -0
- package/utils/install.js +298 -0
- package/utils/install.sh +182 -0
- package/utils/postinstall.js +63 -0
- package/utils/rename-claude.sh +96 -0
- package/utils/uninstall-superpowers.js +273 -0
- package/utils/uninstall.ps1 +136 -0
- package/utils/uninstall.sh +163 -0
- package/utils/update.sh +160 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: code-quality
|
|
3
|
+
description: Use when the code has become difficult to understand, modify, or maintain, or when code smells or anti-patterns have accumulated - identify code smells, suggest improvements, and refactor systematically while preserving functionality
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Code Quality Skill
|
|
7
|
+
|
|
8
|
+
You are a Code Quality Expert specializing in improving code maintainability, readability, and structure. Your expertise includes:
|
|
9
|
+
|
|
10
|
+
- **Code Smell Detection**: Identify problematic code patterns
|
|
11
|
+
- **Refactoring Strategies**: Systematic approaches to improve code
|
|
12
|
+
- **Maintainability**: Make code easier to understand and modify
|
|
13
|
+
- **Documentation**: Ensure code is well-documented
|
|
14
|
+
|
|
15
|
+
## When to Use
|
|
16
|
+
|
|
17
|
+
Trigger this skill when:
|
|
18
|
+
|
|
19
|
+
- **Code Smell Accumulation**: Too many quick fixes have created technical debt
|
|
20
|
+
- **Readability Crisis**: Code has become difficult to understand
|
|
21
|
+
- **Maintenance Nightmare**: Changes keep breaking things
|
|
22
|
+
- "This code is a mess" or similar sentiments from the team
|
|
23
|
+
- **Performance Issues**: Code is slow or inefficient
|
|
24
|
+
- "Why is this so complex?" or similar questions
|
|
25
|
+
|
|
26
|
+
## Code Quality Fundamentals
|
|
27
|
+
|
|
28
|
+
### Identify Code Smells
|
|
29
|
+
|
|
30
|
+
Look for these common code smells:
|
|
31
|
+
|
|
32
|
+
#### 1. Duplicated Code
|
|
33
|
+
- Same logic appears in multiple places
|
|
34
|
+
- Copy-pasted code without abstraction
|
|
35
|
+
- Extract to function or method
|
|
36
|
+
|
|
37
|
+
#### 2. Long Methods/Functions
|
|
38
|
+
- Methods over 50-100 lines (depends on language)
|
|
39
|
+
- Doing too many things
|
|
40
|
+
- Break down into smaller functions
|
|
41
|
+
|
|
42
|
+
#### 3. Large Classes/Modules
|
|
43
|
+
- Class/module with too many responsibilities
|
|
44
|
+
- God object anti-pattern
|
|
45
|
+
- Apply Single Responsibility Principle
|
|
46
|
+
|
|
47
|
+
#### 4. Complex Conditionals
|
|
48
|
+
- Nested if/else or switch statements
|
|
49
|
+
- More than 3 levels of nesting
|
|
50
|
+
- Use guard clauses or early returns
|
|
51
|
+
|
|
52
|
+
#### 5. Magic Numbers/Strings
|
|
53
|
+
- Hardcoded values without explanation
|
|
54
|
+
- Create constants or configuration
|
|
55
|
+
|
|
56
|
+
#### 6. Poor Naming
|
|
57
|
+
- cryptic variable names (a, b, x, tmp, temp)
|
|
58
|
+
- Names that don't describe purpose
|
|
59
|
+
- Use descriptive names
|
|
60
|
+
|
|
61
|
+
#### 7. Dead Code
|
|
62
|
+
- Commented out code that should be removed
|
|
63
|
+
- Unused variables/functions
|
|
64
|
+
- Import statements for unused items
|
|
65
|
+
|
|
66
|
+
#### 8. God Methods
|
|
67
|
+
- Methods that do too much
|
|
68
|
+
- Try to do everything in one function
|
|
69
|
+
- Break down into smaller, testable units
|
|
70
|
+
|
|
71
|
+
## Quality Indicators
|
|
72
|
+
|
|
73
|
+
Good code should be:
|
|
74
|
+
- ✅ **Readable**: Self-documenting with clear names
|
|
75
|
+
- ✅ **Modular**: Broken into small, focused units
|
|
76
|
+
- ✅ **Testable**: Easy to unit test in isolation
|
|
77
|
+
- ✅ **Maintainable**: Easy to modify without breaking things
|
|
78
|
+
- ✅ **Well-Documented**: Comments explain WHY not WHAT
|
|
79
|
+
- ✅ **Consistent**: Follows team conventions and patterns
|
|
80
|
+
|
|
81
|
+
## Refactoring Process
|
|
82
|
+
|
|
83
|
+
### Phase 1: Analyze
|
|
84
|
+
1. Read the target code thoroughly
|
|
85
|
+
2. Understand what it does and why it exists
|
|
86
|
+
3. Identify specific code smells
|
|
87
|
+
4. Determine refactoring priority
|
|
88
|
+
|
|
89
|
+
### Phase 2: Plan
|
|
90
|
+
1. List all identified issues
|
|
91
|
+
2. Categorize by severity (high/medium/low)
|
|
92
|
+
3. Identify dependencies between issues
|
|
93
|
+
4. Create refactoring strategy
|
|
94
|
+
|
|
95
|
+
### Phase 3: Execute
|
|
96
|
+
1. Start with easiest wins (low hanging fruit)
|
|
97
|
+
2. Refactor incrementally with tests at each step
|
|
98
|
+
3. Run tests after each change
|
|
99
|
+
4. Update documentation
|
|
100
|
+
|
|
101
|
+
### Phase 4: Verify
|
|
102
|
+
1. Ensure all tests still pass
|
|
103
|
+
2. Check performance hasn't degraded
|
|
104
|
+
3. Get code review if available
|
|
105
|
+
4. Update documentation
|
|
106
|
+
|
|
107
|
+
## Refactoring Techniques
|
|
108
|
+
|
|
109
|
+
### Extract Method
|
|
110
|
+
- Break large method into smaller methods
|
|
111
|
+
- Each method does one thing well
|
|
112
|
+
- Use meaningful names
|
|
113
|
+
|
|
114
|
+
### Extract Class
|
|
115
|
+
- Extract related functionality into new class
|
|
116
|
+
- Single Responsibility Principle
|
|
117
|
+
- Reduce class size
|
|
118
|
+
|
|
119
|
+
### Replace Magic with Constants
|
|
120
|
+
```python
|
|
121
|
+
# Before
|
|
122
|
+
if user_age > 18: # What is 18?
|
|
123
|
+
return True
|
|
124
|
+
|
|
125
|
+
# After
|
|
126
|
+
ADULT_AGE = 18
|
|
127
|
+
if user_age > ADULT_AGE:
|
|
128
|
+
return True
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Simplify Conditionals
|
|
132
|
+
```python
|
|
133
|
+
# Before
|
|
134
|
+
if condition_a and condition_b:
|
|
135
|
+
do_thing()
|
|
136
|
+
elif condition_c:
|
|
137
|
+
do_alternative()
|
|
138
|
+
else:
|
|
139
|
+
do_default()
|
|
140
|
+
|
|
141
|
+
# After
|
|
142
|
+
if is_adult(): # Guard clause
|
|
143
|
+
do_thing()
|
|
144
|
+
return
|
|
145
|
+
do_alternative()
|
|
146
|
+
do_default()
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Extract Variable/Function
|
|
150
|
+
- Extract repeated logic into reusable components
|
|
151
|
+
- Reduce duplication, improve maintainability
|
|
152
|
+
|
|
153
|
+
## Performance Considerations
|
|
154
|
+
|
|
155
|
+
- Don't optimize prematurely
|
|
156
|
+
- Measure before optimizing
|
|
157
|
+
- Profile to find real bottlenecks
|
|
158
|
+
- Consider time vs space trade-offs
|
|
159
|
+
|
|
160
|
+
## Testing Quality
|
|
161
|
+
|
|
162
|
+
- Ensure 100% test coverage on refactored code
|
|
163
|
+
- Don't break existing functionality
|
|
164
|
+
- Add tests for new extracted functions
|
|
165
|
+
|
|
166
|
+
## Document Changes
|
|
167
|
+
|
|
168
|
+
- Update JSDoc comments/docstrings
|
|
169
|
+
- Update README if public API changes
|
|
170
|
+
- Document refactoring reason
|
|
171
|
+
- Update architecture diagrams if needed
|
|
172
|
+
|
|
173
|
+
## Output
|
|
174
|
+
|
|
175
|
+
Provide:
|
|
176
|
+
|
|
177
|
+
1. **Code Quality Assessment**:
|
|
178
|
+
- List found code smells
|
|
179
|
+
- Severity: Critical/High/Medium/Low
|
|
180
|
+
|
|
181
|
+
2. **Refactoring Plan**:
|
|
182
|
+
- List of refactorings with priorities
|
|
183
|
+
- Estimated time for each refactoring
|
|
184
|
+
|
|
185
|
+
3. Execute refactorings:
|
|
186
|
+
- Run tests after each refactoring step
|
|
187
|
+
- Update documentation
|
|
188
|
+
|
|
189
|
+
4. Quality Metrics:
|
|
190
|
+
- Cyclomatic complexity (lower is better)
|
|
191
|
+
- Lines of code (should decrease)
|
|
192
|
+
- Test coverage (should maintain 100%)
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
**Remember**: The best refactoring is the one that makes the code simpler, not more complex!
|
|
@@ -0,0 +1,120 @@
|
|
|
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
|
+
---
|
|
5
|
+
|
|
6
|
+
# Condition-Based Waiting
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
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.
|
|
11
|
+
|
|
12
|
+
**Core principle:** Wait for the actual condition you care about, not a guess about how long it takes.
|
|
13
|
+
|
|
14
|
+
## When to Use
|
|
15
|
+
|
|
16
|
+
```dot
|
|
17
|
+
digraph when_to_use {
|
|
18
|
+
"Test uses setTimeout/sleep?" [shape=diamond];
|
|
19
|
+
"Testing timing behavior?" [shape=diamond];
|
|
20
|
+
"Document WHY timeout needed" [shape=box];
|
|
21
|
+
"Use condition-based waiting" [shape=box];
|
|
22
|
+
|
|
23
|
+
"Test uses setTimeout/sleep?" -> "Testing timing behavior?" [label="yes"];
|
|
24
|
+
"Testing timing behavior?" -> "Document WHY timeout needed" [label="yes"];
|
|
25
|
+
"Testing timing behavior?" -> "Use condition-based waiting" [label="no"];
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Use when:**
|
|
30
|
+
- Tests have arbitrary delays (`setTimeout`, `sleep`, `time.sleep()`)
|
|
31
|
+
- Tests are flaky (pass sometimes, fail under load)
|
|
32
|
+
- Tests timeout when run in parallel
|
|
33
|
+
- Waiting for async operations to complete
|
|
34
|
+
|
|
35
|
+
**Don't use when:**
|
|
36
|
+
- Testing actual timing behavior (debounce, throttle intervals)
|
|
37
|
+
- Always document WHY if using arbitrary timeout
|
|
38
|
+
|
|
39
|
+
## Core Pattern
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// ❌ BEFORE: Guessing at timing
|
|
43
|
+
await new Promise(r => setTimeout(r, 50));
|
|
44
|
+
const result = getResult();
|
|
45
|
+
expect(result).toBeDefined();
|
|
46
|
+
|
|
47
|
+
// ✅ AFTER: Waiting for condition
|
|
48
|
+
await waitFor(() => getResult() !== undefined);
|
|
49
|
+
const result = getResult();
|
|
50
|
+
expect(result).toBeDefined();
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Quick Patterns
|
|
54
|
+
|
|
55
|
+
| Scenario | Pattern |
|
|
56
|
+
|----------|---------|
|
|
57
|
+
| Wait for event | `waitFor(() => events.find(e => e.type === 'DONE'))` |
|
|
58
|
+
| Wait for state | `waitFor(() => machine.state === 'ready')` |
|
|
59
|
+
| Wait for count | `waitFor(() => items.length >= 5)` |
|
|
60
|
+
| Wait for file | `waitFor(() => fs.existsSync(path))` |
|
|
61
|
+
| Complex condition | `waitFor(() => obj.ready && obj.value > 10)` |
|
|
62
|
+
|
|
63
|
+
## Implementation
|
|
64
|
+
|
|
65
|
+
Generic polling function:
|
|
66
|
+
```typescript
|
|
67
|
+
async function waitFor<T>(
|
|
68
|
+
condition: () => T | undefined | null | false,
|
|
69
|
+
description: string,
|
|
70
|
+
timeoutMs = 5000
|
|
71
|
+
): Promise<T> {
|
|
72
|
+
const startTime = Date.now();
|
|
73
|
+
|
|
74
|
+
while (true) {
|
|
75
|
+
const result = condition();
|
|
76
|
+
if (result) return result;
|
|
77
|
+
|
|
78
|
+
if (Date.now() - startTime > timeoutMs) {
|
|
79
|
+
throw new Error(`Timeout waiting for ${description} after ${timeoutMs}ms`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
await new Promise(r => setTimeout(r, 10)); // Poll every 10ms
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
See @example.ts for complete implementation with domain-specific helpers (`waitForEvent`, `waitForEventCount`, `waitForEventMatch`) from actual debugging session.
|
|
88
|
+
|
|
89
|
+
## Common Mistakes
|
|
90
|
+
|
|
91
|
+
**❌ Polling too fast:** `setTimeout(check, 1)` - wastes CPU
|
|
92
|
+
**✅ Fix:** Poll every 10ms
|
|
93
|
+
|
|
94
|
+
**❌ No timeout:** Loop forever if condition never met
|
|
95
|
+
**✅ Fix:** Always include timeout with clear error
|
|
96
|
+
|
|
97
|
+
**❌ Stale data:** Cache state before loop
|
|
98
|
+
**✅ Fix:** Call getter inside loop for fresh data
|
|
99
|
+
|
|
100
|
+
## When Arbitrary Timeout IS Correct
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
// Tool ticks every 100ms - need 2 ticks to verify partial output
|
|
104
|
+
await waitForEvent(manager, 'TOOL_STARTED'); // First: wait for condition
|
|
105
|
+
await new Promise(r => setTimeout(r, 200)); // Then: wait for timed behavior
|
|
106
|
+
// 200ms = 2 ticks at 100ms intervals - documented and justified
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Requirements:**
|
|
110
|
+
1. First wait for triggering condition
|
|
111
|
+
2. Based on known timing (not guessing)
|
|
112
|
+
3. Comment explaining WHY
|
|
113
|
+
|
|
114
|
+
## Real-World Impact
|
|
115
|
+
|
|
116
|
+
From debugging session (2025-10-03):
|
|
117
|
+
- Fixed 15 flaky tests across 3 files
|
|
118
|
+
- Pass rate: 60% → 100%
|
|
119
|
+
- Execution time: 40% faster
|
|
120
|
+
- No more race conditions
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// Complete implementation of condition-based waiting utilities
|
|
2
|
+
// From: Lace test infrastructure improvements (2025-10-03)
|
|
3
|
+
// Context: Fixed 15 flaky tests by replacing arbitrary timeouts
|
|
4
|
+
|
|
5
|
+
import type { ThreadManager } from '~/threads/thread-manager';
|
|
6
|
+
import type { LaceEvent, LaceEventType } from '~/threads/types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Wait for a specific event type to appear in thread
|
|
10
|
+
*
|
|
11
|
+
* @param threadManager - The thread manager to query
|
|
12
|
+
* @param threadId - Thread to check for events
|
|
13
|
+
* @param eventType - Type of event to wait for
|
|
14
|
+
* @param timeoutMs - Maximum time to wait (default 5000ms)
|
|
15
|
+
* @returns Promise resolving to the first matching event
|
|
16
|
+
*
|
|
17
|
+
* Example:
|
|
18
|
+
* await waitForEvent(threadManager, agentThreadId, 'TOOL_RESULT');
|
|
19
|
+
*/
|
|
20
|
+
export function waitForEvent(
|
|
21
|
+
threadManager: ThreadManager,
|
|
22
|
+
threadId: string,
|
|
23
|
+
eventType: LaceEventType,
|
|
24
|
+
timeoutMs = 5000
|
|
25
|
+
): Promise<LaceEvent> {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
const startTime = Date.now();
|
|
28
|
+
|
|
29
|
+
const check = () => {
|
|
30
|
+
const events = threadManager.getEvents(threadId);
|
|
31
|
+
const event = events.find((e) => e.type === eventType);
|
|
32
|
+
|
|
33
|
+
if (event) {
|
|
34
|
+
resolve(event);
|
|
35
|
+
} else if (Date.now() - startTime > timeoutMs) {
|
|
36
|
+
reject(new Error(`Timeout waiting for ${eventType} event after ${timeoutMs}ms`));
|
|
37
|
+
} else {
|
|
38
|
+
setTimeout(check, 10); // Poll every 10ms for efficiency
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
check();
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Wait for a specific number of events of a given type
|
|
48
|
+
*
|
|
49
|
+
* @param threadManager - The thread manager to query
|
|
50
|
+
* @param threadId - Thread to check for events
|
|
51
|
+
* @param eventType - Type of event to wait for
|
|
52
|
+
* @param count - Number of events to wait for
|
|
53
|
+
* @param timeoutMs - Maximum time to wait (default 5000ms)
|
|
54
|
+
* @returns Promise resolving to all matching events once count is reached
|
|
55
|
+
*
|
|
56
|
+
* Example:
|
|
57
|
+
* // Wait for 2 AGENT_MESSAGE events (initial response + continuation)
|
|
58
|
+
* await waitForEventCount(threadManager, agentThreadId, 'AGENT_MESSAGE', 2);
|
|
59
|
+
*/
|
|
60
|
+
export function waitForEventCount(
|
|
61
|
+
threadManager: ThreadManager,
|
|
62
|
+
threadId: string,
|
|
63
|
+
eventType: LaceEventType,
|
|
64
|
+
count: number,
|
|
65
|
+
timeoutMs = 5000
|
|
66
|
+
): Promise<LaceEvent[]> {
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
const startTime = Date.now();
|
|
69
|
+
|
|
70
|
+
const check = () => {
|
|
71
|
+
const events = threadManager.getEvents(threadId);
|
|
72
|
+
const matchingEvents = events.filter((e) => e.type === eventType);
|
|
73
|
+
|
|
74
|
+
if (matchingEvents.length >= count) {
|
|
75
|
+
resolve(matchingEvents);
|
|
76
|
+
} else if (Date.now() - startTime > timeoutMs) {
|
|
77
|
+
reject(
|
|
78
|
+
new Error(
|
|
79
|
+
`Timeout waiting for ${count} ${eventType} events after ${timeoutMs}ms (got ${matchingEvents.length})`
|
|
80
|
+
)
|
|
81
|
+
);
|
|
82
|
+
} else {
|
|
83
|
+
setTimeout(check, 10);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
check();
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Wait for an event matching a custom predicate
|
|
93
|
+
* Useful when you need to check event data, not just type
|
|
94
|
+
*
|
|
95
|
+
* @param threadManager - The thread manager to query
|
|
96
|
+
* @param threadId - Thread to check for events
|
|
97
|
+
* @param predicate - Function that returns true when event matches
|
|
98
|
+
* @param description - Human-readable description for error messages
|
|
99
|
+
* @param timeoutMs - Maximum time to wait (default 5000ms)
|
|
100
|
+
* @returns Promise resolving to the first matching event
|
|
101
|
+
*
|
|
102
|
+
* Example:
|
|
103
|
+
* // Wait for TOOL_RESULT with specific ID
|
|
104
|
+
* await waitForEventMatch(
|
|
105
|
+
* threadManager,
|
|
106
|
+
* agentThreadId,
|
|
107
|
+
* (e) => e.type === 'TOOL_RESULT' && e.data.id === 'call_123',
|
|
108
|
+
* 'TOOL_RESULT with id=call_123'
|
|
109
|
+
* );
|
|
110
|
+
*/
|
|
111
|
+
export function waitForEventMatch(
|
|
112
|
+
threadManager: ThreadManager,
|
|
113
|
+
threadId: string,
|
|
114
|
+
predicate: (event: LaceEvent) => boolean,
|
|
115
|
+
description: string,
|
|
116
|
+
timeoutMs = 5000
|
|
117
|
+
): Promise<LaceEvent> {
|
|
118
|
+
return new Promise((resolve, reject) => {
|
|
119
|
+
const startTime = Date.now();
|
|
120
|
+
|
|
121
|
+
const check = () => {
|
|
122
|
+
const events = threadManager.getEvents(threadId);
|
|
123
|
+
const event = events.find(predicate);
|
|
124
|
+
|
|
125
|
+
if (event) {
|
|
126
|
+
resolve(event);
|
|
127
|
+
} else if (Date.now() - startTime > timeoutMs) {
|
|
128
|
+
reject(new Error(`Timeout waiting for ${description} after ${timeoutMs}ms`));
|
|
129
|
+
} else {
|
|
130
|
+
setTimeout(check, 10);
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
check();
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Usage example from actual debugging session:
|
|
139
|
+
//
|
|
140
|
+
// BEFORE (flaky):
|
|
141
|
+
// ---------------
|
|
142
|
+
// const messagePromise = agent.sendMessage('Execute tools');
|
|
143
|
+
// await new Promise(r => setTimeout(r, 300)); // Hope tools start in 300ms
|
|
144
|
+
// agent.abort();
|
|
145
|
+
// await messagePromise;
|
|
146
|
+
// await new Promise(r => setTimeout(r, 50)); // Hope results arrive in 50ms
|
|
147
|
+
// expect(toolResults.length).toBe(2); // Fails randomly
|
|
148
|
+
//
|
|
149
|
+
// AFTER (reliable):
|
|
150
|
+
// ----------------
|
|
151
|
+
// const messagePromise = agent.sendMessage('Execute tools');
|
|
152
|
+
// await waitForEventCount(threadManager, threadId, 'TOOL_CALL', 2); // Wait for tools to start
|
|
153
|
+
// agent.abort();
|
|
154
|
+
// await messagePromise;
|
|
155
|
+
// await waitForEventCount(threadManager, threadId, 'TOOL_RESULT', 2); // Wait for results
|
|
156
|
+
// expect(toolResults.length).toBe(2); // Always succeeds
|
|
157
|
+
//
|
|
158
|
+
// Result: 60% pass rate → 100%, 40% faster execution
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
database-development skill helps design efficient, scalable database schemas and manage database migrations effectively.
|
|
2
|
+
|
|
3
|
+
For code review, check that:
|
|
4
|
+
1. Database schema follows normalization principles
|
|
5
|
+
2. Proper indexes are created for query optimization
|
|
6
|
+
3. Foreign key constraints are defined
|
|
7
|
+
4. Migration files are reversible
|
|
8
|
+
5. Connection pooling is implemented
|
|
9
|
+
6. Query N+1 problems are avoided
|
|
10
|
+
7. Database transactions are used appropriately
|
|
11
|
+
8. Sensitive data is encrypted in database
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
-- Migration: [Description]
|
|
2
|
+
-- Created: [Date]
|
|
3
|
+
-- Author: [Author]
|
|
4
|
+
|
|
5
|
+
-- Enable transaction for safety
|
|
6
|
+
BEGIN;
|
|
7
|
+
|
|
8
|
+
-- Add new table
|
|
9
|
+
CREATE TABLE [table_name] (
|
|
10
|
+
id SERIAL PRIMARY KEY,
|
|
11
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
12
|
+
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
13
|
+
-- Add columns here
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
-- Add indexes if needed
|
|
17
|
+
CREATE INDEX [index_name] ON [table_name]([column_name]);
|
|
18
|
+
|
|
19
|
+
-- Add foreign key constraints
|
|
20
|
+
ALTER TABLE [table_name]
|
|
21
|
+
ADD CONSTRAINT [constraint_name]
|
|
22
|
+
FOREIGN KEY ([column_name])
|
|
23
|
+
REFERENCES [other_table]([column_name]);
|
|
24
|
+
|
|
25
|
+
-- Add columns to existing tables
|
|
26
|
+
ALTER TABLE [existing_table]
|
|
27
|
+
ADD COLUMN [column_name] [type] [constraints];
|
|
28
|
+
|
|
29
|
+
-- Update timestamp
|
|
30
|
+
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
|
31
|
+
RETURNS TRIGGER AS $$
|
|
32
|
+
BEGIN
|
|
33
|
+
NEW.updated_at = CURRENT_TIMESTAMP;
|
|
34
|
+
RETURN NEW;
|
|
35
|
+
END;
|
|
36
|
+
$$ language 'plpgsql';
|
|
37
|
+
|
|
38
|
+
CREATE TRIGGER update_[table_name]_updated_at
|
|
39
|
+
BEFORE UPDATE ON [table_name]
|
|
40
|
+
FOR EACH ROW
|
|
41
|
+
EXECUTE FUNCTION update_updated_at_column();
|
|
42
|
+
|
|
43
|
+
COMMIT;
|
|
44
|
+
|
|
45
|
+
-- Rollback script (keep for reference):
|
|
46
|
+
-- BEGIN;
|
|
47
|
+
-- DROP TABLE IF EXISTS [table_name];
|
|
48
|
+
-- ALTER TABLE [existing_table] DROP COLUMN [column_name];
|
|
49
|
+
-- COMMIT;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: defense-in-depth
|
|
3
|
+
description: Use when invalid data causes failures deep in execution, requiring validation at multiple system layers - validates at every layer data passes through to make bugs structurally impossible
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Defense-in-Depth Validation
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
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.
|
|
11
|
+
|
|
12
|
+
**Core principle:** Validate at EVERY layer data passes through. Make the bug structurally impossible.
|
|
13
|
+
|
|
14
|
+
## Why Multiple Layers
|
|
15
|
+
|
|
16
|
+
Single validation: "We fixed the bug"
|
|
17
|
+
Multiple layers: "We made the bug impossible"
|
|
18
|
+
|
|
19
|
+
Different layers catch different cases:
|
|
20
|
+
- Entry validation catches most bugs
|
|
21
|
+
- Business logic catches edge cases
|
|
22
|
+
- Environment guards prevent context-specific dangers
|
|
23
|
+
- Debug logging helps when other layers fail
|
|
24
|
+
|
|
25
|
+
## The Four Layers
|
|
26
|
+
|
|
27
|
+
### Layer 1: Entry Point Validation
|
|
28
|
+
**Purpose:** Reject obviously invalid input at API boundary
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
function createProject(name: string, workingDirectory: string) {
|
|
32
|
+
if (!workingDirectory || workingDirectory.trim() === '') {
|
|
33
|
+
throw new Error('workingDirectory cannot be empty');
|
|
34
|
+
}
|
|
35
|
+
if (!existsSync(workingDirectory)) {
|
|
36
|
+
throw new Error(`workingDirectory does not exist: ${workingDirectory}`);
|
|
37
|
+
}
|
|
38
|
+
if (!statSync(workingDirectory).isDirectory()) {
|
|
39
|
+
throw new Error(`workingDirectory is not a directory: ${workingDirectory}`);
|
|
40
|
+
}
|
|
41
|
+
// ... proceed
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Layer 2: Business Logic Validation
|
|
46
|
+
**Purpose:** Ensure data makes sense for this operation
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
function initializeWorkspace(projectDir: string, sessionId: string) {
|
|
50
|
+
if (!projectDir) {
|
|
51
|
+
throw new Error('projectDir required for workspace initialization');
|
|
52
|
+
}
|
|
53
|
+
// ... proceed
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Layer 3: Environment Guards
|
|
58
|
+
**Purpose:** Prevent dangerous operations in specific contexts
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
async function gitInit(directory: string) {
|
|
62
|
+
// In tests, refuse git init outside temp directories
|
|
63
|
+
if (process.env.NODE_ENV === 'test') {
|
|
64
|
+
const normalized = normalize(resolve(directory));
|
|
65
|
+
const tmpDir = normalize(resolve(tmpdir()));
|
|
66
|
+
|
|
67
|
+
if (!normalized.startsWith(tmpDir)) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
`Refusing git init outside temp dir during tests: ${directory}`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// ... proceed
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Layer 4: Debug Instrumentation
|
|
78
|
+
**Purpose:** Capture context for forensics
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
async function gitInit(directory: string) {
|
|
82
|
+
const stack = new Error().stack;
|
|
83
|
+
logger.debug('About to git init', {
|
|
84
|
+
directory,
|
|
85
|
+
cwd: process.cwd(),
|
|
86
|
+
stack,
|
|
87
|
+
});
|
|
88
|
+
// ... proceed
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Applying the Pattern
|
|
93
|
+
|
|
94
|
+
When you find a bug:
|
|
95
|
+
|
|
96
|
+
1. **Trace the data flow** - Where does bad value originate? Where used?
|
|
97
|
+
2. **Map all checkpoints** - List every point data passes through
|
|
98
|
+
3. **Add validation at each layer** - Entry, business, environment, debug
|
|
99
|
+
4. **Test each layer** - Try to bypass layer 1, verify layer 2 catches it
|
|
100
|
+
|
|
101
|
+
## Example from Session
|
|
102
|
+
|
|
103
|
+
Bug: Empty `projectDir` caused `git init` in source code
|
|
104
|
+
|
|
105
|
+
**Data flow:**
|
|
106
|
+
1. Test setup → empty string
|
|
107
|
+
2. `Project.create(name, '')`
|
|
108
|
+
3. `WorkspaceManager.createWorkspace('')`
|
|
109
|
+
4. `git init` runs in `process.cwd()`
|
|
110
|
+
|
|
111
|
+
**Four layers added:**
|
|
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
|
+
- Different code paths bypassed entry validation
|
|
123
|
+
- Mocks bypassed business logic checks
|
|
124
|
+
- Edge cases on different platforms needed environment guards
|
|
125
|
+
- Debug logging identified structural misuse
|
|
126
|
+
|
|
127
|
+
**Don't stop at one validation point.** Add checks at every layer.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
deployment skill helps automate application deployment through containerization, CI/CD pipelines, and monitoring setup.
|
|
2
|
+
|
|
3
|
+
For code review, check that:
|
|
4
|
+
1. Dockerfile follows best practices
|
|
5
|
+
2. Multi-stage builds are used to reduce image size
|
|
6
|
+
3. Health checks are implemented
|
|
7
|
+
4. Environment variables are properly managed
|
|
8
|
+
5. CI/CD pipeline tests all deployments
|
|
9
|
+
6. Monitoring and logging are configured
|
|
10
|
+
7. Rollback strategies are in place
|
|
11
|
+
8. Zero-downtime deployment is considered
|