aiwcli 0.12.7 → 0.13.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/dist/commands/clean.d.ts +7 -0
- package/dist/commands/clean.js +17 -8
- package/dist/commands/clear.d.ts +85 -0
- package/dist/commands/clear.js +455 -347
- package/dist/commands/init/index.d.ts +15 -0
- package/dist/commands/init/index.js +79 -38
- package/dist/lib/gitignore-manager.js +12 -13
- package/dist/lib/settings-hierarchy.d.ts +13 -1
- package/dist/lib/settings-hierarchy.js +1 -1
- package/dist/lib/template-linter.d.ts +4 -0
- package/dist/lib/template-linter.js +1 -1
- package/dist/lib/tty-detection.d.ts +1 -0
- package/dist/lib/tty-detection.js +1 -0
- package/dist/templates/CLAUDE.md +27 -0
- package/dist/templates/_shared/.claude/settings.json +7 -7
- package/dist/templates/_shared/.claude/{commands/handoff.md → skills/handoff/SKILL.md} +4 -3
- package/dist/templates/_shared/.claude/{commands/handoff-resume.md → skills/handoff-resume/SKILL.md} +3 -2
- package/dist/templates/_shared/.claude/skills/meta-plan/SKILL.md +43 -0
- package/dist/templates/_shared/.codex/workflows/handoff.md +1 -1
- package/dist/templates/_shared/.codex/workflows/meta-plan.md +347 -0
- package/dist/templates/_shared/.windsurf/workflows/handoff.md +1 -1
- package/dist/templates/_shared/.windsurf/workflows/meta-plan.md +347 -0
- package/dist/templates/_shared/hooks-ts/lint_after_edit.ts +59 -0
- package/dist/templates/_shared/hooks-ts/session_end.ts +11 -10
- package/dist/templates/_shared/hooks-ts/session_start.ts +15 -12
- package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +12 -12
- package/dist/templates/_shared/lib-ts/CLAUDE.md +3 -3
- package/dist/templates/_shared/lib-ts/base/constants.ts +324 -306
- package/dist/templates/_shared/lib-ts/base/hook-utils.ts +26 -7
- package/dist/templates/_shared/lib-ts/base/inference.ts +19 -19
- package/dist/templates/_shared/lib-ts/base/lint-dispatch.ts +287 -0
- package/dist/templates/_shared/lib-ts/base/state-io.ts +4 -3
- package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +3 -3
- package/dist/templates/_shared/lib-ts/context/CLAUDE.md +134 -0
- package/dist/templates/_shared/lib-ts/context/context-formatter.ts +16 -15
- package/dist/templates/_shared/lib-ts/context/context-selector.ts +16 -16
- package/dist/templates/_shared/lib-ts/context/context-store.ts +15 -14
- package/dist/templates/_shared/lib-ts/context/plan-manager.ts +2 -2
- package/dist/templates/_shared/scripts/resolve-run.ts +61 -0
- package/dist/templates/_shared/scripts/resolve_context.ts +1 -1
- package/dist/templates/_shared/scripts/status_line.ts +100 -94
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/CLAUDE.md +433 -421
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/lib/document-generator.ts +5 -4
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/lib/handoff-reader.ts +2 -1
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/scripts/resume_handoff.ts +6 -6
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/scripts/save_handoff.ts +16 -17
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/workflows/handoff-resume.md +2 -2
- package/dist/templates/_shared/{handoff-system → skills/handoff-system}/workflows/handoff.md +3 -3
- package/dist/templates/_shared/skills/meta-plan/CLAUDE.md +44 -0
- package/dist/templates/_shared/skills/meta-plan/workflows/meta-plan.md +347 -0
- package/dist/templates/cc-native/.claude/commands/cc-native/specdev.md +1 -1
- package/dist/templates/cc-native/.claude/settings.json +86 -57
- package/dist/templates/cc-native/_cc-native/artifacts/CLAUDE.md +64 -0
- package/dist/templates/cc-native/_cc-native/{lib-ts/artifacts → artifacts/lib}/format.ts +599 -597
- package/dist/templates/cc-native/_cc-native/{lib-ts/artifacts → artifacts/lib}/index.ts +26 -26
- package/dist/templates/cc-native/_cc-native/{lib-ts/artifacts → artifacts/lib}/tracker.ts +107 -106
- package/dist/templates/cc-native/_cc-native/{lib-ts/artifacts → artifacts/lib}/write.ts +119 -118
- package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +237 -247
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +76 -74
- package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +76 -0
- package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +163 -156
- package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +15 -16
- package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +116 -116
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +3 -3
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +16 -12
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +2 -3
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +31 -31
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +7 -6
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +9 -7
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +17 -14
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +41 -37
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +43 -33
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +20 -20
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +9 -8
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +4 -3
- package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +9 -10
- package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +20 -19
- package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +329 -329
- package/dist/templates/cc-native/_cc-native/plan-review/CLAUDE.md +149 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/CLAUDE.md +143 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/PLAN-ORCHESTRATOR.md +213 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-questions/PLAN-QUESTIONER.md +70 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-EVOLUTION.md +62 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-PATTERNS.md +61 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-STRUCTURE.md +62 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ASSUMPTION-TRACER.md +56 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CLARITY-AUDITOR.md +53 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-FEASIBILITY.md +66 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-GAPS.md +70 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-ORDERING.md +62 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CONSTRAINT-VALIDATOR.md +72 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-ADR-VALIDATOR.md +61 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-SCALE-MATCHER.md +64 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DEVILS-ADVOCATE.md +56 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DOCUMENTATION-PHILOSOPHY.md +86 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HANDOFF-READINESS.md +59 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HIDDEN-COMPLEXITY.md +58 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/INCREMENTAL-DELIVERY.md +66 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-DEPENDENCY.md +62 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-FMEA.md +66 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-PREMORTEM.md +71 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-REVERSIBILITY.md +74 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SCOPE-BOUNDARY.md +77 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SIMPLICITY-GUARDIAN.md +62 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SKEPTIC.md +68 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-BEHAVIOR-AUDITOR.md +61 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-CHARACTERIZATION.md +71 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-FIRST-VALIDATOR.md +61 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-PYRAMID-ANALYZER.md +61 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-COSTS.md +67 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-STAKEHOLDERS.md +65 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-COVERAGE.md +74 -0
- package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-STRENGTH.md +69 -0
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/agent-selection.ts +162 -163
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/corroboration.ts +119 -119
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/graduation.ts +132 -132
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/orchestrator.ts +70 -70
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/output-builder.ts +121 -130
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/plan-questions.ts +101 -102
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/review-pipeline.ts +507 -511
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/agent.ts +73 -74
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/base/base-agent.ts +217 -217
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/index.ts +12 -12
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/providers/claude-agent.ts +66 -66
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/providers/codex-agent.ts +185 -185
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/providers/gemini-agent.ts +39 -39
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/providers/orchestrator-claude-agent.ts +196 -196
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/schemas.ts +201 -201
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/reviewers/types.ts +23 -23
- package/dist/templates/cc-native/_cc-native/{lib-ts → plan-review/lib}/verdict.ts +72 -72
- package/dist/templates/cc-native/_cc-native/{workflows → plan-review/workflows}/specdev.md +9 -9
- package/oclif.manifest.json +1 -1
- package/package.json +6 -5
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +0 -21
|
@@ -1,421 +1,433 @@
|
|
|
1
|
-
# Handoff System
|
|
2
|
-
|
|
3
|
-
Comprehensive specification for the handoff workflow system.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
- **Purpose:** Capture session state for asynchronous handoff to next session
|
|
8
|
-
- **Philosophy:** Structured sections (dead-ends, pending, decisions, etc.) + executable restoration
|
|
9
|
-
- **When to use:** End of work session when context needs preservation
|
|
10
|
-
- **Runtime location:** `_output/contexts/{context_id}/handoffs/{YYYY-MM-DD-HHMM}/`
|
|
11
|
-
|
|
12
|
-
## Directory Structure
|
|
13
|
-
|
|
14
|
-
```
|
|
15
|
-
handoff-system/
|
|
16
|
-
├── CLAUDE.md # This file — comprehensive spec
|
|
17
|
-
├── lib/ # Reusable modules
|
|
18
|
-
│ ├── handoff-reader.ts # Read and parse handoff sections
|
|
19
|
-
│ └── document-generator.ts # Generate handoff markdown (not currently imported)
|
|
20
|
-
├── scripts/ # CLI entry points
|
|
21
|
-
│ ├── save_handoff.ts # Create handoff from stdin markdown
|
|
22
|
-
│ └── resume_handoff.ts # Load handoff and format for restoration
|
|
23
|
-
└── workflows/ # Procedural documentation
|
|
24
|
-
├── handoff.md # Creation workflow
|
|
25
|
-
└── handoff-resume.md # Restoration workflow
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Data Model & Schema
|
|
29
|
-
|
|
30
|
-
### Handoff Folder Structure
|
|
31
|
-
|
|
32
|
-
Runtime location: `_output/contexts/{context_id}/handoffs/{YYYY-MM-DD-HHMM}/`
|
|
33
|
-
|
|
34
|
-
**Files created:**
|
|
35
|
-
- `index.md` — Entry point with frontmatter
|
|
36
|
-
- `completed-work.md` — What was accomplished
|
|
37
|
-
- `dead-ends.md` — Failed approaches to avoid
|
|
38
|
-
- `decisions.md` — Key decisions made
|
|
39
|
-
- `pending.md` — Incomplete work items
|
|
40
|
-
- `context.md` — Background context
|
|
41
|
-
- `plan.md` — Optional, copied from context if plan exists
|
|
42
|
-
|
|
43
|
-
### HandoffSections Interface
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
// From _shared/lib-ts/types.ts
|
|
47
|
-
interface HandoffSections {
|
|
48
|
-
index: string; // Entry point with frontmatter
|
|
49
|
-
deadEnds: string | null; // Failed approaches to avoid
|
|
50
|
-
pending: string | null; // Incomplete work items
|
|
51
|
-
plan: string | null; // Copy of plan file if exists
|
|
52
|
-
decisions: string | null; // Key decisions made
|
|
53
|
-
completedWork: string | null; // What was accomplished
|
|
54
|
-
context: string | null; // Background context
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
**Why inline interfaces:** Makes CLAUDE.md self-contained — agents don't jump between files.
|
|
59
|
-
|
|
60
|
-
### Section Markers
|
|
61
|
-
|
|
62
|
-
Content parsed via HTML comments: `<!-- SECTION: name -->`
|
|
63
|
-
|
|
64
|
-
**Valid section names:**
|
|
65
|
-
- `CONTEXT`
|
|
66
|
-
- `COMPLETED_WORK`
|
|
67
|
-
- `DEAD_ENDS`
|
|
68
|
-
- `DECISIONS`
|
|
69
|
-
- `PENDING`
|
|
70
|
-
- `PLAN`
|
|
71
|
-
|
|
72
|
-
**Critical:** Markers must be HTML comments, not markdown headings. Parser searches for `<!-- SECTION: -->` format.
|
|
73
|
-
|
|
74
|
-
### Frontmatter Schema
|
|
75
|
-
|
|
76
|
-
YAML frontmatter in index.md:
|
|
77
|
-
|
|
78
|
-
```yaml
|
|
79
|
-
---
|
|
80
|
-
title: Handoff - {project_name}
|
|
81
|
-
date: {ISO timestamp}
|
|
82
|
-
session_id: {Claude session ID}
|
|
83
|
-
project: {context directory name}
|
|
84
|
-
plan_document: {path to plan file if exists}
|
|
85
|
-
---
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
## Lifecycle & Hook Integration
|
|
89
|
-
|
|
90
|
-
### Creation Flow (save_handoff.ts script)
|
|
91
|
-
|
|
92
|
-
**Trigger:** `/handoff` command invokes script with stdin markdown
|
|
93
|
-
|
|
94
|
-
**Process:**
|
|
95
|
-
1. Parse frontmatter and section markers from stdin
|
|
96
|
-
2. Resolve context ID (5-tier resolution: `--context-id`, `--session-id`, frontmatter, `CLAUDE_SESSION_ID`, fallback to active)
|
|
97
|
-
3. Create timestamped folder: `_output/contexts/{context_id}/handoffs/{YYYY-MM-DD-HHMM}/`
|
|
98
|
-
4. Shard content into section files
|
|
99
|
-
5. Update state.json with handoff metadata
|
|
100
|
-
|
|
101
|
-
**State updates:**
|
|
102
|
-
- `handoff_path`: Set to `handoffs/{timestamp}/index.md` (relative to context folder)
|
|
103
|
-
- `work_consumed`: Set to `false` (enables staging)
|
|
104
|
-
- `next_artifact_type`: Set to `"handoff"` (explicit artifact tracking)
|
|
105
|
-
- **Latest-wins replacement:** If `plan_hash` exists, clear plan fields (`plan_path`, `plan_hash`, `plan_signature`)
|
|
106
|
-
|
|
107
|
-
**Context resolution tiers** (first match wins):
|
|
108
|
-
1. `--context-id` CLI arg
|
|
109
|
-
2. `--session-id` CLI arg (lookup via CLAUDE_SESSION_ID → context)
|
|
110
|
-
3. `session_id` in frontmatter (lookup via session → context)
|
|
111
|
-
4. `CLAUDE_SESSION_ID` env var (lookup via session → context)
|
|
112
|
-
5. Fallback: most recent active context
|
|
113
|
-
|
|
114
|
-
### Staging (session_end.ts hook)
|
|
115
|
-
|
|
116
|
-
**Trigger:** SessionEnd event
|
|
117
|
-
|
|
118
|
-
**Condition for staging:**
|
|
119
|
-
```typescript
|
|
120
|
-
if (state.handoff_path && !state.work_consumed) {
|
|
121
|
-
state.mode = "has_staged_work";
|
|
122
|
-
state.next_artifact_type = "handoff";
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
**Latest-wins detection:**
|
|
127
|
-
If `plan_hash` differs from `plan_hash_consumed`, new plan detected:
|
|
128
|
-
- Clear `handoff_path` (plan wins)
|
|
129
|
-
- Set `work_consumed = false`
|
|
130
|
-
- Set `next_artifact_type = "plan"`
|
|
131
|
-
|
|
132
|
-
**Unified staging mode:** `has_staged_work` replaces old `has_plan` and `has_handoff` modes (v0.13.0+).
|
|
133
|
-
|
|
134
|
-
### Restoration (session_start.ts hook)
|
|
135
|
-
|
|
136
|
-
**Trigger:** SessionStart event with `source = "clear"`
|
|
137
|
-
|
|
138
|
-
**Process:**
|
|
139
|
-
1. Find context with `mode = "has_staged_work"`
|
|
140
|
-
2. Dispatch by `next_artifact_type`:
|
|
141
|
-
- If `"handoff"`: call `formatHandoffContinuation(ctx)`
|
|
142
|
-
- If `"plan"`: inject plan content
|
|
143
|
-
3. Bind session to context
|
|
144
|
-
4. Transition `has_staged_work` → `active`
|
|
145
|
-
5. Set `work_consumed = true` (one-shot latch prevents re-staging)
|
|
146
|
-
|
|
147
|
-
**formatHandoffContinuation()** (from context-formatter.ts):
|
|
148
|
-
- Reads handoff sections via `readHandoffSections()`
|
|
149
|
-
- Assembles restoration context: dead-ends → pending → plan remaining → decisions → git delta → completed work
|
|
150
|
-
- Injects as system-reminder for Claude
|
|
151
|
-
|
|
152
|
-
### Fallback Matching (user_prompt_submit.ts hook)
|
|
153
|
-
|
|
154
|
-
**Trigger:** UserPromptSubmit when no staged work mode detected
|
|
155
|
-
|
|
156
|
-
**Process in determineContext():**
|
|
157
|
-
1. Filter contexts by `has_staged_work` mode
|
|
158
|
-
2. Separate by `determineArtifactType()`:
|
|
159
|
-
- Plan artifacts: check `plan_hash` and `plan_path`
|
|
160
|
-
- Handoff artifacts: check `handoff_path`
|
|
161
|
-
3. Try plan match first (content-based via plan hash)
|
|
162
|
-
4. Fall back to handoff match (first-match by recency)
|
|
163
|
-
5. Set `work_consumed = true` if match found
|
|
164
|
-
|
|
165
|
-
**determineArtifactType() utility:**
|
|
166
|
-
- Checks `next_artifact_type` field first (authoritative)
|
|
167
|
-
- Fallback: field detection (`plan_hash` + `plan_path` vs `handoff_path`)
|
|
168
|
-
- Logs warning if both plan and handoff fields exist (bug - violates latest-wins)
|
|
169
|
-
|
|
170
|
-
## Scripts
|
|
171
|
-
|
|
172
|
-
### save_handoff.ts
|
|
173
|
-
|
|
174
|
-
**Usage:**
|
|
175
|
-
```bash
|
|
176
|
-
bun .aiwcli/_shared/handoff-system/scripts/save_handoff.ts [--context-id ID] [--session-id SID] < handoff.md
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
**Stdin format:**
|
|
180
|
-
```markdown
|
|
181
|
-
---
|
|
182
|
-
title: Handoff - Project Name
|
|
183
|
-
session_id: abc123
|
|
184
|
-
---
|
|
185
|
-
|
|
186
|
-
# Handoff Document
|
|
187
|
-
|
|
188
|
-
<!-- SECTION: CONTEXT -->
|
|
189
|
-
Context details here...
|
|
190
|
-
|
|
191
|
-
<!-- SECTION: PENDING -->
|
|
192
|
-
Pending items...
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
**Output:**
|
|
196
|
-
- Creates folder: `_output/contexts/{context_id}/handoffs/{YYYY-MM-DD-HHMM}/`
|
|
197
|
-
- Shards to files: `index.md`, `pending.md`, `dead-ends.md`, etc.
|
|
198
|
-
- Updates `state.json`: `handoff_path`, `work_consumed=false`, `next_artifact_type="handoff"`
|
|
199
|
-
|
|
200
|
-
**Collision handling:**
|
|
201
|
-
If timestamp folder exists, appends `-2`, `-3`, etc.
|
|
202
|
-
|
|
203
|
-
**State updates (latest-wins):**
|
|
204
|
-
- Sets handoff fields
|
|
205
|
-
- **Clears plan fields if they exist** (`plan_path`, `plan_hash`, `plan_signature` → null)
|
|
206
|
-
|
|
207
|
-
### resume_handoff.ts
|
|
208
|
-
|
|
209
|
-
**Usage:**
|
|
210
|
-
```bash
|
|
211
|
-
# Auto-discover from current session
|
|
212
|
-
bun .aiwcli/_shared/handoff-system/scripts/resume_handoff.ts
|
|
213
|
-
|
|
214
|
-
# Explicit handoff path
|
|
215
|
-
bun .aiwcli/_shared/handoff-system/scripts/resume_handoff.ts path/to/handoff/index.md
|
|
216
|
-
|
|
217
|
-
# Explicit context
|
|
218
|
-
bun .aiwcli/_shared/handoff-system/scripts/resume_handoff.ts --context context-id
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
**Output format (to stdout):**
|
|
222
|
-
```markdown
|
|
223
|
-
# Handoff Restoration
|
|
224
|
-
|
|
225
|
-
## Dead Ends (Priority: Address First)
|
|
226
|
-
...
|
|
227
|
-
|
|
228
|
-
## Pending Items
|
|
229
|
-
...
|
|
230
|
-
|
|
231
|
-
## Plan Status
|
|
232
|
-
42% complete (5/12 tasks)
|
|
233
|
-
|
|
234
|
-
## Decisions Made
|
|
235
|
-
...
|
|
236
|
-
|
|
237
|
-
## Git Delta
|
|
238
|
-
Changed files since handoff...
|
|
239
|
-
|
|
240
|
-
## Completed Work
|
|
241
|
-
...
|
|
242
|
-
|
|
243
|
-
## Full Plan (Appendix)
|
|
244
|
-
...
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
**Features:**
|
|
248
|
-
- **Staleness warnings:** If handoff > 7 days old, warns in output
|
|
249
|
-
- **Plan progress:** Calculates % complete from plan anchors
|
|
250
|
-
- **Git delta:** Compares current git state to plan's git anchors
|
|
251
|
-
- **Priority ordering:** Dead-ends first, then pending, then context
|
|
252
|
-
|
|
253
|
-
**Auto-discovery:**
|
|
254
|
-
Uses `CLAUDE_SESSION_ID` env var → lookup context → find latest handoff in `handoffs/` folder.
|
|
255
|
-
|
|
256
|
-
## Library Modules
|
|
257
|
-
|
|
258
|
-
### handoff-reader.ts
|
|
259
|
-
|
|
260
|
-
**Location:** `_shared/handoff-system/lib/handoff-reader.ts`
|
|
261
|
-
|
|
262
|
-
**Exports:**
|
|
263
|
-
|
|
264
|
-
```typescript
|
|
265
|
-
// Find most recent handoff in context
|
|
266
|
-
function findLatestHandoff(contextPath: string): string | null
|
|
267
|
-
|
|
268
|
-
// Read and parse handoff sections
|
|
269
|
-
function readHandoffSections(handoffPath: string): HandoffSections
|
|
270
|
-
|
|
271
|
-
// Extract timestamp from handoff path
|
|
272
|
-
function getHandoffTimestamp(handoffPath: string): Date | null
|
|
273
|
-
|
|
274
|
-
// Get plan reference from handoff frontmatter
|
|
275
|
-
function getHandoffPlanReference(handoffPath: string): string | null
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
**Section mapping:**
|
|
279
|
-
```typescript
|
|
280
|
-
const SECTION_FILES = {
|
|
281
|
-
index: "index.md",
|
|
282
|
-
deadEnds: "dead-ends.md",
|
|
283
|
-
pending: "pending.md",
|
|
284
|
-
plan: "plan.md",
|
|
285
|
-
decisions: "decisions.md",
|
|
286
|
-
completedWork: "completed-work.md",
|
|
287
|
-
context: "context.md",
|
|
288
|
-
};
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
**Returns null for missing optional sections** (dead-ends, pending, etc.).
|
|
292
|
-
|
|
293
|
-
### document-generator.ts
|
|
294
|
-
|
|
295
|
-
**Location:** `_shared/handoff-system/lib/document-generator.ts`
|
|
296
|
-
|
|
297
|
-
**Exports:**
|
|
298
|
-
|
|
299
|
-
```typescript
|
|
300
|
-
// Generate complete handoff markdown with sections
|
|
301
|
-
function generateHandoffDocument(options: HandoffOptions): string
|
|
302
|
-
|
|
303
|
-
// Section builders
|
|
304
|
-
function buildContextSection(ctx: ContextState): string
|
|
305
|
-
function buildCompletedWorkSection(history: WorkHistory): string
|
|
306
|
-
function buildDeadEndsSection(deadEnds: DeadEnd[]): string
|
|
307
|
-
// ... (other section builders)
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
**Used by:** `/handoff` workflow to programmatically generate handoff content before piping to `save_handoff.ts`.
|
|
311
|
-
|
|
312
|
-
**Note:** Currently not imported by any files. Moved here for logical grouping and completeness.
|
|
313
|
-
|
|
314
|
-
##
|
|
315
|
-
|
|
316
|
-
**Thin pointer pattern:**
|
|
317
|
-
|
|
318
|
-
`.claude/
|
|
319
|
-
→ References `.aiwcli/_shared/handoff-system/workflows/handoff.md` (detailed procedural steps)
|
|
320
|
-
|
|
321
|
-
**Benefits:**
|
|
322
|
-
-
|
|
323
|
-
- Workflow files can expand without bloating command discovery
|
|
324
|
-
- Single source of truth for procedural details
|
|
325
|
-
|
|
326
|
-
**Example reference format:**
|
|
327
|
-
```markdown
|
|
328
|
-
See `.aiwcli/_shared/handoff-system/workflows/handoff.md` for complete process documentation.
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
## Testing
|
|
332
|
-
|
|
333
|
-
**Integration test:**
|
|
334
|
-
`_shared/lib-ts/__tests__/integration/handoff-lifecycle.test.ts`
|
|
335
|
-
|
|
336
|
-
**Coverage:**
|
|
337
|
-
- Creation: active + handoff → session_end → has_staged_work
|
|
338
|
-
- Restoration: /clear → session_start → active + work_consumed=true
|
|
339
|
-
- One-shot latch: subsequent session_end does NOT re-stage (work_consumed=true)
|
|
340
|
-
|
|
341
|
-
**Hook execution test:**
|
|
342
|
-
```bash
|
|
343
|
-
echo '{"hook_event_name":"SessionStart","session_id":"test","source":"clear"}' | \
|
|
344
|
-
bun .aiwcli/_shared/hooks-ts/session_start.ts
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
Expected: No import errors, clean execution.
|
|
348
|
-
|
|
349
|
-
## Migration Notes (v0.13.0+)
|
|
350
|
-
|
|
351
|
-
**Unified lifecycle:**
|
|
352
|
-
- Old modes `has_plan` and `has_handoff` → unified `has_staged_work`
|
|
353
|
-
- Old flags `plan_consumed` and `handoff_consumed` → unified `work_consumed`
|
|
354
|
-
- New field `next_artifact_type` (`"plan" | "handoff" | null`) for explicit artifact tracking
|
|
355
|
-
|
|
356
|
-
**Migration handled by migrateConsumedFlags()** in `state-io.ts`:
|
|
357
|
-
- Runs on every `state.json` read
|
|
358
|
-
- Transparently converts old modes to new structure
|
|
359
|
-
- Idempotent (safe to run multiple times)
|
|
360
|
-
|
|
361
|
-
**Latest-wins principle:**
|
|
362
|
-
- Only ONE artifact staged at a time
|
|
363
|
-
- New handoff clears plan fields
|
|
364
|
-
- New plan clears handoff_path
|
|
365
|
-
- Most recent creation wins
|
|
366
|
-
|
|
367
|
-
**Work consumed as one-shot latch:**
|
|
368
|
-
- Set to `true` when `has_staged_work` → `active` transition occurs
|
|
369
|
-
- Prevents `session_end` from re-staging same artifact
|
|
370
|
-
- Reset to `false` when new artifact created
|
|
371
|
-
|
|
372
|
-
##
|
|
373
|
-
|
|
374
|
-
**
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
-
|
|
382
|
-
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
**
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
**
|
|
409
|
-
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
-
|
|
1
|
+
# Handoff System
|
|
2
|
+
|
|
3
|
+
Comprehensive specification for the handoff workflow system.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
- **Purpose:** Capture session state for asynchronous handoff to next session
|
|
8
|
+
- **Philosophy:** Structured sections (dead-ends, pending, decisions, etc.) + executable restoration
|
|
9
|
+
- **When to use:** End of work session when context needs preservation
|
|
10
|
+
- **Runtime location:** `_output/contexts/{context_id}/handoffs/{YYYY-MM-DD-HHMM}/`
|
|
11
|
+
|
|
12
|
+
## Directory Structure
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
handoff-system/
|
|
16
|
+
├── CLAUDE.md # This file — comprehensive spec
|
|
17
|
+
├── lib/ # Reusable modules
|
|
18
|
+
│ ├── handoff-reader.ts # Read and parse handoff sections
|
|
19
|
+
│ └── document-generator.ts # Generate handoff markdown (not currently imported)
|
|
20
|
+
├── scripts/ # CLI entry points
|
|
21
|
+
│ ├── save_handoff.ts # Create handoff from stdin markdown
|
|
22
|
+
│ └── resume_handoff.ts # Load handoff and format for restoration
|
|
23
|
+
└── workflows/ # Procedural documentation
|
|
24
|
+
├── handoff.md # Creation workflow
|
|
25
|
+
└── handoff-resume.md # Restoration workflow
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Data Model & Schema
|
|
29
|
+
|
|
30
|
+
### Handoff Folder Structure
|
|
31
|
+
|
|
32
|
+
Runtime location: `_output/contexts/{context_id}/handoffs/{YYYY-MM-DD-HHMM}/`
|
|
33
|
+
|
|
34
|
+
**Files created:**
|
|
35
|
+
- `index.md` — Entry point with frontmatter
|
|
36
|
+
- `completed-work.md` — What was accomplished
|
|
37
|
+
- `dead-ends.md` — Failed approaches to avoid
|
|
38
|
+
- `decisions.md` — Key decisions made
|
|
39
|
+
- `pending.md` — Incomplete work items
|
|
40
|
+
- `context.md` — Background context
|
|
41
|
+
- `plan.md` — Optional, copied from context if plan exists
|
|
42
|
+
|
|
43
|
+
### HandoffSections Interface
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// From _shared/lib-ts/types.ts
|
|
47
|
+
interface HandoffSections {
|
|
48
|
+
index: string; // Entry point with frontmatter
|
|
49
|
+
deadEnds: string | null; // Failed approaches to avoid
|
|
50
|
+
pending: string | null; // Incomplete work items
|
|
51
|
+
plan: string | null; // Copy of plan file if exists
|
|
52
|
+
decisions: string | null; // Key decisions made
|
|
53
|
+
completedWork: string | null; // What was accomplished
|
|
54
|
+
context: string | null; // Background context
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Why inline interfaces:** Makes CLAUDE.md self-contained — agents don't jump between files.
|
|
59
|
+
|
|
60
|
+
### Section Markers
|
|
61
|
+
|
|
62
|
+
Content parsed via HTML comments: `<!-- SECTION: name -->`
|
|
63
|
+
|
|
64
|
+
**Valid section names:**
|
|
65
|
+
- `CONTEXT`
|
|
66
|
+
- `COMPLETED_WORK`
|
|
67
|
+
- `DEAD_ENDS`
|
|
68
|
+
- `DECISIONS`
|
|
69
|
+
- `PENDING`
|
|
70
|
+
- `PLAN`
|
|
71
|
+
|
|
72
|
+
**Critical:** Markers must be HTML comments, not markdown headings. Parser searches for `<!-- SECTION: -->` format.
|
|
73
|
+
|
|
74
|
+
### Frontmatter Schema
|
|
75
|
+
|
|
76
|
+
YAML frontmatter in index.md:
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
---
|
|
80
|
+
title: Handoff - {project_name}
|
|
81
|
+
date: {ISO timestamp}
|
|
82
|
+
session_id: {Claude session ID}
|
|
83
|
+
project: {context directory name}
|
|
84
|
+
plan_document: {path to plan file if exists}
|
|
85
|
+
---
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Lifecycle & Hook Integration
|
|
89
|
+
|
|
90
|
+
### Creation Flow (save_handoff.ts script)
|
|
91
|
+
|
|
92
|
+
**Trigger:** `/handoff` command invokes script with stdin markdown
|
|
93
|
+
|
|
94
|
+
**Process:**
|
|
95
|
+
1. Parse frontmatter and section markers from stdin
|
|
96
|
+
2. Resolve context ID (5-tier resolution: `--context-id`, `--session-id`, frontmatter, `CLAUDE_SESSION_ID`, fallback to active)
|
|
97
|
+
3. Create timestamped folder: `_output/contexts/{context_id}/handoffs/{YYYY-MM-DD-HHMM}/`
|
|
98
|
+
4. Shard content into section files
|
|
99
|
+
5. Update state.json with handoff metadata
|
|
100
|
+
|
|
101
|
+
**State updates:**
|
|
102
|
+
- `handoff_path`: Set to `handoffs/{timestamp}/index.md` (relative to context folder)
|
|
103
|
+
- `work_consumed`: Set to `false` (enables staging)
|
|
104
|
+
- `next_artifact_type`: Set to `"handoff"` (explicit artifact tracking)
|
|
105
|
+
- **Latest-wins replacement:** If `plan_hash` exists, clear plan fields (`plan_path`, `plan_hash`, `plan_signature`)
|
|
106
|
+
|
|
107
|
+
**Context resolution tiers** (first match wins):
|
|
108
|
+
1. `--context-id` CLI arg
|
|
109
|
+
2. `--session-id` CLI arg (lookup via CLAUDE_SESSION_ID → context)
|
|
110
|
+
3. `session_id` in frontmatter (lookup via session → context)
|
|
111
|
+
4. `CLAUDE_SESSION_ID` env var (lookup via session → context)
|
|
112
|
+
5. Fallback: most recent active context
|
|
113
|
+
|
|
114
|
+
### Staging (session_end.ts hook)
|
|
115
|
+
|
|
116
|
+
**Trigger:** SessionEnd event
|
|
117
|
+
|
|
118
|
+
**Condition for staging:**
|
|
119
|
+
```typescript
|
|
120
|
+
if (state.handoff_path && !state.work_consumed) {
|
|
121
|
+
state.mode = "has_staged_work";
|
|
122
|
+
state.next_artifact_type = "handoff";
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Latest-wins detection:**
|
|
127
|
+
If `plan_hash` differs from `plan_hash_consumed`, new plan detected:
|
|
128
|
+
- Clear `handoff_path` (plan wins)
|
|
129
|
+
- Set `work_consumed = false`
|
|
130
|
+
- Set `next_artifact_type = "plan"`
|
|
131
|
+
|
|
132
|
+
**Unified staging mode:** `has_staged_work` replaces old `has_plan` and `has_handoff` modes (v0.13.0+).
|
|
133
|
+
|
|
134
|
+
### Restoration (session_start.ts hook)
|
|
135
|
+
|
|
136
|
+
**Trigger:** SessionStart event with `source = "clear"`
|
|
137
|
+
|
|
138
|
+
**Process:**
|
|
139
|
+
1. Find context with `mode = "has_staged_work"`
|
|
140
|
+
2. Dispatch by `next_artifact_type`:
|
|
141
|
+
- If `"handoff"`: call `formatHandoffContinuation(ctx)`
|
|
142
|
+
- If `"plan"`: inject plan content
|
|
143
|
+
3. Bind session to context
|
|
144
|
+
4. Transition `has_staged_work` → `active`
|
|
145
|
+
5. Set `work_consumed = true` (one-shot latch prevents re-staging)
|
|
146
|
+
|
|
147
|
+
**formatHandoffContinuation()** (from context-formatter.ts):
|
|
148
|
+
- Reads handoff sections via `readHandoffSections()`
|
|
149
|
+
- Assembles restoration context: dead-ends → pending → plan remaining → decisions → git delta → completed work
|
|
150
|
+
- Injects as system-reminder for Claude
|
|
151
|
+
|
|
152
|
+
### Fallback Matching (user_prompt_submit.ts hook)
|
|
153
|
+
|
|
154
|
+
**Trigger:** UserPromptSubmit when no staged work mode detected
|
|
155
|
+
|
|
156
|
+
**Process in determineContext():**
|
|
157
|
+
1. Filter contexts by `has_staged_work` mode
|
|
158
|
+
2. Separate by `determineArtifactType()`:
|
|
159
|
+
- Plan artifacts: check `plan_hash` and `plan_path`
|
|
160
|
+
- Handoff artifacts: check `handoff_path`
|
|
161
|
+
3. Try plan match first (content-based via plan hash)
|
|
162
|
+
4. Fall back to handoff match (first-match by recency)
|
|
163
|
+
5. Set `work_consumed = true` if match found
|
|
164
|
+
|
|
165
|
+
**determineArtifactType() utility:**
|
|
166
|
+
- Checks `next_artifact_type` field first (authoritative)
|
|
167
|
+
- Fallback: field detection (`plan_hash` + `plan_path` vs `handoff_path`)
|
|
168
|
+
- Logs warning if both plan and handoff fields exist (bug - violates latest-wins)
|
|
169
|
+
|
|
170
|
+
## Scripts
|
|
171
|
+
|
|
172
|
+
### save_handoff.ts
|
|
173
|
+
|
|
174
|
+
**Usage:**
|
|
175
|
+
```bash
|
|
176
|
+
bun .aiwcli/_shared/skills/handoff-system/scripts/save_handoff.ts [--context-id ID] [--session-id SID] < handoff.md
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Stdin format:**
|
|
180
|
+
```markdown
|
|
181
|
+
---
|
|
182
|
+
title: Handoff - Project Name
|
|
183
|
+
session_id: abc123
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
# Handoff Document
|
|
187
|
+
|
|
188
|
+
<!-- SECTION: CONTEXT -->
|
|
189
|
+
Context details here...
|
|
190
|
+
|
|
191
|
+
<!-- SECTION: PENDING -->
|
|
192
|
+
Pending items...
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Output:**
|
|
196
|
+
- Creates folder: `_output/contexts/{context_id}/handoffs/{YYYY-MM-DD-HHMM}/`
|
|
197
|
+
- Shards to files: `index.md`, `pending.md`, `dead-ends.md`, etc.
|
|
198
|
+
- Updates `state.json`: `handoff_path`, `work_consumed=false`, `next_artifact_type="handoff"`
|
|
199
|
+
|
|
200
|
+
**Collision handling:**
|
|
201
|
+
If timestamp folder exists, appends `-2`, `-3`, etc.
|
|
202
|
+
|
|
203
|
+
**State updates (latest-wins):**
|
|
204
|
+
- Sets handoff fields
|
|
205
|
+
- **Clears plan fields if they exist** (`plan_path`, `plan_hash`, `plan_signature` → null)
|
|
206
|
+
|
|
207
|
+
### resume_handoff.ts
|
|
208
|
+
|
|
209
|
+
**Usage:**
|
|
210
|
+
```bash
|
|
211
|
+
# Auto-discover from current session
|
|
212
|
+
bun .aiwcli/_shared/skills/handoff-system/scripts/resume_handoff.ts
|
|
213
|
+
|
|
214
|
+
# Explicit handoff path
|
|
215
|
+
bun .aiwcli/_shared/skills/handoff-system/scripts/resume_handoff.ts path/to/handoff/index.md
|
|
216
|
+
|
|
217
|
+
# Explicit context
|
|
218
|
+
bun .aiwcli/_shared/skills/handoff-system/scripts/resume_handoff.ts --context context-id
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
**Output format (to stdout):**
|
|
222
|
+
```markdown
|
|
223
|
+
# Handoff Restoration
|
|
224
|
+
|
|
225
|
+
## Dead Ends (Priority: Address First)
|
|
226
|
+
...
|
|
227
|
+
|
|
228
|
+
## Pending Items
|
|
229
|
+
...
|
|
230
|
+
|
|
231
|
+
## Plan Status
|
|
232
|
+
42% complete (5/12 tasks)
|
|
233
|
+
|
|
234
|
+
## Decisions Made
|
|
235
|
+
...
|
|
236
|
+
|
|
237
|
+
## Git Delta
|
|
238
|
+
Changed files since handoff...
|
|
239
|
+
|
|
240
|
+
## Completed Work
|
|
241
|
+
...
|
|
242
|
+
|
|
243
|
+
## Full Plan (Appendix)
|
|
244
|
+
...
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Features:**
|
|
248
|
+
- **Staleness warnings:** If handoff > 7 days old, warns in output
|
|
249
|
+
- **Plan progress:** Calculates % complete from plan anchors
|
|
250
|
+
- **Git delta:** Compares current git state to plan's git anchors
|
|
251
|
+
- **Priority ordering:** Dead-ends first, then pending, then context
|
|
252
|
+
|
|
253
|
+
**Auto-discovery:**
|
|
254
|
+
Uses `CLAUDE_SESSION_ID` env var → lookup context → find latest handoff in `handoffs/` folder.
|
|
255
|
+
|
|
256
|
+
## Library Modules
|
|
257
|
+
|
|
258
|
+
### handoff-reader.ts
|
|
259
|
+
|
|
260
|
+
**Location:** `_shared/skills/handoff-system/lib/handoff-reader.ts`
|
|
261
|
+
|
|
262
|
+
**Exports:**
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
// Find most recent handoff in context
|
|
266
|
+
function findLatestHandoff(contextPath: string): string | null
|
|
267
|
+
|
|
268
|
+
// Read and parse handoff sections
|
|
269
|
+
function readHandoffSections(handoffPath: string): HandoffSections
|
|
270
|
+
|
|
271
|
+
// Extract timestamp from handoff path
|
|
272
|
+
function getHandoffTimestamp(handoffPath: string): Date | null
|
|
273
|
+
|
|
274
|
+
// Get plan reference from handoff frontmatter
|
|
275
|
+
function getHandoffPlanReference(handoffPath: string): string | null
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Section mapping:**
|
|
279
|
+
```typescript
|
|
280
|
+
const SECTION_FILES = {
|
|
281
|
+
index: "index.md",
|
|
282
|
+
deadEnds: "dead-ends.md",
|
|
283
|
+
pending: "pending.md",
|
|
284
|
+
plan: "plan.md",
|
|
285
|
+
decisions: "decisions.md",
|
|
286
|
+
completedWork: "completed-work.md",
|
|
287
|
+
context: "context.md",
|
|
288
|
+
};
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
**Returns null for missing optional sections** (dead-ends, pending, etc.).
|
|
292
|
+
|
|
293
|
+
### document-generator.ts
|
|
294
|
+
|
|
295
|
+
**Location:** `_shared/skills/handoff-system/lib/document-generator.ts`
|
|
296
|
+
|
|
297
|
+
**Exports:**
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
// Generate complete handoff markdown with sections
|
|
301
|
+
function generateHandoffDocument(options: HandoffOptions): string
|
|
302
|
+
|
|
303
|
+
// Section builders
|
|
304
|
+
function buildContextSection(ctx: ContextState): string
|
|
305
|
+
function buildCompletedWorkSection(history: WorkHistory): string
|
|
306
|
+
function buildDeadEndsSection(deadEnds: DeadEnd[]): string
|
|
307
|
+
// ... (other section builders)
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
**Used by:** `/handoff` workflow to programmatically generate handoff content before piping to `save_handoff.ts`.
|
|
311
|
+
|
|
312
|
+
**Note:** Currently not imported by any files. Moved here for logical grouping and completeness.
|
|
313
|
+
|
|
314
|
+
## Skill Integration
|
|
315
|
+
|
|
316
|
+
**Thin pointer pattern:**
|
|
317
|
+
|
|
318
|
+
`.claude/skills/handoff/SKILL.md` (user-facing, discoverable via `/`, `user-invocable: true`)
|
|
319
|
+
→ References `.aiwcli/_shared/skills/handoff-system/workflows/handoff.md` (detailed procedural steps)
|
|
320
|
+
|
|
321
|
+
**Benefits:**
|
|
322
|
+
- Skill files stay concise (easy to scan in `/` menu)
|
|
323
|
+
- Workflow files can expand without bloating command discovery
|
|
324
|
+
- Single source of truth for procedural details
|
|
325
|
+
|
|
326
|
+
**Example reference format:**
|
|
327
|
+
```markdown
|
|
328
|
+
See `.aiwcli/_shared/skills/handoff-system/workflows/handoff.md` for complete process documentation.
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## Testing
|
|
332
|
+
|
|
333
|
+
**Integration test:**
|
|
334
|
+
`_shared/lib-ts/__tests__/integration/handoff-lifecycle.test.ts`
|
|
335
|
+
|
|
336
|
+
**Coverage:**
|
|
337
|
+
- Creation: active + handoff → session_end → has_staged_work
|
|
338
|
+
- Restoration: /clear → session_start → active + work_consumed=true
|
|
339
|
+
- One-shot latch: subsequent session_end does NOT re-stage (work_consumed=true)
|
|
340
|
+
|
|
341
|
+
**Hook execution test:**
|
|
342
|
+
```bash
|
|
343
|
+
echo '{"hook_event_name":"SessionStart","session_id":"test","source":"clear"}' | \
|
|
344
|
+
bun .aiwcli/_shared/hooks-ts/session_start.ts
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Expected: No import errors, clean execution.
|
|
348
|
+
|
|
349
|
+
## Migration Notes (v0.13.0+)
|
|
350
|
+
|
|
351
|
+
**Unified lifecycle:**
|
|
352
|
+
- Old modes `has_plan` and `has_handoff` → unified `has_staged_work`
|
|
353
|
+
- Old flags `plan_consumed` and `handoff_consumed` → unified `work_consumed`
|
|
354
|
+
- New field `next_artifact_type` (`"plan" | "handoff" | null`) for explicit artifact tracking
|
|
355
|
+
|
|
356
|
+
**Migration handled by migrateConsumedFlags()** in `state-io.ts`:
|
|
357
|
+
- Runs on every `state.json` read
|
|
358
|
+
- Transparently converts old modes to new structure
|
|
359
|
+
- Idempotent (safe to run multiple times)
|
|
360
|
+
|
|
361
|
+
**Latest-wins principle:**
|
|
362
|
+
- Only ONE artifact staged at a time
|
|
363
|
+
- New handoff clears plan fields
|
|
364
|
+
- New plan clears handoff_path
|
|
365
|
+
- Most recent creation wins
|
|
366
|
+
|
|
367
|
+
**Work consumed as one-shot latch:**
|
|
368
|
+
- Set to `true` when `has_staged_work` → `active` transition occurs
|
|
369
|
+
- Prevents `session_end` from re-staging same artifact
|
|
370
|
+
- Reset to `false` when new artifact created
|
|
371
|
+
|
|
372
|
+
## Plan-Specific Behaviors
|
|
373
|
+
|
|
374
|
+
**Critical: Auto-paste bypasses hooks.** After ExitPlanMode "clear context", Claude Code runs `/clear` and auto-pastes the plan content. This auto-paste is an internal mechanism that does NOT trigger UserPromptSubmit. The `session_start.ts` handler for `source=clear` bridges this gap.
|
|
375
|
+
|
|
376
|
+
**One plan per session assumption:** Plan review iteration state resets across sessions but NOT within a session. When a plan is rejected by reviewers and the user creates a new plan in the same session, the iteration state (agent graduation, pass streaks) persists. This allows the review framework to work correctly: rejection within a session means "fix and retry," not "start completely fresh." Only when starting a new planning session (new session ID) does iteration state reset to allow full fresh review.
|
|
377
|
+
|
|
378
|
+
**Rejection handling:** `archive_plan` archives the file on PermissionRequest (before accept/reject decision). If rejected, the archive exists but `session_end`'s fallback may assign plan_hash. This is acceptable — rejected plans with hash set don't cause harm because plan matching in context_selector requires content match.
|
|
379
|
+
|
|
380
|
+
**Two restore paths:**
|
|
381
|
+
- **source=clear** (plan/handoff acceptance): Plan auto-pasted by Claude Code (plans only). Hook injects task/git context and handoff content (dispatch by `next_artifact_type`).
|
|
382
|
+
- **source=compact** (auto-compaction): Plan NOT auto-pasted. Hook inlines plan content via `buildRestoreSections(inline_plan=True)`.
|
|
383
|
+
|
|
384
|
+
## Architecture Decisions
|
|
385
|
+
|
|
386
|
+
**Why folder sharding (not single file)?**
|
|
387
|
+
- Enables selective loading (resume script loads only needed sections)
|
|
388
|
+
- Allows future extensions (e.g., attachments, screenshots)
|
|
389
|
+
- Chronological discovery via timestamp folders
|
|
390
|
+
|
|
391
|
+
**Why section markers (not frontmatter)?**
|
|
392
|
+
- Flexible content generation (Claude outputs sections in natural flow)
|
|
393
|
+
- No strict ordering required (script extracts by marker)
|
|
394
|
+
- Easy to extend (add new sections without schema version bump)
|
|
395
|
+
|
|
396
|
+
**Why latest-wins (not dual artifact tracking)?**
|
|
397
|
+
- Simplifies state machine (one artifact, one mode transition)
|
|
398
|
+
- Prevents ambiguity (which artifact to restore?)
|
|
399
|
+
- Matches user mental model (most recent work is relevant)
|
|
400
|
+
|
|
401
|
+
**Why unified work_consumed flag?**
|
|
402
|
+
- Prevents infinite re-staging loop
|
|
403
|
+
- Simpler than per-artifact flags (plan_consumed, handoff_consumed)
|
|
404
|
+
- One-shot latch pattern is well-understood
|
|
405
|
+
|
|
406
|
+
## Gotchas
|
|
407
|
+
|
|
408
|
+
**Template sync is mandatory:**
|
|
409
|
+
Both `.aiwcli/_shared/skills/handoff-system/` (working copy) and `packages/cli/src/templates/_shared/skills/handoff-system/` (template source) must stay in sync per CLAUDE.md template sync rules.
|
|
410
|
+
|
|
411
|
+
**Import paths after move:**
|
|
412
|
+
- From `scripts/resume_handoff.ts` → `lib/handoff-reader.ts`: `../lib/handoff-reader.js`
|
|
413
|
+
- From `lib/handoff-reader.ts` → `lib-ts/base/constants.ts`: `../../lib-ts/base/constants.js`
|
|
414
|
+
|
|
415
|
+
**Hooks don't import handoff-reader:**
|
|
416
|
+
- `session_start.ts` uses `formatHandoffContinuation()` from `context-formatter.ts`
|
|
417
|
+
- `context-formatter.ts` reads `ctx.handoff_path` directly
|
|
418
|
+
- No direct handoff-reader dependency in hooks
|
|
419
|
+
|
|
420
|
+
**Command file script paths are absolute:**
|
|
421
|
+
- Reference from project root: `.aiwcli/_shared/skills/handoff-system/scripts/save_handoff.ts`
|
|
422
|
+
- NOT relative to command file location
|
|
423
|
+
|
|
424
|
+
**Section markers must be HTML comments:**
|
|
425
|
+
```markdown
|
|
426
|
+
<!-- SECTION: PENDING --> ✅ Correct
|
|
427
|
+
# SECTION: PENDING ❌ Incorrect (parsed as heading, not marker)
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
**Windsurf and Codex workflows also reference scripts:**
|
|
431
|
+
When updating script paths, check:
|
|
432
|
+
- `packages/cli/src/templates/_shared/.windsurf/workflows/handoff.md`
|
|
433
|
+
- `packages/cli/src/templates/_shared/.codex/workflows/handoff.md`
|