liteagents 2.9.0 → 2.11.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/CHANGELOG.md +43 -0
- package/README.md +27 -33
- package/installer/cli.js +6 -2
- package/package.json +3 -3
- package/packages/ampcode/AGENT.md +11 -16
- package/packages/ampcode/agents/code-developer.md +11 -12
- package/packages/ampcode/agents/quality-assurance.md +1 -1
- package/packages/{droid/commands/systematic-debugging.md → ampcode/commands/debug-method.md} +9 -9
- package/packages/ampcode/commands/diff-review.md +78 -0
- package/packages/ampcode/commands/friction/friction.js +28 -6
- package/packages/ampcode/commands/optimize.md +45 -4
- package/packages/ampcode/commands/refactor.md +33 -1
- package/packages/ampcode/commands/release.md +88 -0
- package/packages/ampcode/commands/remember.md +34 -3
- package/packages/ampcode/commands/security.md +28 -1
- package/packages/ampcode/commands/stash.md +7 -0
- package/packages/{droid/commands/test-driven-development.md → ampcode/commands/tdd-flow.md} +2 -2
- package/packages/ampcode/commands/test-generate.md +64 -15
- package/packages/{opencode/command/testing-anti-patterns.md → ampcode/commands/test-traps.md} +77 -3
- package/packages/{droid/commands/root-cause-tracing.md → ampcode/commands/trace-back.md} +3 -3
- package/packages/ampcode/commands/{verification-before-completion.md → verify-done.md} +3 -3
- package/packages/claude/CLAUDE.md +10 -15
- package/packages/claude/agents/code-developer.md +11 -12
- package/packages/claude/agents/quality-assurance.md +1 -1
- package/packages/claude/commands/diff-review.md +78 -0
- package/packages/claude/commands/friction/friction.js +28 -6
- package/packages/claude/commands/optimize.md +45 -4
- package/packages/claude/commands/refactor.md +33 -1
- package/packages/claude/commands/release.md +88 -0
- package/packages/claude/commands/remember.md +34 -3
- package/packages/claude/commands/security.md +28 -1
- package/packages/claude/commands/stash.md +7 -0
- package/packages/claude/commands/test-generate.md +64 -15
- package/packages/claude/plugins/live-canvas-marketplace/plugins/live-canvas-channel/package-lock.json +3 -3
- package/packages/claude/skills/{systematic-debugging → debug-method}/CREATION-LOG.md +1 -1
- package/packages/claude/skills/{systematic-debugging → debug-method}/SKILL.md +9 -9
- package/packages/claude/skills/{systematic-debugging → debug-method}/test-academic.md +1 -1
- package/packages/claude/skills/{systematic-debugging → debug-method}/test-pressure-1.md +1 -1
- package/packages/claude/skills/{systematic-debugging → debug-method}/test-pressure-2.md +1 -1
- package/packages/claude/skills/{systematic-debugging → debug-method}/test-pressure-3.md +1 -1
- package/packages/claude/skills/{test-driven-development → tdd-flow}/SKILL.md +3 -3
- package/packages/claude/skills/{testing-anti-patterns → test-traps}/SKILL.md +77 -3
- package/packages/claude/skills/{root-cause-tracing → trace-back}/SKILL.md +3 -3
- package/packages/claude/skills/{verification-before-completion → verify-done}/SKILL.md +3 -3
- package/packages/droid/AGENTS.md +9 -14
- package/packages/{opencode/command/systematic-debugging.md → droid/commands/debug-method.md} +9 -9
- package/packages/droid/commands/diff-review.md +78 -0
- package/packages/droid/commands/friction/friction.js +28 -6
- package/packages/droid/commands/optimize.md +45 -4
- package/packages/droid/commands/refactor.md +33 -1
- package/packages/droid/commands/release.md +88 -0
- package/packages/droid/commands/remember.md +34 -3
- package/packages/droid/commands/security.md +28 -1
- package/packages/droid/commands/stash.md +7 -0
- package/packages/{opencode/command/test-driven-development.md → droid/commands/tdd-flow.md} +2 -2
- package/packages/droid/commands/test-generate.md +64 -15
- package/packages/droid/commands/{testing-anti-patterns.md → test-traps.md} +77 -3
- package/packages/{opencode/command/root-cause-tracing.md → droid/commands/trace-back.md} +3 -3
- package/packages/droid/commands/{verification-before-completion.md → verify-done.md} +3 -3
- package/packages/droid/droids/code-developer.md +11 -12
- package/packages/droid/droids/quality-assurance.md +1 -1
- package/packages/opencode/AGENTS.md +9 -14
- package/packages/opencode/agent/code-developer.md +11 -12
- package/packages/opencode/agent/quality-assurance.md +1 -1
- package/packages/{ampcode/commands/systematic-debugging.md → opencode/command/debug-method.md} +9 -9
- package/packages/opencode/command/diff-review.md +78 -0
- package/packages/opencode/command/friction/friction.js +28 -6
- package/packages/opencode/command/optimize.md +45 -4
- package/packages/opencode/command/refactor.md +33 -1
- package/packages/opencode/command/release.md +88 -0
- package/packages/opencode/command/remember.md +34 -3
- package/packages/opencode/command/security.md +28 -1
- package/packages/opencode/command/stash.md +7 -0
- package/packages/{ampcode/commands/test-driven-development.md → opencode/command/tdd-flow.md} +2 -2
- package/packages/opencode/command/test-generate.md +64 -15
- package/packages/{ampcode/commands/testing-anti-patterns.md → opencode/command/test-traps.md} +77 -3
- package/packages/{ampcode/commands/root-cause-tracing.md → opencode/command/trace-back.md} +3 -3
- package/packages/opencode/command/{verification-before-completion.md → verify-done.md} +3 -3
- package/packages/opencode/opencode.jsonc +16 -36
- package/packages/subagentic-manual.md +56 -51
- package/packages/ampcode/commands/code-review.md +0 -107
- package/packages/ampcode/commands/condition-based-waiting.md +0 -122
- package/packages/ampcode/commands/debug.md +0 -20
- package/packages/ampcode/commands/explain.md +0 -18
- package/packages/ampcode/commands/friction.md +0 -139
- package/packages/ampcode/commands/git-commit.md +0 -14
- package/packages/ampcode/commands/review.md +0 -18
- package/packages/claude/commands/debug.md +0 -20
- package/packages/claude/commands/explain.md +0 -18
- package/packages/claude/commands/friction.md +0 -139
- package/packages/claude/commands/git-commit.md +0 -14
- package/packages/claude/commands/review.md +0 -18
- package/packages/claude/skills/code-review/SKILL.md +0 -107
- package/packages/claude/skills/code-review/code-reviewer.md +0 -146
- package/packages/claude/skills/condition-based-waiting/SKILL.md +0 -122
- package/packages/droid/commands/code-review.md +0 -107
- package/packages/droid/commands/condition-based-waiting.md +0 -122
- package/packages/droid/commands/debug.md +0 -20
- package/packages/droid/commands/explain.md +0 -18
- package/packages/droid/commands/friction.md +0 -139
- package/packages/droid/commands/git-commit.md +0 -14
- package/packages/droid/commands/review.md +0 -18
- package/packages/opencode/command/code-review.md +0 -107
- package/packages/opencode/command/condition-based-waiting.md +0 -122
- package/packages/opencode/command/debug.md +0 -20
- package/packages/opencode/command/explain.md +0 -18
- package/packages/opencode/command/friction.md +0 -139
- package/packages/opencode/command/git-commit.md +0 -14
- package/packages/opencode/command/review.md +0 -18
- /package/packages/ampcode/commands/{condition-based-waiting → test-traps}/example.ts +0 -0
- /package/packages/ampcode/commands/{root-cause-tracing → trace-back}/find-polluter.sh +0 -0
- /package/packages/claude/skills/{condition-based-waiting → test-traps}/example.ts +0 -0
- /package/packages/claude/skills/{root-cause-tracing → trace-back}/find-polluter.sh +0 -0
- /package/packages/droid/commands/{condition-based-waiting → test-traps}/example.ts +0 -0
- /package/packages/droid/commands/{root-cause-tracing → trace-back}/find-polluter.sh +0 -0
- /package/packages/opencode/command/{condition-based-waiting → test-traps}/example.ts +0 -0
- /package/packages/opencode/command/{root-cause-tracing → trace-back}/find-polluter.sh +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: tdd-flow
|
|
3
3
|
description: Use when implementing any feature or bugfix, before writing implementation code - write the test first, watch it fail, write minimal code to pass; ensures tests actually verify behavior by requiring failure first
|
|
4
|
-
usage: /
|
|
4
|
+
usage: /tdd-flow <feature-or-behavior-to-test>
|
|
5
5
|
auto_trigger: true
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# TDD Flow
|
|
9
9
|
|
|
10
10
|
## Auto-Trigger
|
|
11
11
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: test-traps
|
|
3
3
|
description: Use when writing or changing tests, adding mocks, or tempted to add test-only methods to production code - prevents testing mock behavior, production pollution with test-only methods, and mocking without understanding dependencies
|
|
4
|
-
usage: /
|
|
4
|
+
usage: /test-traps <testing-scenario>
|
|
5
5
|
auto_trigger: true
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# Test Traps
|
|
9
9
|
|
|
10
10
|
## Overview
|
|
11
11
|
|
|
@@ -253,6 +253,79 @@ TDD cycle:
|
|
|
253
253
|
4. THEN claim complete
|
|
254
254
|
```
|
|
255
255
|
|
|
256
|
+
## Anti-Pattern 6: Timeout-Based Waiting
|
|
257
|
+
|
|
258
|
+
**The violation:**
|
|
259
|
+
```typescript
|
|
260
|
+
// Wait an arbitrary amount of time, then check
|
|
261
|
+
await new Promise(r => setTimeout(r, 50));
|
|
262
|
+
const result = getResult();
|
|
263
|
+
expect(result).toBeDefined();
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
```python
|
|
267
|
+
time.sleep(0.5)
|
|
268
|
+
assert get_result() is not None
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Why this is wrong:**
|
|
272
|
+
- Passes on fast machines, fails in CI under load (or vice versa).
|
|
273
|
+
- Either too short (flaky) or too long (slow suite) — every value is wrong somewhere.
|
|
274
|
+
- Hides the actual condition the test cares about.
|
|
275
|
+
- A real bug in the async machinery looks identical to a "too-short sleep."
|
|
276
|
+
|
|
277
|
+
**The fix — poll for the actual condition:**
|
|
278
|
+
```typescript
|
|
279
|
+
await waitFor(() => getResult() !== undefined);
|
|
280
|
+
const result = getResult();
|
|
281
|
+
expect(result).toBeDefined();
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
| Scenario | Pattern |
|
|
285
|
+
|----------|---------|
|
|
286
|
+
| Wait for event | `waitFor(() => events.find(e => e.type === 'DONE'))` |
|
|
287
|
+
| Wait for state | `waitFor(() => machine.state === 'ready')` |
|
|
288
|
+
| Wait for count | `waitFor(() => items.length >= 5)` |
|
|
289
|
+
| Wait for file | `waitFor(() => fs.existsSync(path))` |
|
|
290
|
+
| Complex condition | `waitFor(() => obj.ready && obj.value > 10)` |
|
|
291
|
+
|
|
292
|
+
Minimal generic poller:
|
|
293
|
+
```typescript
|
|
294
|
+
async function waitFor<T>(
|
|
295
|
+
condition: () => T | undefined | null | false,
|
|
296
|
+
description = 'condition',
|
|
297
|
+
timeoutMs = 5000
|
|
298
|
+
): Promise<T> {
|
|
299
|
+
const start = Date.now();
|
|
300
|
+
while (true) {
|
|
301
|
+
const result = condition();
|
|
302
|
+
if (result) return result;
|
|
303
|
+
if (Date.now() - start > timeoutMs) {
|
|
304
|
+
throw new Error(`Timeout waiting for ${description} after ${timeoutMs}ms`);
|
|
305
|
+
}
|
|
306
|
+
await new Promise(r => setTimeout(r, 10));
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
See `example.ts` for domain-specific helpers (`waitForEvent`, `waitForEventCount`, `waitForEventMatch`) drawn from a real debugging session.
|
|
312
|
+
|
|
313
|
+
**Polling pitfalls:**
|
|
314
|
+
- **Polling too fast** (`setTimeout(check, 1)`) wastes CPU. **Fix:** poll every ~10ms.
|
|
315
|
+
- **No timeout** means a never-met condition hangs the suite forever. **Fix:** always include a timeout with a descriptive error.
|
|
316
|
+
- **Stale data** — if you read state once before the loop, you'll never see updates. **Fix:** call the getter *inside* the loop.
|
|
317
|
+
|
|
318
|
+
**When an arbitrary timeout IS correct:**
|
|
319
|
+
```typescript
|
|
320
|
+
// Tool ticks every 100ms; observe 2 ticks of partial output.
|
|
321
|
+
await waitForEvent(manager, 'TOOL_STARTED'); // condition first
|
|
322
|
+
await new Promise(r => setTimeout(r, 200)); // then a documented, calculated wait
|
|
323
|
+
// 200ms = 2 ticks at the documented 100ms cadence
|
|
324
|
+
```
|
|
325
|
+
Requirements: (1) wait for the triggering condition first, (2) the delay is based on a *known* interval (not a guess), (3) a comment explains why a sleep is correct here.
|
|
326
|
+
|
|
327
|
+
**Real-world impact** (debugging session, 2025-10-03): 15 flaky tests across 3 files, pass rate 60% → 100%, suite 40% faster, race conditions gone.
|
|
328
|
+
|
|
256
329
|
## When Mocks Become Too Complex
|
|
257
330
|
|
|
258
331
|
**Warning signs:**
|
|
@@ -284,6 +357,7 @@ TDD cycle:
|
|
|
284
357
|
| Mock without understanding | Understand dependencies first, mock minimally |
|
|
285
358
|
| Incomplete mocks | Mirror real API completely |
|
|
286
359
|
| Tests as afterthought | TDD - tests first |
|
|
360
|
+
| Timeout-based waiting | Poll for the actual condition with `waitFor()` |
|
|
287
361
|
| Over-complex mocks | Consider integration tests |
|
|
288
362
|
|
|
289
363
|
## Red Flags
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: trace-back
|
|
3
3
|
description: Use when errors occur deep in execution and you need to trace back to find the original trigger - systematically traces bugs backward through call stack, adding instrumentation when needed, to identify source of invalid data or incorrect behavior
|
|
4
|
-
usage: /
|
|
4
|
+
usage: /trace-back <issue-description>
|
|
5
5
|
auto_trigger: false
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# Trace Back
|
|
9
9
|
|
|
10
10
|
## Overview
|
|
11
11
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: verify-done
|
|
3
3
|
description: Use when about to claim work is complete, fixed, or passing, before committing or creating PRs - requires running verification commands and confirming output before making any success claims; evidence before assertions always
|
|
4
|
-
usage: /
|
|
4
|
+
usage: /verify-done <work-to-verify>
|
|
5
5
|
auto_trigger: true
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# Verify Done
|
|
9
9
|
|
|
10
10
|
## Auto-Trigger
|
|
11
11
|
|
package/packages/droid/AGENTS.md
CHANGED
|
@@ -22,33 +22,28 @@ These subagents are available when using Claude Code CLI. Droid can reference th
|
|
|
22
22
|
| system-architect | Architect | Use for system design, architecture documents, technology selection, API design, and infrastructure planning |
|
|
23
23
|
| ui-designer | UX Expert | Use for UI/UX design, wireframes, prototypes, front-end specifications, and user experience optimization |
|
|
24
24
|
|
|
25
|
-
## Droid Commands (
|
|
25
|
+
## Droid Commands (18 total)
|
|
26
26
|
|
|
27
27
|
| ID | Description | Usage | Auto |
|
|
28
28
|
|---|---|---|---|
|
|
29
29
|
| brainstorming | Refines rough ideas into fully-formed designs through collaborative questioning | /brainstorming <session-type> <topic> | false |
|
|
30
|
-
| code-review | Reviews implementation against plan or requirements before proceeding | /code-review <review-scope> <focus-areas> | false |
|
|
31
|
-
| condition-based-waiting | Replaces arbitrary timeouts with condition polling to wait for actual state changes | /condition-based-waiting <condition-type> <timeout-specs> | false |
|
|
32
|
-
| debug | Debug an issue systematically using structured investigation techniques | /debug <issue-description> | - |
|
|
33
30
|
| docs-builder | Create comprehensive project documentation with structured /docs hierarchy | /docs-builder | false |
|
|
34
|
-
| explain | Explain code for someone new to the codebase | /explain <code-section> | - |
|
|
35
|
-
| friction | Analyze session logs for failure patterns and behavioral signals | /friction <sessions-path> | - |
|
|
36
|
-
| git-commit | Analyze changes and create intelligent git commits | /git-commit | - |
|
|
37
31
|
| live-canvas | Design UI variations and collect click-to-annotate feedback from the browser (batch mode only on Droid) | /live-canvas | false |
|
|
38
32
|
| optimize | Analyze and optimize performance issues | /optimize <target-area> | - |
|
|
39
33
|
| refactor | Refactor code while maintaining behavior and tests | /refactor <code-section> | - |
|
|
40
34
|
| remember | Consolidate stashes + friction into project memory | /remember | - |
|
|
41
|
-
| review | Comprehensive code review including quality, tests, and architecture | /review | - |
|
|
42
|
-
|
|
|
35
|
+
| diff-review | Comprehensive code review including quality, tests, and architecture | /diff-review | - |
|
|
36
|
+
| trace-back | Systematically traces bugs backward through call stack to identify source | /trace-back <issue-description> | false |
|
|
43
37
|
| security | Security vulnerability scan and analysis | /security | - |
|
|
44
38
|
| ship | Pre-deployment verification checklist | /ship | - |
|
|
39
|
+
| release | Deliver a feature end-to-end: verify, docs, merge, tag (publish stays manual) | /release [branch] | - |
|
|
45
40
|
| skill-creator | Guide for creating effective skills and extending Claude capabilities | /skill-creator <skill-type> <skill-description> | false |
|
|
46
41
|
| stash | Save session context for compaction recovery or handoffs | /stash ["optional-name"] | - |
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
| test-generate | Generate
|
|
50
|
-
|
|
|
51
|
-
|
|
|
42
|
+
| debug-method | Four-phase debugging framework - investigate root cause before any fixes | /debug-method <bug-or-error-description> | false |
|
|
43
|
+
| tdd-flow | Write test first, watch it fail, write minimal code to pass | /tdd-flow <feature-or-behavior-to-test> | true |
|
|
44
|
+
| test-generate | Generate tests, run them, verify each one actually exercises the code | /test-generate <file> | - |
|
|
45
|
+
| test-traps | Prevents testing mock behavior and production pollution with test-only methods | /test-traps <testing-scenario> | true |
|
|
46
|
+
| verify-done | Requires running verification commands before making any success claims | /verify-done <work-to-verify> | true |
|
|
52
47
|
|
|
53
48
|
All resources are auto-discovered from frontmatter in their respective directories:
|
|
54
49
|
- **Agents**: `./droids/*.md`
|
package/packages/{opencode/command/systematic-debugging.md → droid/commands/debug-method.md}
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: debug-method
|
|
3
3
|
description: Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes - four-phase framework (root cause investigation, pattern analysis, hypothesis testing, implementation) that ensures understanding before attempting solutions
|
|
4
|
-
usage: /
|
|
4
|
+
usage: /debug-method <bug-or-error-description>
|
|
5
5
|
auto_trigger: false
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# Debug Method
|
|
9
9
|
|
|
10
10
|
## Overview
|
|
11
11
|
|
|
@@ -113,7 +113,7 @@ You MUST complete each phase before proceeding to the next.
|
|
|
113
113
|
|
|
114
114
|
**WHEN error is deep in call stack:**
|
|
115
115
|
|
|
116
|
-
**REQUIRED SUB-SKILL:** Use
|
|
116
|
+
**REQUIRED SUB-SKILL:** Use trace-back for backward tracing technique
|
|
117
117
|
|
|
118
118
|
**Quick version:**
|
|
119
119
|
- Where does bad value originate?
|
|
@@ -178,7 +178,7 @@ You MUST complete each phase before proceeding to the next.
|
|
|
178
178
|
- Automated test if possible
|
|
179
179
|
- One-off test script if no framework
|
|
180
180
|
- MUST have before fixing
|
|
181
|
-
- **REQUIRED SUB-SKILL:** Use
|
|
181
|
+
- **REQUIRED SUB-SKILL:** Use tdd-flow for writing proper failing tests
|
|
182
182
|
|
|
183
183
|
2. **Implement Single Fix**
|
|
184
184
|
- Address the root cause identified
|
|
@@ -280,13 +280,13 @@ If systematic investigation reveals issue is truly environmental, timing-depende
|
|
|
280
280
|
## Integration with Other Skills
|
|
281
281
|
|
|
282
282
|
**This skill requires using:**
|
|
283
|
-
- **
|
|
284
|
-
- **
|
|
283
|
+
- **trace-back** - REQUIRED when error is deep in call stack (see Phase 1, Step 5)
|
|
284
|
+
- **tdd-flow** - REQUIRED for creating failing test case (see Phase 4, Step 1)
|
|
285
285
|
|
|
286
286
|
**Complementary skills:**
|
|
287
287
|
- **defense-in-depth** - Add validation at multiple layers after finding root cause
|
|
288
|
-
- **
|
|
289
|
-
- **
|
|
288
|
+
- **test-traps** (Anti-Pattern 6) - Replace arbitrary timeouts identified in Phase 2
|
|
289
|
+
- **verify-done** - Verify fix worked before claiming success
|
|
290
290
|
|
|
291
291
|
## Real-World Impact
|
|
292
292
|
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: diff-review
|
|
3
|
+
description: Review diff [file, branch, or range]
|
|
4
|
+
usage: /diff-review
|
|
5
|
+
argument-hint: [file, branch (e.g. main), range (main..HEAD), or empty]
|
|
6
|
+
allowed-tools: Read, Edit, Grep, Glob, Bash(git diff *), Bash(git log *), Bash(git show *), Bash(git status *), Bash(git grep *), Bash(git rev-parse *), Bash(git merge-base *), Bash(rg *)
|
|
7
|
+
---
|
|
8
|
+
Review $ARGUMENTS. Interpret in this order:
|
|
9
|
+
1. **Empty** → staged diff (`git diff --staged`); if empty, working-tree diff
|
|
10
|
+
(`git diff`).
|
|
11
|
+
2. **A range** like `main..HEAD` or `origin/main...HEAD` → `git diff <range>`.
|
|
12
|
+
3. **A single ref** (branch / tag / SHA — confirm with `git rev-parse
|
|
13
|
+
--verify`) → diff that ref's merge-base against `HEAD` (i.e. everything on
|
|
14
|
+
the current branch since it diverged: `git diff $(git merge-base <ref>
|
|
15
|
+
HEAD)..HEAD`). This is the common "review my branch before merging" path.
|
|
16
|
+
4. **A file or directory path** → that target.
|
|
17
|
+
5. Otherwise → ask.
|
|
18
|
+
|
|
19
|
+
The diff is the subject; widen to surrounding code only as needed to judge a
|
|
20
|
+
hunk. For multi-commit ranges, also skim `git log <range>` to understand
|
|
21
|
+
intent before judging.
|
|
22
|
+
|
|
23
|
+
## Check For
|
|
24
|
+
- **Bugs needing a fix.** Logic errors, off-by-one, null/undefined paths,
|
|
25
|
+
races, wrong defaults, broken edge cases. Concrete failure modes only — not
|
|
26
|
+
vibes.
|
|
27
|
+
- **Dead code.** Unreferenced functions / vars / imports / params, unreachable
|
|
28
|
+
branches, commented-out blocks, legacy paths the diff just obsoleted.
|
|
29
|
+
`git grep` the symbol before flagging — easy to be wrong.
|
|
30
|
+
- **Loose ends.** TODO / FIXME / XXX added by this diff, half-finished
|
|
31
|
+
branches, silently swallowed errors, stub bodies, mocked-out paths,
|
|
32
|
+
"temporary" names, abandoned feature flags.
|
|
33
|
+
- **Correctness.** Edge cases, error handling, type / contract violations,
|
|
34
|
+
broken invariants.
|
|
35
|
+
- **Security.** OWASP Top 10, auth, data exposure. (`/security` for depth.)
|
|
36
|
+
- **Performance.** N+1, blocking calls in hot paths, unbounded loops, indexes
|
|
37
|
+
the diff actually touches.
|
|
38
|
+
- **Maintainability.** Complexity, naming, duplication — only when material.
|
|
39
|
+
|
|
40
|
+
## Output Format
|
|
41
|
+
### 🚨 Critical (blocks merge)
|
|
42
|
+
### ⚠️ Warnings (should fix)
|
|
43
|
+
### 💡 Suggestions (nice to have)
|
|
44
|
+
|
|
45
|
+
Each finding: **Location** (`file:line`), **What's wrong**, **Why it matters**,
|
|
46
|
+
**Concrete fix** — not "consider improving".
|
|
47
|
+
|
|
48
|
+
## After the review — verify, then fix
|
|
49
|
+
|
|
50
|
+
Findings are claims, not facts. Validate before acting; validate again after.
|
|
51
|
+
|
|
52
|
+
**Verify each claim.** Re-read the cited `file:line` in context. For
|
|
53
|
+
dead-code or unused-symbol claims, `git grep` the name across the repo before
|
|
54
|
+
trusting it. Mark each **confirmed**, **false positive** (with reason), or
|
|
55
|
+
**uncertain**.
|
|
56
|
+
|
|
57
|
+
**Fix what's confirmed and unambiguous** — minimal shape, one obvious way, no
|
|
58
|
+
change to a public API / response / caller contract. Apply directly. After
|
|
59
|
+
each edit, re-read the changed region and confirm it does what you intended
|
|
60
|
+
without breaking nearby logic. A fix isn't done until you've grounded it the
|
|
61
|
+
same way you grounded the claim.
|
|
62
|
+
|
|
63
|
+
**Stop and ask** when any of these hold (HITL gates — not all the time, only
|
|
64
|
+
here):
|
|
65
|
+
- the finding is **uncertain** after grounding,
|
|
66
|
+
- the fix has **multiple reasonable shapes** (e.g. delete-vs-keep-behind-flag,
|
|
67
|
+
extract-vs-inline, patch-vs-rewrite) — present options with tradeoffs, not a
|
|
68
|
+
chosen path,
|
|
69
|
+
- it **affects downstream** (signatures, response shape, schema, any caller
|
|
70
|
+
contract) or removes a public/exported symbol, or
|
|
71
|
+
- the "dead code" looks intentionally kept (stub for upcoming work, framework
|
|
72
|
+
hook, documented extension point) — confirm before deleting.
|
|
73
|
+
|
|
74
|
+
Final report: **confirmed-and-fixed** · **confirmed-but-asking** (why +
|
|
75
|
+
options) · **false-positive** (why) · **uncertain** (what's needed to decide).
|
|
76
|
+
|
|
77
|
+
End with a one-line verdict: **Ready to merge? Yes / No / With fixes** — and
|
|
78
|
+
the reason in a sentence.
|
|
@@ -81,6 +81,24 @@ function loadConfig() {
|
|
|
81
81
|
return CONFIG;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Parse newline-delimited JSON, skipping (and warning about) malformed lines
|
|
86
|
+
* instead of crashing the whole run on one bad record.
|
|
87
|
+
*/
|
|
88
|
+
function parseJsonl(raw, source) {
|
|
89
|
+
const records = [];
|
|
90
|
+
const lines = raw.split('\n');
|
|
91
|
+
for (let i = 0; i < lines.length; i++) {
|
|
92
|
+
if (!lines[i].trim()) continue;
|
|
93
|
+
try {
|
|
94
|
+
records.push(JSON.parse(lines[i]));
|
|
95
|
+
} catch (e) {
|
|
96
|
+
console.error(`Warning: skipping malformed JSONL line ${i + 1}${source ? ` in ${source}` : ''}: ${e.message}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return records;
|
|
100
|
+
}
|
|
101
|
+
|
|
84
102
|
function parseISODate(s) {
|
|
85
103
|
if (!s) return null;
|
|
86
104
|
try {
|
|
@@ -235,9 +253,7 @@ function extractSignals(sessionFile) {
|
|
|
235
253
|
const metadata = {};
|
|
236
254
|
|
|
237
255
|
const raw = fs.readFileSync(sessionFile, 'utf-8');
|
|
238
|
-
const events = raw
|
|
239
|
-
.filter(line => line.trim())
|
|
240
|
-
.map(line => JSON.parse(line));
|
|
256
|
+
const events = parseJsonl(raw, sessionFile);
|
|
241
257
|
|
|
242
258
|
let turnCount = 0;
|
|
243
259
|
const userMessages = [];
|
|
@@ -1695,7 +1711,7 @@ function extractContextWindow(sessionFile, anchorTs, windowSize) {
|
|
|
1695
1711
|
windowSize = windowSize || 5;
|
|
1696
1712
|
|
|
1697
1713
|
const raw = fs.readFileSync(sessionFile, 'utf-8');
|
|
1698
|
-
const events = raw
|
|
1714
|
+
const events = parseJsonl(raw, sessionFile);
|
|
1699
1715
|
|
|
1700
1716
|
const turns = [];
|
|
1701
1717
|
for (const event of events) {
|
|
@@ -2180,14 +2196,20 @@ function extractMain(sessionsDir) {
|
|
|
2180
2196
|
return 1;
|
|
2181
2197
|
}
|
|
2182
2198
|
|
|
2183
|
-
|
|
2199
|
+
let analyses;
|
|
2200
|
+
try {
|
|
2201
|
+
analyses = JSON.parse(fs.readFileSync(analysisFile, 'utf-8'));
|
|
2202
|
+
} catch (e) {
|
|
2203
|
+
console.log(`Error: ${analysisFile} is not valid JSON (${e.message}). Re-run friction analysis.`);
|
|
2204
|
+
return 1;
|
|
2205
|
+
}
|
|
2184
2206
|
|
|
2185
2207
|
// Load raw signals
|
|
2186
2208
|
const rawFile = '.factory/friction/friction_raw.jsonl';
|
|
2187
2209
|
let signals = [];
|
|
2188
2210
|
if (fs.existsSync(rawFile)) {
|
|
2189
2211
|
const rawContent = fs.readFileSync(rawFile, 'utf-8');
|
|
2190
|
-
signals = rawContent
|
|
2212
|
+
signals = parseJsonl(rawContent, rawFile);
|
|
2191
2213
|
}
|
|
2192
2214
|
|
|
2193
2215
|
// NEW: no per-session BAD verdict. Seed from ALL sessions; the observed-only
|
|
@@ -3,6 +3,7 @@ name: optimize
|
|
|
3
3
|
description: Optimize performance [target]
|
|
4
4
|
usage: /optimize <target-area>
|
|
5
5
|
argument-hint: [file-or-function]
|
|
6
|
+
allowed-tools: Read, Edit, Grep, Glob, Bash(git diff *), Bash(git log *), Bash(git grep *), Bash(rg *)
|
|
6
7
|
---
|
|
7
8
|
Analyze $ARGUMENTS for performance.
|
|
8
9
|
|
|
@@ -14,7 +15,47 @@ Analyze $ARGUMENTS for performance.
|
|
|
14
15
|
- Unnecessary allocations
|
|
15
16
|
|
|
16
17
|
## Output
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
|
|
18
|
+
Per bottleneck:
|
|
19
|
+
- **Location** (`file:line`)
|
|
20
|
+
- **Cost** — what's slow and by how much. Concrete ("N+1 over ~1k rows on
|
|
21
|
+
every page load"), not vague ("could be faster").
|
|
22
|
+
- **Optimization** — specific change.
|
|
23
|
+
- **Expected improvement** — order-of-magnitude estimate.
|
|
24
|
+
- **Trade-offs** — readability / memory / consistency cost.
|
|
25
|
+
|
|
26
|
+
## After the analysis — verify, then fix
|
|
27
|
+
|
|
28
|
+
Performance claims are easy to invent. Validate before acting.
|
|
29
|
+
|
|
30
|
+
**Verify each bottleneck.** Re-read the cited `file:line` in context.
|
|
31
|
+
Confirm the path is **actually hot** — look for at least one of:
|
|
32
|
+
- a profile / benchmark / log line showing call frequency or duration,
|
|
33
|
+
- the path sits on an obvious hot loop / per-request handler with real
|
|
34
|
+
volume,
|
|
35
|
+
- the user provided evidence in the request.
|
|
36
|
+
|
|
37
|
+
Without one of those, the claim is **uncertain — don't optimize on
|
|
38
|
+
speculation.** Mark each finding **confirmed**, **false positive** (with
|
|
39
|
+
reason), or **uncertain (needs profiling data)**.
|
|
40
|
+
|
|
41
|
+
**Fix what's confirmed and unambiguous** — minimal change, one obvious
|
|
42
|
+
shape, **no behavior change**, no API change. Apply directly. After
|
|
43
|
+
each edit, re-read the changed region and confirm it still computes the
|
|
44
|
+
same answer (perf optimizations that quietly change semantics are the
|
|
45
|
+
worst kind).
|
|
46
|
+
|
|
47
|
+
**Stop and ask** when (HITL gates — not all the time, only here):
|
|
48
|
+
- the bottleneck is **uncertain** after grounding (no profile / log and
|
|
49
|
+
not obviously hot),
|
|
50
|
+
- the fix has **multiple reasonable shapes** (cache vs precompute vs
|
|
51
|
+
batch vs paginate vs index) — present options with tradeoffs, not a
|
|
52
|
+
chosen path,
|
|
53
|
+
- it changes **public API / response shape / DB schema / caller contract**,
|
|
54
|
+
- it trades **correctness for speed** (lossy approximation, weaker
|
|
55
|
+
consistency, eventual-vs-strict) — even when "obviously" faster, or
|
|
56
|
+
- it touches **concurrency primitives** (locks, atomics, ordering) —
|
|
57
|
+
easy to introduce races.
|
|
58
|
+
|
|
59
|
+
Final report: **confirmed-and-fixed** · **confirmed-but-asking** (why +
|
|
60
|
+
options) · **false-positive** (why) · **uncertain** (what profiling /
|
|
61
|
+
data is needed to decide).
|
|
@@ -3,6 +3,7 @@ name: refactor
|
|
|
3
3
|
description: Refactor [code]
|
|
4
4
|
usage: /refactor <code-section>
|
|
5
5
|
argument-hint: [file-or-function]
|
|
6
|
+
allowed-tools: Read, Edit, Grep, Glob, Bash(npm test *), Bash(npx jest *), Bash(npx vitest *), Bash(pnpm test *), Bash(yarn test *), Bash(pytest *), Bash(python *), Bash(go test *), Bash(cargo test *), Bash(make test *), Bash(git diff *)
|
|
6
7
|
---
|
|
7
8
|
Refactor $ARGUMENTS.
|
|
8
9
|
|
|
@@ -14,8 +15,39 @@ Refactor $ARGUMENTS.
|
|
|
14
15
|
- Smaller functions (single responsibility)
|
|
15
16
|
|
|
16
17
|
## Constraints
|
|
17
|
-
- NO behavior changes
|
|
18
|
+
- **NO behavior changes**
|
|
18
19
|
- Keep public API intact
|
|
19
20
|
- Existing tests must pass
|
|
20
21
|
|
|
21
22
|
Explain each change.
|
|
23
|
+
|
|
24
|
+
## After the refactor — verify it didn't break anything
|
|
25
|
+
|
|
26
|
+
"Existing tests must pass" is the load-bearing constraint, and the only
|
|
27
|
+
honest way to know is to run them.
|
|
28
|
+
|
|
29
|
+
1. **Detect the project's test command** (look for `package.json`
|
|
30
|
+
scripts, `pytest.ini` / `pyproject.toml`, `go.mod`, `Cargo.toml`,
|
|
31
|
+
`Makefile`). If none is found, **stop and ask** before claiming the
|
|
32
|
+
refactor is done — silent green isn't acceptable.
|
|
33
|
+
2. **Run the tests.** Scope to the affected area when possible (`-t`,
|
|
34
|
+
`--testPathPattern`, `pytest path/`, `go test ./pkg`); otherwise run
|
|
35
|
+
the suite.
|
|
36
|
+
3. **Report** pass / fail counts and any failure's name + `file:line`.
|
|
37
|
+
|
|
38
|
+
**Stop and ask** when (HITL gates — not all the time, only here):
|
|
39
|
+
- a test **fails** after the refactor. Don't auto-revert (destroys
|
|
40
|
+
work-in-progress) and don't push forward (the no-behavior-change
|
|
41
|
+
constraint is broken). Present the failure and the options:
|
|
42
|
+
**revert**, **patch the refactor**, or **update the test** (with
|
|
43
|
+
reasoning).
|
|
44
|
+
- the refactor crossed a **public API boundary** that callers depend
|
|
45
|
+
on — even if tests pass, downstream consumers may break.
|
|
46
|
+
- the change is **bigger than the user asked for** (scope creep —
|
|
47
|
+
unrelated cleanups, formatting, comment edits). Confirm before
|
|
48
|
+
applying.
|
|
49
|
+
|
|
50
|
+
Final report:
|
|
51
|
+
- **refactor done, tests N pass / 0 fail** — ready, OR
|
|
52
|
+
- **refactor done, but K tests fail** — awaiting direction (revert /
|
|
53
|
+
patch / update test).
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release
|
|
3
|
+
description: Deliver a feature end-to-end — verify, docs, merge, tag (publish stays manual)
|
|
4
|
+
usage: /release [branch]
|
|
5
|
+
argument-hint: [branch — new or existing; else current]
|
|
6
|
+
allowed-tools: Read, Grep, Glob, Edit, Write, Bash(git *), Bash(gh *), Bash(npm *), Bash(pnpm *), Bash(yarn *), Bash(pytest *), Bash(python *), Bash(go *), Bash(cargo *), Bash(make *)
|
|
7
|
+
---
|
|
8
|
+
End-to-end feature-delivery **orchestrator**. It does **not** re-implement
|
|
9
|
+
checks — it runs your existing gates (`/ship`, `/security`, `/diff-review`)
|
|
10
|
+
under `/verify-done` discipline, then performs the release actions. Two halves
|
|
11
|
+
split by a hard gate: everything **before** the gate is safe and read-only;
|
|
12
|
+
everything **after** rewrites history and is confirmed step by step.
|
|
13
|
+
|
|
14
|
+
**A feature branch is required — `main` is only the merge target.** `$ARGUMENTS`
|
|
15
|
+
names the branch to release. Omit it only if you are already on a feature
|
|
16
|
+
branch. If you are on `main` with nothing named, a branch is created for you —
|
|
17
|
+
but you should be releasing a deliberately-named feature branch.
|
|
18
|
+
|
|
19
|
+
## Phase 0 — Preflight (resolve a feature branch — never `main`)
|
|
20
|
+
- **Resolve the release branch** — whatever gets merged into `main`:
|
|
21
|
+
- `$ARGUMENTS` given → `git switch` to it (create it if it does not exist).
|
|
22
|
+
- else not on `main` → release the **current** branch.
|
|
23
|
+
- else on `main` with no arg → **create** `feat/<slug>` (named for the
|
|
24
|
+
change) and carry your working changes onto it. **Never release `main`.**
|
|
25
|
+
- **Land the feature on the branch** — if the working tree still has
|
|
26
|
+
uncommitted feature changes, commit them now; the gates must review a real
|
|
27
|
+
diff, not a dirty tree.
|
|
28
|
+
- `git fetch origin`; the release diff is `origin/main...HEAD` (now guaranteed
|
|
29
|
+
to be the resolved branch). If it is empty, **stop** — nothing to release.
|
|
30
|
+
- Print a one-line plan: branch · commit count · files changed.
|
|
31
|
+
|
|
32
|
+
## Phase 1 — VERIFY (delegate; no hand-waving)
|
|
33
|
+
**First, load the real checklists.** Locate and **read** the sibling command
|
|
34
|
+
definitions so you apply their exact checks, not an approximation — glob your
|
|
35
|
+
installed commands/skills for `ship.md`, `security.md`, `diff-review.md`, and
|
|
36
|
+
`verify-done` (a skill or command). If one cannot be found, run that check from
|
|
37
|
+
its name and **flag that its full checklist was unavailable** — never pretend
|
|
38
|
+
it passed.
|
|
39
|
+
|
|
40
|
+
Then run each gate and capture **fresh evidence** — the exact command, its exit
|
|
41
|
+
code, and the result. Per `/verify-done`: a check you did **not** actually run
|
|
42
|
+
is a **FAIL**, never an assumed pass.
|
|
43
|
+
- **`/ship`** — pre-deploy gate (tests, lint, build, secrets, authz, rate
|
|
44
|
+
limit, data scope, migrations, docs-sync).
|
|
45
|
+
- **`/security`** — on the changed files.
|
|
46
|
+
- **`/diff-review`** — on `origin/main...HEAD`.
|
|
47
|
+
|
|
48
|
+
Emit a coverage table, one row per gate: `ran? ✓/✗` · evidence · verdict. If
|
|
49
|
+
any row is ✗ (could not run), the run is **Blocked 🛑** — do not continue.
|
|
50
|
+
|
|
51
|
+
## 🚦 Gate
|
|
52
|
+
- **Any Critical** (failing tests/build, a Critical security or diff-review
|
|
53
|
+
finding) → **stop**, report, ask how to proceed. Touch no history.
|
|
54
|
+
- **Warnings, or anything you cannot confidently decide** → **stop**,
|
|
55
|
+
summarize, ask.
|
|
56
|
+
- **All clean** → continue to Phase 2.
|
|
57
|
+
|
|
58
|
+
## Phase 2 — DOCS (only what the feature changed)
|
|
59
|
+
Update as needed, matching each file's existing format; touch nothing
|
|
60
|
+
unrelated. If a doc needs no change, **say so** rather than editing for its
|
|
61
|
+
own sake.
|
|
62
|
+
- **CHANGELOG.md** — new entry.
|
|
63
|
+
- **PRD** — the feature's PRD entry / status.
|
|
64
|
+
- **context / guide** — the project's context or guide doc.
|
|
65
|
+
- **README.md** — only if user-facing usage changed.
|
|
66
|
+
|
|
67
|
+
## Phase 3 — RELEASE (irreversible — confirm each step)
|
|
68
|
+
1. **Version bump** — pick the semver level from the change (patch / minor /
|
|
69
|
+
major; ask if ambiguous) and update `package.json`.
|
|
70
|
+
2. **Commit** — `release: vX.Y.Z — <summary>`, including the docs + bump.
|
|
71
|
+
3. **Push** the branch.
|
|
72
|
+
4. **Open PR** — `gh pr create` into `main` (main is PR-protected: 1 approving
|
|
73
|
+
review).
|
|
74
|
+
5. **Merge** — `gh pr merge --delete-branch`. If the review requirement blocks
|
|
75
|
+
it, **stop** and ask the user to approve — never force or bypass protection.
|
|
76
|
+
6. **Tag** — after the merge, `git tag vX.Y.Z` on `main` and push it. Keep
|
|
77
|
+
cut→tag tight — one frozen step.
|
|
78
|
+
|
|
79
|
+
## Stop here — publish is your call
|
|
80
|
+
Do **not** publish. `publish.yml` is manual `workflow_dispatch` **by design**.
|
|
81
|
+
Print the handoff:
|
|
82
|
+
> Merged, branch deleted, tagged **vX.Y.Z**. To publish, run it yourself:
|
|
83
|
+
> `gh workflow run publish.yml`
|
|
84
|
+
> Then confirm the version is actually live (`npm view <pkg> versions`) and
|
|
85
|
+
> validate the **installed** artifact, not the working tree.
|
|
86
|
+
|
|
87
|
+
Final report: **Delivered ✅ (vX.Y.Z — publish pending)** or **Blocked 🛑**
|
|
88
|
+
with the specific reason.
|
|
@@ -4,7 +4,7 @@ description: Consolidate stashes + friction into project memory
|
|
|
4
4
|
usage: /remember
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Run friction analysis, then consolidate session stashes + friction antigens into a single project-local MEMORY.md, and inject into AGENTS.md. Friction runs automatically (best-effort) — there is no separate `/friction` command.
|
|
8
8
|
|
|
9
9
|
**Guardrails**
|
|
10
10
|
- Favor straightforward, minimal implementations first and add complexity only when requested or clearly required.
|
|
@@ -17,12 +17,43 @@ Reads all raw material (`.factory/stash/*.md` + `.factory/friction/antigen_clust
|
|
|
17
17
|
|
|
18
18
|
**Steps**
|
|
19
19
|
|
|
20
|
+
0. **Run friction first** (best-effort — friction analyzes ALL your usage, not just this repo)
|
|
21
|
+
|
|
22
|
+
Friction's signal is *global*: recurring corrections and frustrations across every
|
|
23
|
+
project are behavioral lessons worth keeping everywhere. So point it at the tool's
|
|
24
|
+
**global sessions root** (all projects), not a per-project directory.
|
|
25
|
+
|
|
26
|
+
- **Locate `friction.js`** — it is bundled next to this command at `friction/friction.js`
|
|
27
|
+
(the same directory as `remember.md`, whether installed or run from the package). If it
|
|
28
|
+
exists nowhere, skip to step 1 (stash-only) and tell the user friction.js is missing.
|
|
29
|
+
- **Resolve the global sessions root** — probe this list top-to-bottom, use the first that
|
|
30
|
+
exists and contains `.jsonl` files (recursively). **Never prompt the user.**
|
|
31
|
+
```
|
|
32
|
+
# ── Add your own global sessions root at the TOP so it is checked first ──
|
|
33
|
+
~/.claude/projects/ # Claude Code
|
|
34
|
+
~/.factory/projects/ # Droid / Factory
|
|
35
|
+
~/.config/amp/projects/ # Amp
|
|
36
|
+
~/.config/opencode/projects/ # opencode
|
|
37
|
+
~/.codex/sessions/ # Codex CLI (use $CODEX_HOME/sessions/ if set)
|
|
38
|
+
~/.gemini/antigravity-cli/brain/ # Antigravity
|
|
39
|
+
```
|
|
40
|
+
> Note: `friction.js` parses Claude Code's session schema. The Codex/Antigravity roots
|
|
41
|
+
> will resolve but yield no signals until friction learns their formats — open an issue
|
|
42
|
+
> to request one: https://github.com/hamr0/liteagents/issues
|
|
43
|
+
- **Run** `node <friction.js> "<resolved-root>"`. friction writes its output to
|
|
44
|
+
`.factory/friction/` in the current project.
|
|
45
|
+
- **On any miss — loud, never silent.** If no root resolves, or friction errors, or it
|
|
46
|
+
finds no usable sessions, print this and continue with stash-only consolidation:
|
|
47
|
+
> ⚠️ Friction didn't run — no sessions found. To enable it, open this command file
|
|
48
|
+
> (`remember.md`) and add your tool's **global** sessions root to the TOP of the probe
|
|
49
|
+
> list in step 0, then re-run `/remember`. Consolidating stashes only this time.
|
|
50
|
+
|
|
20
51
|
1. **Gather sources**
|
|
21
52
|
- Read all `.factory/stash/*.md` files in the current project
|
|
22
|
-
-
|
|
53
|
+
- Read friction output written in step 0: `.factory/friction/antigen_clusters.json` (preferred) or `.factory/friction/antigen_review.md` (fallback)
|
|
23
54
|
- Read existing `.factory/memory/MEMORY.md` if it exists — create dir if missing
|
|
24
55
|
- Read processed manifest at `.factory/memory/.processed` — skip already-processed stashes
|
|
25
|
-
- If no unprocessed stashes AND no
|
|
56
|
+
- If no unprocessed stashes AND friction produced no new antigens, report "nothing to consolidate" and stop
|
|
26
57
|
|
|
27
58
|
2. **Extract from unprocessed stashes** (use Task tool with sonnet model for each)
|
|
28
59
|
- For each unprocessed stash, call sonnet to extract:
|