aiwcli 0.12.2 → 0.12.6

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.
Files changed (46) hide show
  1. package/dist/templates/_shared/.claude/commands/handoff-resume.md +8 -60
  2. package/dist/templates/_shared/.claude/commands/handoff.md +6 -226
  3. package/dist/templates/_shared/.codex/workflows/handoff.md +1 -1
  4. package/dist/templates/_shared/.windsurf/workflows/handoff.md +1 -1
  5. package/dist/templates/_shared/handoff-system/CLAUDE.md +421 -0
  6. package/dist/templates/_shared/{lib-ts/handoff → handoff-system/lib}/document-generator.ts +10 -11
  7. package/dist/templates/_shared/{lib-ts/handoff → handoff-system/lib}/handoff-reader.ts +5 -6
  8. package/dist/templates/_shared/{scripts → handoff-system/scripts}/resume_handoff.ts +19 -16
  9. package/dist/templates/_shared/{scripts → handoff-system/scripts}/save_handoff.ts +153 -43
  10. package/dist/templates/_shared/handoff-system/workflows/handoff-resume.md +66 -0
  11. package/dist/templates/_shared/{workflows → handoff-system/workflows}/handoff.md +31 -9
  12. package/dist/templates/_shared/hooks-ts/session_end.ts +66 -48
  13. package/dist/templates/_shared/hooks-ts/session_start.ts +62 -47
  14. package/dist/templates/_shared/lib-ts/base/inference.ts +73 -24
  15. package/dist/templates/_shared/lib-ts/base/state-io.ts +88 -11
  16. package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +56 -0
  17. package/dist/templates/_shared/lib-ts/context/context-formatter.ts +8 -2
  18. package/dist/templates/_shared/lib-ts/context/context-selector.ts +79 -70
  19. package/dist/templates/_shared/lib-ts/context/context-store.ts +90 -85
  20. package/dist/templates/_shared/lib-ts/types.ts +71 -64
  21. package/dist/templates/_shared/scripts/resolve_context.ts +14 -5
  22. package/dist/templates/cc-native/.claude/commands/cc-native/rlm/ask.md +136 -0
  23. package/dist/templates/cc-native/.claude/commands/cc-native/rlm/index.md +21 -0
  24. package/dist/templates/cc-native/.claude/commands/cc-native/rlm/overview.md +56 -0
  25. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +4 -4
  26. package/dist/templates/cc-native/_cc-native/{plan-review.config.json → cc-native.config.json} +12 -0
  27. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +1 -1
  28. package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +3 -3
  29. package/dist/templates/cc-native/_cc-native/lib-ts/review-pipeline.ts +26 -4
  30. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/claude-agent.ts +1 -0
  31. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/orchestrator-claude-agent.ts +1 -0
  32. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/CLAUDE.md +480 -0
  33. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +287 -0
  34. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +148 -0
  35. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +54 -0
  36. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +58 -0
  37. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +208 -0
  38. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +460 -0
  39. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +446 -0
  40. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +280 -0
  41. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +274 -0
  42. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +201 -0
  43. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +278 -0
  44. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +2 -1
  45. package/oclif.manifest.json +1 -1
  46. package/package.json +1 -1
