devflow-kit 1.5.0 → 1.6.1
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 +51 -0
- package/README.md +9 -4
- package/dist/commands/ambient.js +1 -1
- package/dist/commands/init.js +8 -4
- package/dist/commands/uninstall.d.ts +9 -0
- package/dist/commands/uninstall.js +60 -4
- package/dist/plugins.js +23 -23
- package/dist/utils/post-install.js +6 -2
- package/package.json +1 -1
- package/plugins/devflow-accessibility/.claude-plugin/plugin.json +1 -1
- package/plugins/devflow-ambient/.claude-plugin/plugin.json +25 -4
- package/plugins/devflow-ambient/README.md +48 -29
- package/plugins/devflow-ambient/agents/coder.md +135 -0
- package/plugins/devflow-ambient/agents/reviewer.md +165 -0
- package/plugins/devflow-ambient/agents/scrutinizer.md +80 -0
- package/plugins/devflow-ambient/agents/shepherd.md +94 -0
- package/plugins/devflow-ambient/agents/simplifier.md +93 -0
- package/plugins/devflow-ambient/agents/skimmer.md +93 -0
- package/plugins/devflow-ambient/agents/validator.md +86 -0
- package/plugins/devflow-ambient/skills/ambient-router/SKILL.md +76 -29
- package/plugins/devflow-ambient/skills/ambient-router/references/skill-catalog.md +40 -35
- package/plugins/devflow-ambient/skills/debug-orchestration/SKILL.md +69 -0
- package/plugins/devflow-ambient/skills/implementation-orchestration/SKILL.md +92 -0
- package/plugins/devflow-ambient/skills/plan-orchestration/SKILL.md +71 -0
- package/plugins/devflow-audit-claude/.claude-plugin/plugin.json +10 -1
- package/plugins/devflow-audit-claude/commands/audit-claude.md +4 -0
- package/plugins/devflow-code-review/.claude-plugin/plugin.json +2 -1
- package/plugins/devflow-code-review/agents/reviewer.md +10 -9
- package/plugins/devflow-code-review/commands/code-review-teams.md +43 -30
- package/plugins/devflow-code-review/commands/code-review.md +10 -1
- package/plugins/devflow-code-review/skills/knowledge-persistence/SKILL.md +128 -0
- package/plugins/devflow-code-review/skills/knowledge-persistence/references/examples.md +44 -0
- package/plugins/devflow-core-skills/.claude-plugin/plugin.json +1 -1
- package/plugins/devflow-core-skills/skills/docs-framework/SKILL.md +7 -2
- package/plugins/devflow-core-skills/skills/test-driven-development/SKILL.md +6 -5
- package/plugins/devflow-debug/.claude-plugin/plugin.json +5 -3
- package/plugins/devflow-debug/agents/synthesizer.md +211 -0
- package/plugins/devflow-debug/commands/debug-teams.md +28 -14
- package/plugins/devflow-debug/commands/debug.md +26 -12
- package/plugins/devflow-debug/skills/knowledge-persistence/SKILL.md +128 -0
- package/plugins/devflow-debug/skills/knowledge-persistence/references/examples.md +44 -0
- package/plugins/devflow-frontend-design/.claude-plugin/plugin.json +1 -1
- package/plugins/devflow-go/.claude-plugin/plugin.json +1 -1
- package/plugins/devflow-implement/.claude-plugin/plugin.json +2 -1
- package/plugins/devflow-implement/agents/coder.md +6 -1
- package/plugins/devflow-implement/agents/simplifier.md +32 -1
- package/plugins/devflow-implement/agents/skimmer.md +5 -0
- package/plugins/devflow-implement/commands/implement-teams.md +72 -55
- package/plugins/devflow-implement/commands/implement.md +44 -35
- package/plugins/devflow-implement/skills/knowledge-persistence/SKILL.md +128 -0
- package/plugins/devflow-implement/skills/knowledge-persistence/references/examples.md +44 -0
- package/plugins/devflow-java/.claude-plugin/plugin.json +1 -1
- package/plugins/devflow-python/.claude-plugin/plugin.json +1 -1
- package/plugins/devflow-react/.claude-plugin/plugin.json +1 -1
- package/plugins/devflow-resolve/.claude-plugin/plugin.json +4 -3
- package/plugins/devflow-resolve/agents/simplifier.md +32 -1
- package/plugins/devflow-resolve/commands/resolve-teams.md +16 -7
- package/plugins/devflow-resolve/commands/resolve.md +16 -7
- package/plugins/devflow-resolve/skills/knowledge-persistence/SKILL.md +128 -0
- package/plugins/devflow-resolve/skills/knowledge-persistence/references/examples.md +44 -0
- package/plugins/devflow-rust/.claude-plugin/plugin.json +1 -1
- package/plugins/devflow-self-review/.claude-plugin/plugin.json +10 -1
- package/plugins/devflow-self-review/agents/simplifier.md +32 -1
- package/plugins/devflow-self-review/commands/self-review.md +10 -4
- package/plugins/devflow-specify/.claude-plugin/plugin.json +1 -1
- package/plugins/devflow-specify/agents/skimmer.md +5 -0
- package/plugins/devflow-specify/commands/specify-teams.md +27 -20
- package/plugins/devflow-specify/commands/specify.md +26 -19
- package/plugins/devflow-typescript/.claude-plugin/plugin.json +1 -1
- package/scripts/hooks/ambient-prompt +10 -8
- package/scripts/hooks/background-memory-update +114 -85
- package/scripts/hooks/session-start-memory +34 -20
- package/shared/agents/coder.md +6 -1
- package/shared/agents/reviewer.md +10 -9
- package/shared/agents/simplifier.md +32 -1
- package/shared/agents/skimmer.md +5 -0
- package/shared/skills/ambient-router/SKILL.md +76 -29
- package/shared/skills/ambient-router/references/skill-catalog.md +40 -35
- package/shared/skills/debug-orchestration/SKILL.md +69 -0
- package/shared/skills/docs-framework/SKILL.md +7 -2
- package/shared/skills/implementation-orchestration/SKILL.md +92 -0
- package/shared/skills/knowledge-persistence/SKILL.md +128 -0
- package/shared/skills/knowledge-persistence/references/examples.md +44 -0
- package/shared/skills/plan-orchestration/SKILL.md +71 -0
- package/shared/skills/test-driven-development/SKILL.md +6 -5
- package/plugins/devflow-ambient/commands/ambient.md +0 -110
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: Skimmer
|
|
3
3
|
description: Codebase orientation using skim to identify relevant files, functions, and patterns for a feature or task
|
|
4
|
+
skills: knowledge-persistence
|
|
4
5
|
model: inherit
|
|
5
6
|
---
|
|
6
7
|
|
|
@@ -20,6 +21,7 @@ You receive from orchestrator:
|
|
|
20
21
|
3. **Search for task-relevant code** - Find files matching task keywords
|
|
21
22
|
4. **Identify integration points** - Exports, entry points, import patterns
|
|
22
23
|
5. **Generate orientation summary** - Structured output for implementation planning
|
|
24
|
+
6. **Check project knowledge** - If `.memory/knowledge/decisions.md` exists, read its `<!-- TL;DR: ... -->` first-line comment and include active decision count in orientation under "### Active Decisions". Only the TL;DR is read here (not full entries) — this is intentional for token efficiency; agents that need full entries read the file themselves.
|
|
23
25
|
|
|
24
26
|
## Tool Invocation
|
|
25
27
|
|
|
@@ -64,6 +66,9 @@ Always invoke skim via `npx rskim`. This works whether or not skim is globally i
|
|
|
64
66
|
### Patterns Observed
|
|
65
67
|
{Existing patterns to follow}
|
|
66
68
|
|
|
69
|
+
### Active Decisions
|
|
70
|
+
{Count and key decisions from `.memory/knowledge/decisions.md` TL;DR, or "None found" if file missing}
|
|
71
|
+
|
|
67
72
|
### Suggested Approach
|
|
68
73
|
{Brief recommendation based on codebase structure}
|
|
69
74
|
```
|
|
@@ -57,7 +57,11 @@ Find: project structure, similar features, patterns, integration points
|
|
|
57
57
|
Return: codebase context for requirements (not implementation details)"
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
### Phase 3:
|
|
60
|
+
### Phase 3: Load Project Knowledge
|
|
61
|
+
|
|
62
|
+
Read `.memory/knowledge/decisions.md` and `.memory/knowledge/pitfalls.md`. Pass their content as context to the exploration team below — prior decisions constrain requirements, known pitfalls inform failure modes.
|
|
63
|
+
|
|
64
|
+
### Phase 4: Explore Requirements (Agent Teams)
|
|
61
65
|
|
|
62
66
|
Create an agent team for collaborative requirements exploration:
|
|
63
67
|
|
|
@@ -122,7 +126,7 @@ Max 2 debate rounds, then submit consensus requirements findings.
|
|
|
122
126
|
|
|
123
127
|
**Exploration team output**: Consensus findings on user needs, similar features, constraints, failure modes.
|
|
124
128
|
|
|
125
|
-
**Team Shutdown Protocol** (must complete before Phase
|
|
129
|
+
**Team Shutdown Protocol** (must complete before Phase 6):
|
|
126
130
|
|
|
127
131
|
```
|
|
128
132
|
Step 1: Shutdown each teammate
|
|
@@ -139,9 +143,9 @@ Step 3: GATE — Verify TeamDelete succeeded
|
|
|
139
143
|
If retry failed → HALT and report: "Exploration team cleanup failed. Cannot create planning team."
|
|
140
144
|
```
|
|
141
145
|
|
|
142
|
-
### Phase
|
|
146
|
+
### Phase 5: Synthesize Exploration
|
|
143
147
|
|
|
144
|
-
**WAIT** for Phase
|
|
148
|
+
**WAIT** for Phase 4, then spawn Synthesizer:
|
|
145
149
|
|
|
146
150
|
```
|
|
147
151
|
Task(subagent_type="Synthesizer"):
|
|
@@ -151,7 +155,7 @@ Explorer consensus: {team exploration consensus output}
|
|
|
151
155
|
Combine into: user needs, similar features, constraints, failure modes"
|
|
152
156
|
```
|
|
153
157
|
|
|
154
|
-
### Phase
|
|
158
|
+
### Phase 6: Plan Scope (Agent Teams)
|
|
155
159
|
|
|
156
160
|
Create an agent team for collaborative scope planning:
|
|
157
161
|
|
|
@@ -164,7 +168,7 @@ Spawn planning teammates with self-contained prompts:
|
|
|
164
168
|
Prompt: |
|
|
165
169
|
You are planning scope for feature: {feature}
|
|
166
170
|
Exploration synthesis (what we know):
|
|
167
|
-
{synthesis output from Phase
|
|
171
|
+
{synthesis output from Phase 5}
|
|
168
172
|
|
|
169
173
|
Your deliverable: User stories in "As X, I want Y, so that Z" format.
|
|
170
174
|
Cover all actors, actions, and outcomes identified in exploration.
|
|
@@ -175,7 +179,7 @@ Spawn planning teammates with self-contained prompts:
|
|
|
175
179
|
Prompt: |
|
|
176
180
|
You are planning scope for feature: {feature}
|
|
177
181
|
Exploration synthesis (what we know):
|
|
178
|
-
{synthesis output from Phase
|
|
182
|
+
{synthesis output from Phase 5}
|
|
179
183
|
|
|
180
184
|
Your deliverable: v1 MVP scope, v2 deferred items, explicitly out of scope,
|
|
181
185
|
and dependencies on other features or systems.
|
|
@@ -186,7 +190,7 @@ Spawn planning teammates with self-contained prompts:
|
|
|
186
190
|
Prompt: |
|
|
187
191
|
You are planning scope for feature: {feature}
|
|
188
192
|
Exploration synthesis (what we know):
|
|
189
|
-
{synthesis output from Phase
|
|
193
|
+
{synthesis output from Phase 5}
|
|
190
194
|
|
|
191
195
|
Your deliverable: Testable acceptance criteria for success cases,
|
|
192
196
|
failure cases, and edge cases. Every criterion must be verifiable.
|
|
@@ -221,9 +225,9 @@ Step 3: GATE — Verify TeamDelete succeeded
|
|
|
221
225
|
If retry failed → HALT and report: "Planning team cleanup failed. Cannot proceed to Gate 1."
|
|
222
226
|
```
|
|
223
227
|
|
|
224
|
-
### Phase
|
|
228
|
+
### Phase 7: Synthesize Planning
|
|
225
229
|
|
|
226
|
-
**WAIT** for Phase
|
|
230
|
+
**WAIT** for Phase 6, then spawn Synthesizer:
|
|
227
231
|
|
|
228
232
|
```
|
|
229
233
|
Task(subagent_type="Synthesizer"):
|
|
@@ -233,7 +237,7 @@ Planner consensus: {team planning consensus output}
|
|
|
233
237
|
Combine into: user stories, scope breakdown, acceptance criteria, open questions"
|
|
234
238
|
```
|
|
235
239
|
|
|
236
|
-
### Phase
|
|
240
|
+
### Phase 8: Gate 1 - Validate Scope
|
|
237
241
|
|
|
238
242
|
Use AskUserQuestion to validate:
|
|
239
243
|
- Primary problem being solved
|
|
@@ -241,14 +245,14 @@ Use AskUserQuestion to validate:
|
|
|
241
245
|
- v1 scope selection (minimal/medium/full)
|
|
242
246
|
- Explicit exclusions
|
|
243
247
|
|
|
244
|
-
### Phase
|
|
248
|
+
### Phase 9: Gate 2 - Confirm Criteria
|
|
245
249
|
|
|
246
250
|
Present specification summary, then use AskUserQuestion for final confirmation:
|
|
247
251
|
- Success UX pattern
|
|
248
252
|
- Error handling approach
|
|
249
253
|
- Ready to create issue / Needs changes / Cancel
|
|
250
254
|
|
|
251
|
-
### Phase
|
|
255
|
+
### Phase 10: Create Issue
|
|
252
256
|
|
|
253
257
|
Create GitHub issue with `gh issue create`:
|
|
254
258
|
- Title: feature name
|
|
@@ -268,32 +272,35 @@ Report issue number and URL.
|
|
|
268
272
|
├─ Phase 2: Orient
|
|
269
273
|
│ └─ Skimmer agent (codebase context via skim)
|
|
270
274
|
│
|
|
271
|
-
├─ Phase 3:
|
|
275
|
+
├─ Phase 3: Load Project Knowledge
|
|
276
|
+
│ └─ Read decisions.md + pitfalls.md
|
|
277
|
+
│
|
|
278
|
+
├─ Phase 4: Explore Requirements (Agent Teams)
|
|
272
279
|
│ ├─ User Perspective Explorer (teammate)
|
|
273
280
|
│ ├─ Similar Features Explorer (teammate)
|
|
274
281
|
│ ├─ Constraints Explorer (teammate)
|
|
275
282
|
│ ├─ Failure Mode Explorer (teammate)
|
|
276
283
|
│ └─ Debate → consensus requirements findings
|
|
277
284
|
│
|
|
278
|
-
├─ Phase
|
|
285
|
+
├─ Phase 5: Synthesize Exploration
|
|
279
286
|
│ └─ Synthesizer agent (mode: exploration)
|
|
280
287
|
│
|
|
281
|
-
├─ Phase
|
|
288
|
+
├─ Phase 6: Plan Scope (Agent Teams)
|
|
282
289
|
│ ├─ User Stories Planner (teammate)
|
|
283
290
|
│ ├─ Scope Boundaries Planner (teammate)
|
|
284
291
|
│ ├─ Acceptance Criteria Planner (teammate)
|
|
285
292
|
│ └─ Debate → consensus scope plan
|
|
286
293
|
│
|
|
287
|
-
├─ Phase
|
|
294
|
+
├─ Phase 7: Synthesize Planning
|
|
288
295
|
│ └─ Synthesizer agent (mode: planning)
|
|
289
296
|
│
|
|
290
|
-
├─ Phase
|
|
297
|
+
├─ Phase 8: GATE 1 - Validate Scope ⛔ MANDATORY
|
|
291
298
|
│ └─ AskUserQuestion: Confirm scope and priorities
|
|
292
299
|
│
|
|
293
|
-
├─ Phase
|
|
300
|
+
├─ Phase 9: GATE 2 - Confirm Criteria ⛔ MANDATORY
|
|
294
301
|
│ └─ AskUserQuestion: Final spec approval
|
|
295
302
|
│
|
|
296
|
-
├─ Phase
|
|
303
|
+
├─ Phase 10: Create Issue
|
|
297
304
|
│ └─ gh issue create
|
|
298
305
|
│
|
|
299
306
|
└─ Report: Issue number, URL, /implement command
|
|
@@ -57,20 +57,24 @@ Find: project structure, similar features, patterns, integration points
|
|
|
57
57
|
Return: codebase context for requirements (not implementation details)"
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
### Phase 3:
|
|
60
|
+
### Phase 3: Load Project Knowledge
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
Read `.memory/knowledge/decisions.md` and `.memory/knowledge/pitfalls.md`. Pass their content as context to the Explore agents below — prior decisions constrain requirements, known pitfalls inform failure modes.
|
|
63
|
+
|
|
64
|
+
### Phase 4: Explore Requirements (Parallel)
|
|
65
|
+
|
|
66
|
+
Spawn 4 Explore agents **in a single message**, each with Skimmer context and project knowledge (if loaded):
|
|
63
67
|
|
|
64
68
|
| Focus | Thoroughness | Find |
|
|
65
69
|
|-------|-------------|------|
|
|
66
70
|
| User perspective | medium | Target users, goals, pain points, user journeys |
|
|
67
71
|
| Similar features | medium | Comparable features, scope patterns, edge cases |
|
|
68
|
-
| Constraints | quick | Dependencies, business rules, security, performance |
|
|
69
|
-
| Failure modes | quick | Error states, edge cases, validation needs |
|
|
72
|
+
| Constraints | quick | Dependencies, business rules, security, performance, **prior architectural decisions** |
|
|
73
|
+
| Failure modes | quick | Error states, edge cases, validation needs, **known pitfalls** |
|
|
70
74
|
|
|
71
|
-
### Phase
|
|
75
|
+
### Phase 5: Synthesize Exploration
|
|
72
76
|
|
|
73
|
-
**WAIT** for Phase
|
|
77
|
+
**WAIT** for Phase 4, then spawn Synthesizer:
|
|
74
78
|
|
|
75
79
|
```
|
|
76
80
|
Task(subagent_type="Synthesizer"):
|
|
@@ -79,7 +83,7 @@ Mode: exploration
|
|
|
79
83
|
Combine into: user needs, similar features, constraints, failure modes"
|
|
80
84
|
```
|
|
81
85
|
|
|
82
|
-
### Phase
|
|
86
|
+
### Phase 6: Plan Scope (Parallel)
|
|
83
87
|
|
|
84
88
|
Spawn 3 Plan agents **in a single message**, each with exploration synthesis:
|
|
85
89
|
|
|
@@ -89,9 +93,9 @@ Spawn 3 Plan agents **in a single message**, each with exploration synthesis:
|
|
|
89
93
|
| Scope boundaries | v1 MVP, v2 deferred, out of scope, dependencies |
|
|
90
94
|
| Acceptance criteria | Success/failure/edge case criteria (testable) |
|
|
91
95
|
|
|
92
|
-
### Phase
|
|
96
|
+
### Phase 7: Synthesize Planning
|
|
93
97
|
|
|
94
|
-
**WAIT** for Phase
|
|
98
|
+
**WAIT** for Phase 6, then spawn Synthesizer:
|
|
95
99
|
|
|
96
100
|
```
|
|
97
101
|
Task(subagent_type="Synthesizer"):
|
|
@@ -100,7 +104,7 @@ Mode: planning
|
|
|
100
104
|
Combine into: user stories, scope breakdown, acceptance criteria, open questions"
|
|
101
105
|
```
|
|
102
106
|
|
|
103
|
-
### Phase
|
|
107
|
+
### Phase 8: Gate 1 - Validate Scope
|
|
104
108
|
|
|
105
109
|
Use AskUserQuestion to validate:
|
|
106
110
|
- Primary problem being solved
|
|
@@ -108,14 +112,14 @@ Use AskUserQuestion to validate:
|
|
|
108
112
|
- v1 scope selection (minimal/medium/full)
|
|
109
113
|
- Explicit exclusions
|
|
110
114
|
|
|
111
|
-
### Phase
|
|
115
|
+
### Phase 9: Gate 2 - Confirm Criteria
|
|
112
116
|
|
|
113
117
|
Present specification summary, then use AskUserQuestion for final confirmation:
|
|
114
118
|
- Success UX pattern
|
|
115
119
|
- Error handling approach
|
|
116
120
|
- Ready to create issue / Needs changes / Cancel
|
|
117
121
|
|
|
118
|
-
### Phase
|
|
122
|
+
### Phase 10: Create Issue
|
|
119
123
|
|
|
120
124
|
Create GitHub issue with `gh issue create`:
|
|
121
125
|
- Title: feature name
|
|
@@ -135,30 +139,33 @@ Report issue number and URL.
|
|
|
135
139
|
├─ Phase 2: Orient
|
|
136
140
|
│ └─ Skimmer agent (codebase context via skim)
|
|
137
141
|
│
|
|
138
|
-
├─ Phase 3:
|
|
142
|
+
├─ Phase 3: Load Project Knowledge
|
|
143
|
+
│ └─ Read decisions.md + pitfalls.md
|
|
144
|
+
│
|
|
145
|
+
├─ Phase 4: Explore Requirements (PARALLEL)
|
|
139
146
|
│ ├─ Explore: User perspective
|
|
140
147
|
│ ├─ Explore: Similar features
|
|
141
148
|
│ ├─ Explore: Constraints
|
|
142
149
|
│ └─ Explore: Failure modes
|
|
143
150
|
│
|
|
144
|
-
├─ Phase
|
|
151
|
+
├─ Phase 5: Synthesize Exploration
|
|
145
152
|
│ └─ Synthesizer agent (mode: exploration)
|
|
146
153
|
│
|
|
147
|
-
├─ Phase
|
|
154
|
+
├─ Phase 6: Plan Scope (PARALLEL)
|
|
148
155
|
│ ├─ Plan: User stories
|
|
149
156
|
│ ├─ Plan: Scope boundaries
|
|
150
157
|
│ └─ Plan: Acceptance criteria
|
|
151
158
|
│
|
|
152
|
-
├─ Phase
|
|
159
|
+
├─ Phase 7: Synthesize Planning
|
|
153
160
|
│ └─ Synthesizer agent (mode: planning)
|
|
154
161
|
│
|
|
155
|
-
├─ Phase
|
|
162
|
+
├─ Phase 8: GATE 1 - Validate Scope ⛔ MANDATORY
|
|
156
163
|
│ └─ AskUserQuestion: Confirm scope and priorities
|
|
157
164
|
│
|
|
158
|
-
├─ Phase
|
|
165
|
+
├─ Phase 9: GATE 2 - Confirm Criteria ⛔ MANDATORY
|
|
159
166
|
│ └─ AskUserQuestion: Final spec approval
|
|
160
167
|
│
|
|
161
|
-
├─ Phase
|
|
168
|
+
├─ Phase 10: Create Issue
|
|
162
169
|
│ └─ gh issue create
|
|
163
170
|
│
|
|
164
171
|
└─ Report: Issue number, URL, /implement command
|
|
@@ -25,20 +25,22 @@ if [[ "$PROMPT" == /* ]]; then
|
|
|
25
25
|
fi
|
|
26
26
|
|
|
27
27
|
# Skip single-word confirmations (< 2 words)
|
|
28
|
-
WORD_COUNT=$(
|
|
28
|
+
WORD_COUNT=$(printf '%s' "$PROMPT" | wc -w | tr -d ' ')
|
|
29
29
|
if [ "$WORD_COUNT" -lt 2 ]; then
|
|
30
30
|
exit 0
|
|
31
31
|
fi
|
|
32
32
|
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
Intent: BUILD | DEBUG | REVIEW | PLAN | EXPLORE | CHAT
|
|
36
|
-
Depth: QUICK (no overhead) | GUIDED (load skills) | ELEVATE (suggest /command)
|
|
33
|
+
# Normalize to lowercase for matching
|
|
34
|
+
PROMPT_LOWER=$(printf '%s' "$PROMPT" | tr '[:upper:]' '[:lower:]')
|
|
37
35
|
|
|
38
|
-
|
|
36
|
+
# Fast-path: git operations are always QUICK — skip preamble
|
|
37
|
+
if printf '%s' "$PROMPT_LOWER" | grep -qE '^(commit|push|pull|merge|rebase|cherry-pick|squash|tag|stash)|create (a )?pr|open (a )?pr'; then
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
# Inject classification preamble
|
|
42
|
+
# SYNC: must match tests/integration/helpers.ts AMBIENT_PREAMBLE
|
|
43
|
+
PREAMBLE="AMBIENT MODE ACTIVE: Before responding, silently classify this prompt using the ambient-router skill already in your session context. If QUICK, respond normally without stating classification. If GUIDED or ORCHESTRATED, you MUST load the selected skills using the Skill tool before proceeding."
|
|
42
44
|
|
|
43
45
|
jq -n --arg ctx "$PREAMBLE" '{
|
|
44
46
|
"hookSpecificOutput": {
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
# Background Working Memory Updater
|
|
4
4
|
# Called by stop-update-memory as a detached background process.
|
|
5
|
-
#
|
|
6
|
-
#
|
|
5
|
+
# Reads the last turn from the session transcript, then uses a fresh `claude -p`
|
|
6
|
+
# invocation to update .memory/WORKING-MEMORY.md.
|
|
7
|
+
# On failure: logs error, does nothing (stale memory is better than fake data).
|
|
7
8
|
|
|
8
9
|
set -e
|
|
9
10
|
|
|
@@ -29,7 +30,7 @@ rotate_log() {
|
|
|
29
30
|
|
|
30
31
|
# --- Stale Lock Recovery ---
|
|
31
32
|
|
|
32
|
-
# Portable mtime in epoch seconds
|
|
33
|
+
# Portable mtime in epoch seconds
|
|
33
34
|
get_mtime() {
|
|
34
35
|
if stat --version &>/dev/null 2>&1; then
|
|
35
36
|
stat -c %Y "$1"
|
|
@@ -72,11 +73,65 @@ cleanup() {
|
|
|
72
73
|
}
|
|
73
74
|
trap cleanup EXIT
|
|
74
75
|
|
|
76
|
+
# --- Transcript Extraction ---
|
|
77
|
+
|
|
78
|
+
extract_last_turn() {
|
|
79
|
+
# Compute transcript path: Claude Code stores transcripts at
|
|
80
|
+
# ~/.claude/projects/{cwd-with-slashes-replaced-by-hyphens}/{session_id}.jsonl
|
|
81
|
+
local encoded_cwd
|
|
82
|
+
encoded_cwd=$(echo "$CWD" | sed 's|^/||' | tr '/' '-')
|
|
83
|
+
local transcript="$HOME/.claude/projects/-${encoded_cwd}/${SESSION_ID}.jsonl"
|
|
84
|
+
|
|
85
|
+
if [ ! -f "$transcript" ]; then
|
|
86
|
+
log "Transcript not found at $transcript"
|
|
87
|
+
return 1
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
# Extract last user and assistant text from JSONL
|
|
91
|
+
# Each line is a JSON object with "type" field
|
|
92
|
+
local last_user last_assistant
|
|
93
|
+
|
|
94
|
+
last_user=$(grep '"type":"user"' "$transcript" 2>/dev/null \
|
|
95
|
+
| tail -3 \
|
|
96
|
+
| jq -r '
|
|
97
|
+
if .message.content then
|
|
98
|
+
[.message.content[] | select(.type == "text") | .text] | join("\n")
|
|
99
|
+
else ""
|
|
100
|
+
end
|
|
101
|
+
' 2>/dev/null \
|
|
102
|
+
| tail -1)
|
|
103
|
+
|
|
104
|
+
last_assistant=$(grep '"type":"assistant"' "$transcript" 2>/dev/null \
|
|
105
|
+
| tail -3 \
|
|
106
|
+
| jq -r '
|
|
107
|
+
if .message.content then
|
|
108
|
+
[.message.content[] | select(.type == "text") | .text] | join("\n")
|
|
109
|
+
else ""
|
|
110
|
+
end
|
|
111
|
+
' 2>/dev/null \
|
|
112
|
+
| tail -1)
|
|
113
|
+
|
|
114
|
+
# Truncate to ~4000 chars total to keep token cost low
|
|
115
|
+
if [ ${#last_user} -gt 2000 ]; then
|
|
116
|
+
last_user="${last_user:0:2000}... [truncated]"
|
|
117
|
+
fi
|
|
118
|
+
if [ ${#last_assistant} -gt 2000 ]; then
|
|
119
|
+
last_assistant="${last_assistant:0:2000}... [truncated]"
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
if [ -z "$last_user" ] && [ -z "$last_assistant" ]; then
|
|
123
|
+
log "No text content found in transcript"
|
|
124
|
+
return 1
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
LAST_USER_TEXT="$last_user"
|
|
128
|
+
LAST_ASSISTANT_TEXT="$last_assistant"
|
|
129
|
+
return 0
|
|
130
|
+
}
|
|
131
|
+
|
|
75
132
|
# --- Main ---
|
|
76
133
|
|
|
77
|
-
# Wait for parent session to flush transcript
|
|
78
|
-
# 3s provides ~6-10x margin over typical flush times.
|
|
79
|
-
# If --resume shows stale transcripts, bump to 5s.
|
|
134
|
+
# Wait for parent session to flush transcript
|
|
80
135
|
sleep 3
|
|
81
136
|
|
|
82
137
|
log "Starting update for session $SESSION_ID"
|
|
@@ -87,7 +142,6 @@ break_stale_lock
|
|
|
87
142
|
# Acquire lock (other sessions may be updating concurrently)
|
|
88
143
|
if ! acquire_lock; then
|
|
89
144
|
log "Lock timeout after 90s — skipping update for session $SESSION_ID"
|
|
90
|
-
# Don't clean up lock we don't own
|
|
91
145
|
trap - EXIT
|
|
92
146
|
exit 0
|
|
93
147
|
fi
|
|
@@ -102,97 +156,72 @@ if [ -f "$MEMORY_FILE" ]; then
|
|
|
102
156
|
PRE_UPDATE_MTIME=$(get_mtime "$MEMORY_FILE")
|
|
103
157
|
fi
|
|
104
158
|
|
|
105
|
-
#
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
$
|
|
118
|
-
else
|
|
119
|
-
PATTERNS_INSTRUCTION="
|
|
120
|
-
|
|
121
|
-
If recurring patterns were observed during this session (coding conventions, architectural decisions, team preferences, tooling quirks), create $PATTERNS_FILE with entries formatted as: - **Pattern name**: Brief description (discovered: YYYY-MM-DD). Only create this file if genuine patterns were observed — do not fabricate entries."
|
|
159
|
+
# Gather git state (always available, used as fallback too)
|
|
160
|
+
GIT_STATE=""
|
|
161
|
+
if cd "$CWD" 2>/dev/null && git rev-parse --git-dir >/dev/null 2>&1; then
|
|
162
|
+
GIT_STATUS=$(git status --short 2>/dev/null | head -20)
|
|
163
|
+
GIT_LOG=$(git log --oneline -5 2>/dev/null)
|
|
164
|
+
GIT_DIFF=$(git diff --stat HEAD 2>/dev/null | tail -10)
|
|
165
|
+
GIT_STATE="Branch: $(git branch --show-current 2>/dev/null || echo 'unknown')
|
|
166
|
+
Recent commits:
|
|
167
|
+
${GIT_LOG}
|
|
168
|
+
Changed files:
|
|
169
|
+
${GIT_STATUS}
|
|
170
|
+
Diff summary:
|
|
171
|
+
${GIT_DIFF}"
|
|
122
172
|
fi
|
|
123
173
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
$
|
|
174
|
+
# Extract last turn from transcript (or fall back to git-only)
|
|
175
|
+
LAST_USER_TEXT=""
|
|
176
|
+
LAST_ASSISTANT_TEXT=""
|
|
177
|
+
EXCHANGE_SECTION=""
|
|
178
|
+
|
|
179
|
+
if extract_last_turn; then
|
|
180
|
+
log "--- Extracted user text (${#LAST_USER_TEXT} chars) ---"
|
|
181
|
+
log "$LAST_USER_TEXT"
|
|
182
|
+
log "--- Extracted assistant text (${#LAST_ASSISTANT_TEXT} chars) ---"
|
|
183
|
+
log "$LAST_ASSISTANT_TEXT"
|
|
184
|
+
log "--- End transcript extraction ---"
|
|
185
|
+
EXCHANGE_SECTION="Last exchange:
|
|
186
|
+
User: ${LAST_USER_TEXT}
|
|
187
|
+
Assistant: ${LAST_ASSISTANT_TEXT}"
|
|
132
188
|
else
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
EXISTING_PATTERNS=$(cat "$PATTERNS_FILE")
|
|
137
|
-
PATTERNS_INSTRUCTION="
|
|
138
|
-
|
|
139
|
-
Also update $PATTERNS_FILE by APPENDING any new recurring patterns discovered during this session. Do NOT overwrite existing entries — only add new ones. Skip if no new patterns were observed. Format each entry as: - **Pattern name**: Brief description (discovered: YYYY-MM-DD). Keep patterns.md under 40 entries. When approaching the limit, consolidate related patterns into broader entries rather than adding duplicates.
|
|
140
|
-
|
|
141
|
-
Existing patterns:
|
|
142
|
-
$EXISTING_PATTERNS"
|
|
143
|
-
else
|
|
144
|
-
PATTERNS_INSTRUCTION="
|
|
145
|
-
|
|
146
|
-
If recurring patterns were observed during this session (coding conventions, architectural decisions, team preferences, tooling quirks), create $PATTERNS_FILE with entries formatted as: - **Pattern name**: Brief description (discovered: YYYY-MM-DD). Only create this file if genuine patterns were observed — do not fabricate entries."
|
|
147
|
-
fi
|
|
148
|
-
|
|
149
|
-
INSTRUCTION="First, Read the file $MEMORY_FILE if it exists (to satisfy Claude Code's read-before-write requirement). Then create it with working memory from this session. Keep under 120 lines. Use this structure:
|
|
150
|
-
|
|
151
|
-
# Working Memory
|
|
152
|
-
|
|
153
|
-
## Now
|
|
154
|
-
<!-- Current focus, status, blockers (1-3 bullets) -->
|
|
155
|
-
|
|
156
|
-
## Progress
|
|
157
|
-
<!-- Done: completed items (1-3). Remaining: next steps (1-3). Blockers: if any. -->
|
|
189
|
+
log "Falling back to git-state-only context"
|
|
190
|
+
EXCHANGE_SECTION="(Session transcript not available — using git state only)"
|
|
191
|
+
fi
|
|
158
192
|
|
|
159
|
-
|
|
160
|
-
|
|
193
|
+
# Build prompt for fresh claude -p invocation
|
|
194
|
+
PROMPT="You are a working memory updater. Your ONLY job is to update the file at ${MEMORY_FILE} using the Write tool. Do it immediately — do not ask questions or explain.
|
|
161
195
|
|
|
162
|
-
|
|
163
|
-
|
|
196
|
+
Current working memory:
|
|
197
|
+
${EXISTING_MEMORY:-"(no existing content)"}
|
|
164
198
|
|
|
165
|
-
|
|
166
|
-
<!-- Branch, PR, architectural context, open questions -->
|
|
199
|
+
${EXCHANGE_SECTION}
|
|
167
200
|
|
|
168
|
-
|
|
201
|
+
Git state:
|
|
202
|
+
${GIT_STATE:-"(not a git repo)"}
|
|
169
203
|
|
|
170
|
-
|
|
171
|
-
|
|
204
|
+
Instructions:
|
|
205
|
+
- Use the Write tool to update ${MEMORY_FILE} immediately
|
|
206
|
+
- Keep under 120 lines
|
|
207
|
+
- Use sections: ## Now, ## Progress, ## Decisions, ## Modified Files, ## Context, ## Session Log
|
|
208
|
+
- Integrate new information with existing content
|
|
209
|
+
- Deduplicate overlapping information
|
|
210
|
+
- ## Progress tracks Done (completed), Remaining (next steps), Blockers (if any)
|
|
211
|
+
- ## Decisions entries: format as - **[Decision]** — [rationale] (YYYY-MM-DD) [ACTIVE|SUPERSEDED]"
|
|
172
212
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
213
|
+
log "--- Full prompt being passed to claude -p ---"
|
|
214
|
+
log "$PROMPT"
|
|
215
|
+
log "--- End prompt ---"
|
|
176
216
|
|
|
177
|
-
#
|
|
178
|
-
TIMEOUT=120
|
|
217
|
+
# Run fresh claude -p (no --resume, no conversation confusion)
|
|
218
|
+
TIMEOUT=120
|
|
179
219
|
|
|
180
|
-
DEVFLOW_BG_UPDATER=1
|
|
181
|
-
--resume "$SESSION_ID" \
|
|
220
|
+
DEVFLOW_BG_UPDATER=1 "$CLAUDE_BIN" -p \
|
|
182
221
|
--model haiku \
|
|
183
|
-
--
|
|
184
|
-
--allowedTools \
|
|
185
|
-
"Read($CWD/.memory/WORKING-MEMORY.md)" \
|
|
186
|
-
"Read($CWD/.memory/PROJECT-PATTERNS.md)" \
|
|
187
|
-
"Write($CWD/.memory/WORKING-MEMORY.md)" \
|
|
188
|
-
"Write($CWD/.memory/PROJECT-PATTERNS.md)" \
|
|
189
|
-
"Bash(git status:*)" \
|
|
190
|
-
"Bash(git log:*)" \
|
|
191
|
-
"Bash(git diff:*)" \
|
|
192
|
-
"Bash(git branch:*)" \
|
|
193
|
-
--no-session-persistence \
|
|
222
|
+
--dangerously-skip-permissions \
|
|
194
223
|
--output-format text \
|
|
195
|
-
"$
|
|
224
|
+
"$PROMPT" \
|
|
196
225
|
>> "$LOG_FILE" 2>&1 &
|
|
197
226
|
CLAUDE_PID=$!
|
|
198
227
|
|