@@ -0,0 +1,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/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
+ ## Command Integration
315
+
316
+ **Thin pointer pattern:**
317
+
318
+ `.claude/commands/handoff.md` (user-facing, discoverable via `/`)
319
+ → References `.aiwcli/_shared/handoff-system/workflows/handoff.md` (detailed procedural steps)
320
+
321
+ **Benefits:**
322
+ - Command 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/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
+ ## Architecture Decisions
373
+
374
+ **Why folder sharding (not single file)?**
375
+ - Enables selective loading (resume script loads only needed sections)
376
+ - Allows future extensions (e.g., attachments, screenshots)
377
+ - Chronological discovery via timestamp folders
378
+
379
+ **Why section markers (not frontmatter)?**
380
+ - Flexible content generation (Claude outputs sections in natural flow)
381
+ - No strict ordering required (script extracts by marker)
382
+ - Easy to extend (add new sections without schema version bump)
383
+
384
+ **Why latest-wins (not dual artifact tracking)?**
385
+ - Simplifies state machine (one artifact, one mode transition)
386
+ - Prevents ambiguity (which artifact to restore?)
387
+ - Matches user mental model (most recent work is relevant)
388
+
389
+ **Why unified work_consumed flag?**
390
+ - Prevents infinite re-staging loop
391
+ - Simpler than per-artifact flags (plan_consumed, handoff_consumed)
392
+ - One-shot latch pattern is well-understood
393
+
394
+ ## Gotchas
395
+
396
+ **Template sync is mandatory:**
397
+ Both `.aiwcli/_shared/handoff-system/` (working copy) and `packages/cli/src/templates/_shared/handoff-system/` (template source) must stay in sync per CLAUDE.md template sync rules.
398
+
399
+ **Import paths after move:**
400
+ - From `scripts/resume_handoff.ts` → `lib/handoff-reader.ts`: `../lib/handoff-reader.js`
401
+ - From `lib/handoff-reader.ts` → `lib-ts/base/constants.ts`: `../../lib-ts/base/constants.js`
402
+
403
+ **Hooks don't import handoff-reader:**
404
+ - `session_start.ts` uses `formatHandoffContinuation()` from `context-formatter.ts`
405
+ - `context-formatter.ts` reads `ctx.handoff_path` directly
406
+ - No direct handoff-reader dependency in hooks
407
+
408
+ **Command file script paths are absolute:**
409
+ - Reference from project root: `.aiwcli/_shared/handoff-system/scripts/save_handoff.ts`
410
+ - NOT relative to command file location
411
+
412
+ **Section markers must be HTML comments:**
413
+ ```markdown
414
+ <!-- SECTION: PENDING --> ✅ Correct
415
+ # SECTION: PENDING ❌ Incorrect (parsed as heading, not marker)
416
+ ```
417
+
418
+ **Windsurf and Codex workflows also reference scripts:**
419
+ When updating script paths, check:
420
+ - `packages/cli/src/templates/_shared/.windsurf/workflows/handoff.md`
421
+ - `packages/cli/src/templates/_shared/.codex/workflows/handoff.md`
@@ -6,18 +6,17 @@
6
6
  * work to a new session (typically due to context window limits).
7
7
  */
8
8
 
9
- import * as crypto from "node:crypto";
10
9
  import * as fs from "node:fs";
11
10
  import * as path from "node:path";
12
-
11
+ import * as crypto from "node:crypto";
12
+ import { getContextHandoffsDir, getContextDir } from "../base/constants.js";
13
13
  import { atomicWrite } from "../base/atomic-write.js";
14
- import { getContextDir, getContextHandoffsDir } from "../base/constants.js";
15
- import { logError, logInfo } from "../base/logger.js";
14
+ import { logInfo, logError } from "../base/logger.js";
16
15
  import { nowIso } from "../base/utils.js";
17
- import { getContext, saveState as _saveState } from "../context/context-store.js";
16
+ import { getContext, saveState } from "../context/context-store.js";
18
17
  import { getTasks } from "../context/task-tracker.js";
19
- import { formatContinuationHeader, formatReason, renderTaskList } from "../templates/formatters.js";
20
- import type { HandoffDocument, Task as _Task } from "../types.js";
18
+ import { renderTaskList, formatContinuationHeader, formatReason } from "../templates/formatters.js";
19
+ import type { HandoffDocument, Task } from "../types.js";
21
20
 
22
21
  /**
23
22
  * Generate and save a handoff document for a context.
@@ -125,7 +124,8 @@ function renderHandoffMarkdown(doc: HandoffDocument): string {
125
124
  );
126
125
 
127
126
  // Active tasks
128
- lines.push(renderTaskList(doc.active_tasks, "Active Tasks", true).trimEnd(), "");
127
+ lines.push(renderTaskList(doc.active_tasks, "Active Tasks", true).trimEnd());
128
+ lines.push("");
129
129
 
130
130
  // Completed this session
131
131
  if (doc.completed_tasks_this_session.length > 0) {
@@ -133,7 +133,8 @@ function renderHandoffMarkdown(doc: HandoffDocument): string {
133
133
  doc.completed_tasks_this_session as any[],
134
134
  "Completed This Session",
135
135
  false,
136
- ).trimEnd(), "");
136
+ ).trimEnd());
137
+ lines.push("");
137
138
  }
138
139
 
139
140
  // Work summary
@@ -147,7 +148,6 @@ function renderHandoffMarkdown(doc: HandoffDocument): string {
147
148
  for (let i = 0; i < doc.next_steps.length; i++) {
148
149
  lines.push(`${i + 1}. ${doc.next_steps[i]}`);
149
150
  }
150
-
151
151
  lines.push("");
152
152
  }
153
153
 
@@ -157,7 +157,6 @@ function renderHandoffMarkdown(doc: HandoffDocument): string {
157
157
  for (const note of doc.important_notes) {
158
158
  lines.push(`- ${note}`);
159
159
  }
160
-
161
160
  lines.push("");
162
161
  }
163
162
 
@@ -7,11 +7,10 @@
7
7
  */
8
8
 
9
9
  import * as fs from "node:fs";
10
- import * as path from "node:path";
11
-
12
- import { getContextHandoffsDir } from "../base/constants.js";
13
- import { getContext } from "../context/context-store.js";
14
- import type { HandoffSections } from "../types.js";
10
+ import * as path from "node:path";
11
+ import { getContextHandoffsDir } from "../../lib-ts/base/constants.js";
12
+ import { getContext } from "../../lib-ts/context/context-store.js";
13
+ import type { HandoffSections } from "../../lib-ts/types.js";
15
14
 
16
15
  /**
17
16
  * Find the most recent handoff folder for a context.
@@ -30,7 +29,7 @@ export function findLatestHandoff(contextId: string, projectRoot?: string): stri
30
29
  .sort();
31
30
 
32
31
  if (entries.length === 0) return null;
33
- return path.join(handoffsDir, entries.at(-1)!);
32
+ return path.join(handoffsDir, entries[entries.length - 1]!);
34
33
  } catch {
35
34
  return null;
36
35
  }
@@ -4,8 +4,8 @@
4
4
  * a structured briefing to stdout.
5
5
  *
6
6
  * Usage:
7
- * bun .aiwcli/_shared/scripts/resume_handoff.ts <handoff_folder_or_index>
8
- * bun .aiwcli/_shared/scripts/resume_handoff.ts --context <context_id>
7
+ * bun .aiwcli/_shared/handoff-system/scripts/resume_handoff.ts <handoff_folder_or_index>
8
+ * bun .aiwcli/_shared/handoff-system/scripts/resume_handoff.ts --context <context_id>
9
9
  *
10
10
  * If no args, auto-discovers the active context and finds the latest handoff.
11
11
  *
@@ -15,16 +15,16 @@
15
15
  import * as fs from "node:fs";
16
16
  import * as path from "node:path";
17
17
 
18
- import { getProjectRoot } from "../lib-ts/base/constants.js";
19
- import { getGitStatusShort } from "../lib-ts/base/git-state.js";
20
- import { eprint } from "../lib-ts/base/utils.js";
21
- import { findActiveContextId } from "../lib-ts/context/context-store.js";
22
18
  import {
23
19
  findLatestHandoff,
24
20
  readHandoffSections,
25
21
  getHandoffTimestamp,
26
22
  getHandoffPlanReference,
27
- } from "../lib-ts/handoff/handoff-reader.js";
23
+ } from "../lib/handoff-reader.js";
24
+ import { getProjectRoot } from "../../lib-ts/base/constants.js";
25
+ import { getContextBySessionId } from "../../lib-ts/context/context-store.js";
26
+ import { getGitStatusShort } from "../../lib-ts/base/git-state.js";
27
+ import { eprint } from "../../lib-ts/base/utils.js";
28
28
 
29
29
  // ---------------------------------------------------------------------------
30
30
  // Helpers
@@ -117,19 +117,22 @@ function resolveHandoffFolder(args: string[]): [string, string | null] {
117
117
  return [target, null];
118
118
  }
119
119
 
120
- // Auto-discover active context
121
- const discoveredId = findActiveContextId(projectRoot);
122
- if (discoveredId) {
123
- const folder = findLatestHandoff(discoveredId, projectRoot);
124
- if (!folder) {
125
- eprint(`No handoff folders found for context: ${discoveredId} (auto-discovered)`);
126
- process.exit(1);
120
+ // Auto-discover via session ID (when running from Claude Code)
121
+ const sessionId = process.env.CLAUDE_SESSION_ID;
122
+ if (sessionId) {
123
+ const context = getContextBySessionId(sessionId, projectRoot);
124
+ if (context) {
125
+ const folder = findLatestHandoff(context.id, projectRoot);
126
+ if (!folder) {
127
+ eprint(`No handoff folders found for context: ${context.id} (from session ${sessionId})`);
128
+ process.exit(1);
129
+ }
130
+ return [folder, context.id];
127
131
  }
128
- return [folder, discoveredId];
129
132
  }
130
133
 
131
134
  eprint(
132
- "No active context found.\n\n" +
135
+ "No context found for current session.\n\n" +
133
136
  "Usage: bun resume_handoff.ts <handoff_folder_or_index>\n" +
134
137
  " bun resume_handoff.ts --context <context_id>",
135
138
  );