aiwcli 0.12.6 → 0.12.7
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/bin/dev.cmd +3 -3
- package/bin/dev.js +16 -16
- package/bin/run.cmd +3 -3
- package/bin/run.js +21 -21
- package/dist/commands/branch.js +7 -2
- package/dist/lib/bmad-installer.js +37 -37
- package/dist/lib/terminal.d.ts +2 -0
- package/dist/lib/terminal.js +57 -7
- package/dist/templates/CLAUDE.md +205 -205
- package/dist/templates/_shared/.claude/commands/handoff-resume.md +12 -12
- package/dist/templates/_shared/.claude/commands/handoff.md +12 -12
- package/dist/templates/_shared/.claude/settings.json +65 -65
- package/dist/templates/_shared/.codex/workflows/handoff.md +226 -226
- package/dist/templates/_shared/.windsurf/workflows/handoff.md +226 -226
- package/dist/templates/_shared/handoff-system/CLAUDE.md +421 -421
- package/dist/templates/_shared/handoff-system/lib/document-generator.ts +215 -215
- package/dist/templates/_shared/handoff-system/lib/handoff-reader.ts +158 -158
- package/dist/templates/_shared/handoff-system/scripts/resume_handoff.ts +373 -373
- package/dist/templates/_shared/handoff-system/scripts/save_handoff.ts +469 -469
- package/dist/templates/_shared/handoff-system/workflows/handoff-resume.md +66 -66
- package/dist/templates/_shared/handoff-system/workflows/handoff.md +254 -254
- package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +2 -2
- package/dist/templates/_shared/hooks-ts/archive_plan.ts +159 -159
- package/dist/templates/_shared/hooks-ts/context_monitor.ts +147 -147
- package/dist/templates/_shared/hooks-ts/file-suggestion.ts +128 -128
- package/dist/templates/_shared/hooks-ts/pre_compact.ts +49 -49
- package/dist/templates/_shared/hooks-ts/session_end.ts +196 -196
- package/dist/templates/_shared/hooks-ts/session_start.ts +163 -163
- package/dist/templates/_shared/hooks-ts/task_create_capture.ts +48 -48
- package/dist/templates/_shared/hooks-ts/task_update_capture.ts +74 -74
- package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +93 -93
- package/dist/templates/_shared/lib-ts/CLAUDE.md +367 -367
- package/dist/templates/_shared/lib-ts/base/atomic-write.ts +138 -138
- package/dist/templates/_shared/lib-ts/base/constants.ts +303 -303
- package/dist/templates/_shared/lib-ts/base/git-state.ts +58 -58
- package/dist/templates/_shared/lib-ts/base/hook-utils.ts +582 -582
- package/dist/templates/_shared/lib-ts/base/inference.ts +301 -301
- package/dist/templates/_shared/lib-ts/base/logger.ts +247 -247
- package/dist/templates/_shared/lib-ts/base/state-io.ts +202 -202
- package/dist/templates/_shared/lib-ts/base/stop-words.ts +184 -184
- package/dist/templates/_shared/lib-ts/base/utils.ts +184 -184
- package/dist/templates/_shared/lib-ts/context/context-formatter.ts +566 -566
- package/dist/templates/_shared/lib-ts/context/context-selector.ts +524 -524
- package/dist/templates/_shared/lib-ts/context/context-store.ts +712 -712
- package/dist/templates/_shared/lib-ts/context/plan-manager.ts +312 -312
- package/dist/templates/_shared/lib-ts/context/task-tracker.ts +185 -185
- package/dist/templates/_shared/lib-ts/package.json +20 -20
- package/dist/templates/_shared/lib-ts/templates/formatters.ts +102 -102
- package/dist/templates/_shared/lib-ts/templates/plan-context.ts +58 -58
- package/dist/templates/_shared/lib-ts/tsconfig.json +13 -13
- package/dist/templates/_shared/lib-ts/types.ts +186 -186
- package/dist/templates/_shared/scripts/resolve_context.ts +33 -33
- package/dist/templates/_shared/scripts/status_line.ts +690 -690
- package/dist/templates/cc-native/.claude/commands/cc-native/rlm/ask.md +136 -136
- package/dist/templates/cc-native/.claude/commands/cc-native/rlm/index.md +21 -21
- package/dist/templates/cc-native/.claude/commands/cc-native/rlm/overview.md +56 -56
- package/dist/templates/cc-native/.claude/commands/cc-native/specdev.md +10 -10
- package/dist/templates/cc-native/.windsurf/workflows/cc-native/fix.md +8 -8
- package/dist/templates/cc-native/.windsurf/workflows/cc-native/implement.md +8 -8
- package/dist/templates/cc-native/.windsurf/workflows/cc-native/research.md +8 -8
- package/dist/templates/cc-native/CC-NATIVE-README.md +189 -189
- package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +304 -304
- package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +143 -143
- package/dist/templates/cc-native/_cc-native/agents/PLAN-ORCHESTRATOR.md +213 -213
- package/dist/templates/cc-native/_cc-native/agents/plan-questions/PLAN-QUESTIONER.md +70 -70
- package/dist/templates/cc-native/_cc-native/cc-native.config.json +96 -96
- package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +247 -247
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +76 -76
- package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +54 -54
- package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +51 -51
- package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +53 -53
- package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +61 -61
- package/dist/templates/cc-native/_cc-native/lib-ts/agent-selection.ts +163 -163
- package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +156 -156
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/format.ts +597 -597
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/index.ts +26 -26
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/tracker.ts +107 -107
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/write.ts +119 -119
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +21 -21
- package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +319 -319
- package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +144 -144
- package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +57 -57
- package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +83 -83
- package/dist/templates/cc-native/_cc-native/lib-ts/corroboration.ts +119 -119
- package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +79 -79
- package/dist/templates/cc-native/_cc-native/lib-ts/graduation.ts +132 -132
- package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +116 -116
- package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +168 -168
- package/dist/templates/cc-native/_cc-native/lib-ts/orchestrator.ts +70 -70
- package/dist/templates/cc-native/_cc-native/lib-ts/output-builder.ts +130 -130
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +80 -80
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-enhancement.ts +41 -41
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-questions.ts +101 -101
- package/dist/templates/cc-native/_cc-native/lib-ts/review-pipeline.ts +511 -511
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/agent.ts +71 -71
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/base/base-agent.ts +217 -217
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/index.ts +12 -12
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/claude-agent.ts +66 -66
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/codex-agent.ts +184 -184
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/gemini-agent.ts +39 -39
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/orchestrator-claude-agent.ts +196 -196
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/schemas.ts +201 -201
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/types.ts +21 -21
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/CLAUDE.md +480 -480
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +287 -287
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +148 -148
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +54 -54
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +58 -58
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +208 -208
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +460 -460
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +446 -446
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +280 -280
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +274 -274
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +201 -201
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +278 -278
- package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +184 -184
- package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +275 -275
- package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +18 -18
- package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +329 -329
- package/dist/templates/cc-native/_cc-native/lib-ts/verdict.ts +72 -72
- package/dist/templates/cc-native/_cc-native/workflows/specdev.md +9 -9
- package/oclif.manifest.json +1 -1
- package/package.json +108 -108
- package/dist/templates/cc-native/_cc-native/lib-ts/nul +0 -3
|
@@ -1,247 +1,247 @@
|
|
|
1
|
-
# CC-Native Hooks Development Guide
|
|
2
|
-
|
|
3
|
-
> **Keep this document updated.** When you solve an issue related to hooks, add the solution to the relevant section and log it in the Changelog. This document should grow with discovered patterns and fixes—don't wait to be asked.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Quick Reference
|
|
8
|
-
|
|
9
|
-
| Hook | Trigger | Purpose |
|
|
10
|
-
|------|---------|---------|
|
|
11
|
-
| `cc-native-plan-review.ts` | PreToolUse: ExitPlanMode | Questions gate + plan review before user approval |
|
|
12
|
-
| `add_plan_context.ts` | PostToolUse: AskUserQuestion, PreToolUse: Task | Mark questions asked; nudge Plan subagent to ask questions first |
|
|
13
|
-
| `plan_questions_early.ts` | UserPromptSubmit | Inject Phase A clarification prompt in plan mode |
|
|
14
|
-
|
|
15
|
-
### Plan Review Architecture
|
|
16
|
-
|
|
17
|
-
The hook is a thin coordinator (~70 lines) that delegates to `lib-ts/review-pipeline.ts`. The pipeline wires together focused modules:
|
|
18
|
-
|
|
19
|
-
| Module | Responsibility |
|
|
20
|
-
|--------|----------------|
|
|
21
|
-
| `plan-discovery.ts` | Find plan file, read content, compute hash |
|
|
22
|
-
| `settings.ts` | Load + merge config with defaults, load agent library |
|
|
23
|
-
| `agent-selection.ts` | Mandatory agent resolution, orchestrator-based selection, model assignment |
|
|
24
|
-
| `graduation.ts` | Pass eligibility, pass streaks, graduation threshold, iteration advancement |
|
|
25
|
-
| `output-builder.ts` | Issue truncation, verdict override, context/block message construction |
|
|
26
|
-
| `review-pipeline.ts` | Pipeline orchestrator wiring all modules together |
|
|
27
|
-
| `artifacts/format.ts` | Pure formatting (markdown, JSON, inline summaries) |
|
|
28
|
-
| `artifacts/write.ts` | File I/O for review artifacts |
|
|
29
|
-
| `artifacts/tracker.ts` | Review tracker management |
|
|
30
|
-
|
|
31
|
-
### Questions Gate (in review-pipeline.ts)
|
|
32
|
-
|
|
33
|
-
Before running plan review agents, the pipeline checks `wasQuestionsAsked()`. If the user hasn't been asked questions yet, it runs a fresh-context plan-questions agent (from `agents/plan-questions/PLAN-QUESTIONER.md`) that independently reviews the plan and generates questions, assumptions, and ambiguities. If questions are found, ExitPlanMode is denied with the question list injected as context. After the user answers via AskUserQuestion (which triggers `mark_questions_asked.ts`), the next ExitPlanMode attempt passes the gate and proceeds to normal plan review.
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Import Pattern
|
|
38
|
-
|
|
39
|
-
CC-native hooks are TypeScript, run via `bun`. Use relative imports from the hook file location.
|
|
40
|
-
|
|
41
|
-
```typescript
|
|
42
|
-
// Shared library imports (via _shared/lib-ts/)
|
|
43
|
-
import { loadHookInput, runHook, logInfo, emitContext } from "../../_shared/lib-ts/base/hook-utils.js";
|
|
44
|
-
import { isInternalCall } from "../../_shared/lib-ts/base/subprocess-utils.js";
|
|
45
|
-
import { getProjectRoot } from "../../_shared/lib-ts/base/constants.js";
|
|
46
|
-
|
|
47
|
-
// CC-native library imports (via ../lib-ts/)
|
|
48
|
-
import { wasQuestionsAsked, markQuestionsAsked } from "../lib-ts/cc-native-state.js";
|
|
49
|
-
import { loadConfig } from "../lib-ts/config.js";
|
|
50
|
-
import type { AgentConfig } from "../lib-ts/types.js";
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
**Important:** Always use `.js` extensions in import paths — Bun resolves `.ts` files from `.js` imports.
|
|
54
|
-
|
|
55
|
-
**Import direction:** Hooks → `_cc-native/lib-ts/` → `_shared/lib-ts/`. Never reverse.
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## Internal Call Detection
|
|
60
|
-
|
|
61
|
-
Hooks can be invoked recursively when spawning subprocesses (agents, orchestrator). Always check and skip:
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
import { isInternalCall } from "../../_shared/lib-ts/base/subprocess-utils.js";
|
|
65
|
-
|
|
66
|
-
function main(): void {
|
|
67
|
-
// FIRST LINE of main - before any other logic
|
|
68
|
-
if (isInternalCall()) return;
|
|
69
|
-
|
|
70
|
-
// Rest of hook logic...
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Without this check, the hook runs multiple times per plan review, causing duplicate reviews and state corruption.
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Hook Output Format
|
|
79
|
-
|
|
80
|
-
Claude Code hooks return JSON to stdout. The format is specific to each hook type.
|
|
81
|
-
|
|
82
|
-
### PreToolUse Output
|
|
83
|
-
|
|
84
|
-
Use the shared hook utilities — never construct JSON manually:
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
import { emitContext, emitContextAndBlock } from "../../_shared/lib-ts/base/hook-utils.js";
|
|
88
|
-
|
|
89
|
-
// Inject context without blocking:
|
|
90
|
-
emitContext("Information for Claude to see...");
|
|
91
|
-
|
|
92
|
-
// Block the tool call with context and reason:
|
|
93
|
-
emitContextAndBlock(
|
|
94
|
-
"Review feedback for Claude to see...",
|
|
95
|
-
"Reason shown to Claude for the denial",
|
|
96
|
-
);
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
**Key insight:** The old `decision`/`reason` format fails silently. If your hook isn't affecting Claude's behavior, check the output format first. Only `hookSpecificOutput` with `additionalContext`, `permissionDecision`, and `permissionDecisionReason` fields are recognized.
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
## Debugging Output
|
|
104
|
-
|
|
105
|
-
For logging tiers, visibility rules, and stderr behavior, see **`_shared/lib-ts/CLAUDE.md`** (the shared library guide). The key rules:
|
|
106
|
-
|
|
107
|
-
- **stderr is opt-in.** `log_debug/log_info/log_warn/log_error` write to file only (no UI noise)
|
|
108
|
-
- **`logBlocking()` / `log_hook_error()`** for problems that must be visible
|
|
109
|
-
- **`eprint()`** for terminal-only UX (not logged to JSONL)
|
|
110
|
-
- **`print()` corrupts stdout** — never use for diagnostics
|
|
111
|
-
|
|
112
|
-
TypeScript hooks use re-exported logger functions from `hook-utils.ts`:
|
|
113
|
-
|
|
114
|
-
```typescript
|
|
115
|
-
import { logDebug, logInfo, logWarn, logError } from "../../_shared/lib-ts/base/hook-utils.js";
|
|
116
|
-
|
|
117
|
-
logDebug("hook-name", `Found ${items.length} items`); // file only
|
|
118
|
-
logInfo("hook-name", "Starting hook..."); // file only
|
|
119
|
-
logError("hook-name", `Failed: ${e}`); // file only
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
---
|
|
123
|
-
|
|
124
|
-
## Context System Integration
|
|
125
|
-
|
|
126
|
-
Plan review hooks integrate with the shared context system for state management:
|
|
127
|
-
|
|
128
|
-
```typescript
|
|
129
|
-
import { getContextBySessionId, getAllContexts } from "../../_shared/lib-ts/context/context-store.js";
|
|
130
|
-
import { getContextReviewsDir } from "../../_shared/lib-ts/base/constants.js";
|
|
131
|
-
|
|
132
|
-
// Find active context
|
|
133
|
-
const context = getContextBySessionId(sessionId, projectRoot);
|
|
134
|
-
if (!context) {
|
|
135
|
-
// Fallback: find single planning context
|
|
136
|
-
const allActive = getAllContexts("active", projectRoot);
|
|
137
|
-
const planning = allActive.filter((c: any) => c.mode === "active" || c.mode === "has_plan");
|
|
138
|
-
if (planning.length === 1) {
|
|
139
|
-
context = planning[0];
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Get reviews directory for this context
|
|
144
|
-
const reviewsDir = getContextReviewsDir(context.id, projectRoot);
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
CC-native specific state is accessed via `cc-native-state.ts`:
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
import { isPlanAlreadyReviewed, markPlanReviewed, wasQuestionsAsked } from "../lib-ts/cc-native-state.js";
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
---
|
|
154
|
-
|
|
155
|
-
## Error Handling
|
|
156
|
-
|
|
157
|
-
Hooks should fail gracefully — a broken hook shouldn't break the user's workflow. `runHook()` and `runHookAsync()` handle this automatically: uncaught errors log to file and exit 0 (non-blocking).
|
|
158
|
-
|
|
159
|
-
```typescript
|
|
160
|
-
import { runHook, logInfo } from "../../_shared/lib-ts/base/hook-utils.js";
|
|
161
|
-
|
|
162
|
-
function main(): void {
|
|
163
|
-
// Hook logic — uncaught errors are handled by runHook
|
|
164
|
-
logInfo("hook-name", "Starting...");
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
runHook(main, "hook_name");
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
For async hooks (plan review with parallel agents):
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
import { runHookAsync } from "../../_shared/lib-ts/base/hook-utils.js";
|
|
174
|
-
|
|
175
|
-
async function main(): Promise<void> {
|
|
176
|
-
// Async hook logic with Promise.all() etc.
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
runHookAsync(main, "hook_name");
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
Use `emitContextAndBlock()` for intentional blocking (e.g., plan review denial). `hookEventName` is auto-detected.
|
|
183
|
-
|
|
184
|
-
---
|
|
185
|
-
|
|
186
|
-
## Error Handling: Non-Critical Operations
|
|
187
|
-
|
|
188
|
-
Wrap non-critical shared library calls in try/catch to prevent false "hook error" UI display. See **`_shared/lib-ts/CLAUDE.md`** > Context Store for the pattern and rationale.
|
|
189
|
-
|
|
190
|
-
**When to catch locally vs let bubble:**
|
|
191
|
-
- **Catch locally:** Side effects like mode transitions, state saves — the hook's primary purpose can still succeed without them
|
|
192
|
-
- **Let bubble:** Core operations where failure means the hook genuinely can't do its job
|
|
193
|
-
|
|
194
|
-
---
|
|
195
|
-
|
|
196
|
-
## DO NOT
|
|
197
|
-
|
|
198
|
-
These are reminders based on past issues. Not enforcement rules.
|
|
199
|
-
|
|
200
|
-
- **Don't modify hook output format** without verifying the current Claude Code hook API (it changes between versions)
|
|
201
|
-
- **Don't use `process.exit(1)` or `process.exit(2)`** for non-fatal errors - it blocks the user's workflow
|
|
202
|
-
- **Don't forget template sync** after modifying hooks in `.aiwcli/` - changes should also go to `packages/cli/src/templates/cc-native/`
|
|
203
|
-
- **Don't use `console.log()`** for anything — it corrupts stdout. Use `emitContext()` for hook output
|
|
204
|
-
- **Don't assume session_id format** - it can be UUID, path-like, or other formats
|
|
205
|
-
- **Don't skip `is_internal_call()` check** - recursive hook execution causes state corruption
|
|
206
|
-
- **Don't hardcode paths** - use `getProjectRoot()` and relative imports
|
|
207
|
-
- **Don't let non-critical operations bubble to `runHook`** - catch locally to prevent stderr "hook error" display
|
|
208
|
-
|
|
209
|
-
---
|
|
210
|
-
|
|
211
|
-
## Verification After Changes
|
|
212
|
-
|
|
213
|
-
Validate TypeScript syntax after editing hooks:
|
|
214
|
-
|
|
215
|
-
```bash
|
|
216
|
-
# Quick syntax check via bun
|
|
217
|
-
bun --print "import('.aiwcli/_cc-native/hooks/cc-native-plan-review.ts')" 2>&1 | head -5
|
|
218
|
-
|
|
219
|
-
# Or check imports resolve (dry run)
|
|
220
|
-
bun build --no-bundle .aiwcli/_cc-native/hooks/add_plan_context.ts --outdir /dev/null 2>&1
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
Hooks fail silently on import errors — verify after any import path changes.
|
|
224
|
-
|
|
225
|
-
---
|
|
226
|
-
|
|
227
|
-
## Changelog
|
|
228
|
-
|
|
229
|
-
<!-- Add dated entries as new issues are discovered -->
|
|
230
|
-
|
|
231
|
-
| Date | Change |
|
|
232
|
-
|------|--------|
|
|
233
|
-
| 2026-02-14 | **Plan review hook refactored into focused modules.** `cc-native-plan-review.ts` reduced from 1061 to ~70 lines (thin coordinator). Core logic moved to `review-pipeline.ts`. Extracted: `plan-discovery.ts`, `settings.ts`, `agent-selection.ts`, `graduation.ts`, `output-builder.ts`. Split `artifacts.ts` (822 lines) into `artifacts/format.ts`, `artifacts/write.ts`, `artifacts/tracker.ts` with barrel re-export. Added `loadIterationState()`/`saveIterationState()` to `state.ts`. New pipeline types in `types.ts`. |
|
|
234
|
-
| 2026-02-14 | **Questions gate added to plan review.** `cc-native-plan-review.ts` now runs a fresh-context plan-questions agent before plan review. If `wasQuestionsAsked()` returns false, the PLAN-QUESTIONER agent (from `agents/plan-questions/`) generates questions/assumptions/ambiguities using `QUESTIONS_SCHEMA`. On questions found, ExitPlanMode is denied with question list as context. New library module: `lib-ts/plan-questions.ts`. Agent directory reorganized: review agents moved to `agents/plan-review/`, question agents in `agents/plan-questions/`. |
|
|
235
|
-
| 2026-02-10 | **Migrated cc-native hooks from Python to TypeScript.** `cc-native-plan-review.ts` (async, parallel agent reviews via `Promise.all()`), `add_plan_context.ts`, `plan_questions_early.ts`. All hooks use `runHook()`/`runHookAsync()` entry points. Library code in `_cc-native/lib-ts/` (18 files). Settings.json updated to use `bun` runner. Python `.py` files kept as fallback until TS hooks verified. |
|
|
236
|
-
| 2026-02-10 | Flipped TS logger stderr default to opt-in (`opts?.stderr === true`). Added `logBlocking()` for intentional stderr visibility. Removed redundant `{stderr: false}` from hook-utils.ts, user_prompt_submit.ts, context_monitor.ts. Added "Hook Error Visibility" section documenting visibility tiers and exit code behavior. |
|
|
237
|
-
| 2026-02-10 | Fixed `debug.py` `context_path` crash. Added local try/catch around `maybeActivate` in `user_prompt_submit.ts` and `context_monitor.ts` to prevent stderr error display on non-critical I/O failures. Removed dead `context_path` from `_emitHookEnd` in `hook-utils.ts`. Added "Error Handling" section to CLAUDE.md. |
|
|
238
|
-
| 2026-02-07 | Handoff staging lifecycle: `has_handoff` mode + `handoff_consumed` flag mirrors plan lifecycle. `save_handoff.py` no longer transitions to idle — stays active for session_end staging. `session_end.py` stages `active→has_handoff` when handoff_path set and not consumed. `session_start.py` restores `has_handoff→active` on /clear. `context_selector.py` has fallback Case 3b for has_handoff. PostToolUse context_monitor matcher simplified from specific tool list to `*`. |
|
|
239
|
-
| 2026-02-07 | Removed PreToolUse:Write matcher from `add_plan_context.py`. Write-time plan nudges were redundant after consolidating enforcement to PreToolUse:Task. Removed `is_plan_file_write()`, `load_plan_context_config()`, `PHASE_B_ENFORCEMENT`, `nudge_write_questions()`, and `project_dir` import. |
|
|
240
|
-
| 2026-02-07 | Question enforcement is now advisory-only (never blocks). `add_plan_context.py` uses `emit_context()` for all question nudges — no `permissionDecision:deny` anywhere. Removed `emit_context_and_block` import and `TASK_ENFORCEMENT_REASON` constant. |
|
|
241
|
-
| 2026-02-07 | Moved question enforcement to PreToolUse:Task (Plan subagent gate). `add_plan_context.py` now handles three events: PostToolUse:AskUserQuestion, PreToolUse:Task (primary gate), PreToolUse:Write (fallback). Added `is_plan_task()`, `is_internal_call()` guard, `TASK_ENFORCEMENT_CONTEXT` constant. Registered `^Task$` command hook in settings.json. |
|
|
242
|
-
| 2026-02-07 | Deleted `plan_accepted.py` (dead code — PostToolUse:ExitPlanMode never fires due to /clear race). Plan field assignment handled by `session_end.py` fallback. Added `plan_consumed` flag to prevent infinite plan re-staging. |
|
|
243
|
-
| 2026-02-07 | Hook lifecycle diagnostics: all hooks now use `run_hook(main, "hook_name")` entry point. Logs HOOK_START/HOOK_END with template origin, event type, duration_ms, and status. Millisecond timestamps in logger. |
|
|
244
|
-
| 2026-02-07 | Unified logger: all diagnostic logging uses `log_debug/log_info/log_warn/log_error` from `_shared/lib/base/logger.py` instead of eprint/print-to-stderr. Updated debugging and error handling docs. |
|
|
245
|
-
| 2026-02-06 | Merged mark_questions_asked.py into add_plan_context.py. Hook now handles both PostToolUse:AskUserQuestion and PreToolUse:Write. Deleted standalone mark_questions_asked.py. |
|
|
246
|
-
| 2026-02-06 | Fixed add_plan_context.py trigger docs (was PostToolUse: EnterPlanMode, is PreToolUse: Write). Added emit_context/emit_context_and_block utility docs. |
|
|
247
|
-
| 2026-02-03 | Initial creation |
|
|
1
|
+
# CC-Native Hooks Development Guide
|
|
2
|
+
|
|
3
|
+
> **Keep this document updated.** When you solve an issue related to hooks, add the solution to the relevant section and log it in the Changelog. This document should grow with discovered patterns and fixes—don't wait to be asked.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Quick Reference
|
|
8
|
+
|
|
9
|
+
| Hook | Trigger | Purpose |
|
|
10
|
+
|------|---------|---------|
|
|
11
|
+
| `cc-native-plan-review.ts` | PreToolUse: ExitPlanMode | Questions gate + plan review before user approval |
|
|
12
|
+
| `add_plan_context.ts` | PostToolUse: AskUserQuestion, PreToolUse: Task | Mark questions asked; nudge Plan subagent to ask questions first |
|
|
13
|
+
| `plan_questions_early.ts` | UserPromptSubmit | Inject Phase A clarification prompt in plan mode |
|
|
14
|
+
|
|
15
|
+
### Plan Review Architecture
|
|
16
|
+
|
|
17
|
+
The hook is a thin coordinator (~70 lines) that delegates to `lib-ts/review-pipeline.ts`. The pipeline wires together focused modules:
|
|
18
|
+
|
|
19
|
+
| Module | Responsibility |
|
|
20
|
+
|--------|----------------|
|
|
21
|
+
| `plan-discovery.ts` | Find plan file, read content, compute hash |
|
|
22
|
+
| `settings.ts` | Load + merge config with defaults, load agent library |
|
|
23
|
+
| `agent-selection.ts` | Mandatory agent resolution, orchestrator-based selection, model assignment |
|
|
24
|
+
| `graduation.ts` | Pass eligibility, pass streaks, graduation threshold, iteration advancement |
|
|
25
|
+
| `output-builder.ts` | Issue truncation, verdict override, context/block message construction |
|
|
26
|
+
| `review-pipeline.ts` | Pipeline orchestrator wiring all modules together |
|
|
27
|
+
| `artifacts/format.ts` | Pure formatting (markdown, JSON, inline summaries) |
|
|
28
|
+
| `artifacts/write.ts` | File I/O for review artifacts |
|
|
29
|
+
| `artifacts/tracker.ts` | Review tracker management |
|
|
30
|
+
|
|
31
|
+
### Questions Gate (in review-pipeline.ts)
|
|
32
|
+
|
|
33
|
+
Before running plan review agents, the pipeline checks `wasQuestionsAsked()`. If the user hasn't been asked questions yet, it runs a fresh-context plan-questions agent (from `agents/plan-questions/PLAN-QUESTIONER.md`) that independently reviews the plan and generates questions, assumptions, and ambiguities. If questions are found, ExitPlanMode is denied with the question list injected as context. After the user answers via AskUserQuestion (which triggers `mark_questions_asked.ts`), the next ExitPlanMode attempt passes the gate and proceeds to normal plan review.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Import Pattern
|
|
38
|
+
|
|
39
|
+
CC-native hooks are TypeScript, run via `bun`. Use relative imports from the hook file location.
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// Shared library imports (via _shared/lib-ts/)
|
|
43
|
+
import { loadHookInput, runHook, logInfo, emitContext } from "../../_shared/lib-ts/base/hook-utils.js";
|
|
44
|
+
import { isInternalCall } from "../../_shared/lib-ts/base/subprocess-utils.js";
|
|
45
|
+
import { getProjectRoot } from "../../_shared/lib-ts/base/constants.js";
|
|
46
|
+
|
|
47
|
+
// CC-native library imports (via ../lib-ts/)
|
|
48
|
+
import { wasQuestionsAsked, markQuestionsAsked } from "../lib-ts/cc-native-state.js";
|
|
49
|
+
import { loadConfig } from "../lib-ts/config.js";
|
|
50
|
+
import type { AgentConfig } from "../lib-ts/types.js";
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Important:** Always use `.js` extensions in import paths — Bun resolves `.ts` files from `.js` imports.
|
|
54
|
+
|
|
55
|
+
**Import direction:** Hooks → `_cc-native/lib-ts/` → `_shared/lib-ts/`. Never reverse.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Internal Call Detection
|
|
60
|
+
|
|
61
|
+
Hooks can be invoked recursively when spawning subprocesses (agents, orchestrator). Always check and skip:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { isInternalCall } from "../../_shared/lib-ts/base/subprocess-utils.js";
|
|
65
|
+
|
|
66
|
+
function main(): void {
|
|
67
|
+
// FIRST LINE of main - before any other logic
|
|
68
|
+
if (isInternalCall()) return;
|
|
69
|
+
|
|
70
|
+
// Rest of hook logic...
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Without this check, the hook runs multiple times per plan review, causing duplicate reviews and state corruption.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Hook Output Format
|
|
79
|
+
|
|
80
|
+
Claude Code hooks return JSON to stdout. The format is specific to each hook type.
|
|
81
|
+
|
|
82
|
+
### PreToolUse Output
|
|
83
|
+
|
|
84
|
+
Use the shared hook utilities — never construct JSON manually:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { emitContext, emitContextAndBlock } from "../../_shared/lib-ts/base/hook-utils.js";
|
|
88
|
+
|
|
89
|
+
// Inject context without blocking:
|
|
90
|
+
emitContext("Information for Claude to see...");
|
|
91
|
+
|
|
92
|
+
// Block the tool call with context and reason:
|
|
93
|
+
emitContextAndBlock(
|
|
94
|
+
"Review feedback for Claude to see...",
|
|
95
|
+
"Reason shown to Claude for the denial",
|
|
96
|
+
);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
**Key insight:** The old `decision`/`reason` format fails silently. If your hook isn't affecting Claude's behavior, check the output format first. Only `hookSpecificOutput` with `additionalContext`, `permissionDecision`, and `permissionDecisionReason` fields are recognized.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Debugging Output
|
|
104
|
+
|
|
105
|
+
For logging tiers, visibility rules, and stderr behavior, see **`_shared/lib-ts/CLAUDE.md`** (the shared library guide). The key rules:
|
|
106
|
+
|
|
107
|
+
- **stderr is opt-in.** `log_debug/log_info/log_warn/log_error` write to file only (no UI noise)
|
|
108
|
+
- **`logBlocking()` / `log_hook_error()`** for problems that must be visible
|
|
109
|
+
- **`eprint()`** for terminal-only UX (not logged to JSONL)
|
|
110
|
+
- **`print()` corrupts stdout** — never use for diagnostics
|
|
111
|
+
|
|
112
|
+
TypeScript hooks use re-exported logger functions from `hook-utils.ts`:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { logDebug, logInfo, logWarn, logError } from "../../_shared/lib-ts/base/hook-utils.js";
|
|
116
|
+
|
|
117
|
+
logDebug("hook-name", `Found ${items.length} items`); // file only
|
|
118
|
+
logInfo("hook-name", "Starting hook..."); // file only
|
|
119
|
+
logError("hook-name", `Failed: ${e}`); // file only
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Context System Integration
|
|
125
|
+
|
|
126
|
+
Plan review hooks integrate with the shared context system for state management:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { getContextBySessionId, getAllContexts } from "../../_shared/lib-ts/context/context-store.js";
|
|
130
|
+
import { getContextReviewsDir } from "../../_shared/lib-ts/base/constants.js";
|
|
131
|
+
|
|
132
|
+
// Find active context
|
|
133
|
+
const context = getContextBySessionId(sessionId, projectRoot);
|
|
134
|
+
if (!context) {
|
|
135
|
+
// Fallback: find single planning context
|
|
136
|
+
const allActive = getAllContexts("active", projectRoot);
|
|
137
|
+
const planning = allActive.filter((c: any) => c.mode === "active" || c.mode === "has_plan");
|
|
138
|
+
if (planning.length === 1) {
|
|
139
|
+
context = planning[0];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Get reviews directory for this context
|
|
144
|
+
const reviewsDir = getContextReviewsDir(context.id, projectRoot);
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
CC-native specific state is accessed via `cc-native-state.ts`:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { isPlanAlreadyReviewed, markPlanReviewed, wasQuestionsAsked } from "../lib-ts/cc-native-state.js";
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Error Handling
|
|
156
|
+
|
|
157
|
+
Hooks should fail gracefully — a broken hook shouldn't break the user's workflow. `runHook()` and `runHookAsync()` handle this automatically: uncaught errors log to file and exit 0 (non-blocking).
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
import { runHook, logInfo } from "../../_shared/lib-ts/base/hook-utils.js";
|
|
161
|
+
|
|
162
|
+
function main(): void {
|
|
163
|
+
// Hook logic — uncaught errors are handled by runHook
|
|
164
|
+
logInfo("hook-name", "Starting...");
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
runHook(main, "hook_name");
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
For async hooks (plan review with parallel agents):
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import { runHookAsync } from "../../_shared/lib-ts/base/hook-utils.js";
|
|
174
|
+
|
|
175
|
+
async function main(): Promise<void> {
|
|
176
|
+
// Async hook logic with Promise.all() etc.
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
runHookAsync(main, "hook_name");
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Use `emitContextAndBlock()` for intentional blocking (e.g., plan review denial). `hookEventName` is auto-detected.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Error Handling: Non-Critical Operations
|
|
187
|
+
|
|
188
|
+
Wrap non-critical shared library calls in try/catch to prevent false "hook error" UI display. See **`_shared/lib-ts/CLAUDE.md`** > Context Store for the pattern and rationale.
|
|
189
|
+
|
|
190
|
+
**When to catch locally vs let bubble:**
|
|
191
|
+
- **Catch locally:** Side effects like mode transitions, state saves — the hook's primary purpose can still succeed without them
|
|
192
|
+
- **Let bubble:** Core operations where failure means the hook genuinely can't do its job
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## DO NOT
|
|
197
|
+
|
|
198
|
+
These are reminders based on past issues. Not enforcement rules.
|
|
199
|
+
|
|
200
|
+
- **Don't modify hook output format** without verifying the current Claude Code hook API (it changes between versions)
|
|
201
|
+
- **Don't use `process.exit(1)` or `process.exit(2)`** for non-fatal errors - it blocks the user's workflow
|
|
202
|
+
- **Don't forget template sync** after modifying hooks in `.aiwcli/` - changes should also go to `packages/cli/src/templates/cc-native/`
|
|
203
|
+
- **Don't use `console.log()`** for anything — it corrupts stdout. Use `emitContext()` for hook output
|
|
204
|
+
- **Don't assume session_id format** - it can be UUID, path-like, or other formats
|
|
205
|
+
- **Don't skip `is_internal_call()` check** - recursive hook execution causes state corruption
|
|
206
|
+
- **Don't hardcode paths** - use `getProjectRoot()` and relative imports
|
|
207
|
+
- **Don't let non-critical operations bubble to `runHook`** - catch locally to prevent stderr "hook error" display
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Verification After Changes
|
|
212
|
+
|
|
213
|
+
Validate TypeScript syntax after editing hooks:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Quick syntax check via bun
|
|
217
|
+
bun --print "import('.aiwcli/_cc-native/hooks/cc-native-plan-review.ts')" 2>&1 | head -5
|
|
218
|
+
|
|
219
|
+
# Or check imports resolve (dry run)
|
|
220
|
+
bun build --no-bundle .aiwcli/_cc-native/hooks/add_plan_context.ts --outdir /dev/null 2>&1
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Hooks fail silently on import errors — verify after any import path changes.
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Changelog
|
|
228
|
+
|
|
229
|
+
<!-- Add dated entries as new issues are discovered -->
|
|
230
|
+
|
|
231
|
+
| Date | Change |
|
|
232
|
+
|------|--------|
|
|
233
|
+
| 2026-02-14 | **Plan review hook refactored into focused modules.** `cc-native-plan-review.ts` reduced from 1061 to ~70 lines (thin coordinator). Core logic moved to `review-pipeline.ts`. Extracted: `plan-discovery.ts`, `settings.ts`, `agent-selection.ts`, `graduation.ts`, `output-builder.ts`. Split `artifacts.ts` (822 lines) into `artifacts/format.ts`, `artifacts/write.ts`, `artifacts/tracker.ts` with barrel re-export. Added `loadIterationState()`/`saveIterationState()` to `state.ts`. New pipeline types in `types.ts`. |
|
|
234
|
+
| 2026-02-14 | **Questions gate added to plan review.** `cc-native-plan-review.ts` now runs a fresh-context plan-questions agent before plan review. If `wasQuestionsAsked()` returns false, the PLAN-QUESTIONER agent (from `agents/plan-questions/`) generates questions/assumptions/ambiguities using `QUESTIONS_SCHEMA`. On questions found, ExitPlanMode is denied with question list as context. New library module: `lib-ts/plan-questions.ts`. Agent directory reorganized: review agents moved to `agents/plan-review/`, question agents in `agents/plan-questions/`. |
|
|
235
|
+
| 2026-02-10 | **Migrated cc-native hooks from Python to TypeScript.** `cc-native-plan-review.ts` (async, parallel agent reviews via `Promise.all()`), `add_plan_context.ts`, `plan_questions_early.ts`. All hooks use `runHook()`/`runHookAsync()` entry points. Library code in `_cc-native/lib-ts/` (18 files). Settings.json updated to use `bun` runner. Python `.py` files kept as fallback until TS hooks verified. |
|
|
236
|
+
| 2026-02-10 | Flipped TS logger stderr default to opt-in (`opts?.stderr === true`). Added `logBlocking()` for intentional stderr visibility. Removed redundant `{stderr: false}` from hook-utils.ts, user_prompt_submit.ts, context_monitor.ts. Added "Hook Error Visibility" section documenting visibility tiers and exit code behavior. |
|
|
237
|
+
| 2026-02-10 | Fixed `debug.py` `context_path` crash. Added local try/catch around `maybeActivate` in `user_prompt_submit.ts` and `context_monitor.ts` to prevent stderr error display on non-critical I/O failures. Removed dead `context_path` from `_emitHookEnd` in `hook-utils.ts`. Added "Error Handling" section to CLAUDE.md. |
|
|
238
|
+
| 2026-02-07 | Handoff staging lifecycle: `has_handoff` mode + `handoff_consumed` flag mirrors plan lifecycle. `save_handoff.py` no longer transitions to idle — stays active for session_end staging. `session_end.py` stages `active→has_handoff` when handoff_path set and not consumed. `session_start.py` restores `has_handoff→active` on /clear. `context_selector.py` has fallback Case 3b for has_handoff. PostToolUse context_monitor matcher simplified from specific tool list to `*`. |
|
|
239
|
+
| 2026-02-07 | Removed PreToolUse:Write matcher from `add_plan_context.py`. Write-time plan nudges were redundant after consolidating enforcement to PreToolUse:Task. Removed `is_plan_file_write()`, `load_plan_context_config()`, `PHASE_B_ENFORCEMENT`, `nudge_write_questions()`, and `project_dir` import. |
|
|
240
|
+
| 2026-02-07 | Question enforcement is now advisory-only (never blocks). `add_plan_context.py` uses `emit_context()` for all question nudges — no `permissionDecision:deny` anywhere. Removed `emit_context_and_block` import and `TASK_ENFORCEMENT_REASON` constant. |
|
|
241
|
+
| 2026-02-07 | Moved question enforcement to PreToolUse:Task (Plan subagent gate). `add_plan_context.py` now handles three events: PostToolUse:AskUserQuestion, PreToolUse:Task (primary gate), PreToolUse:Write (fallback). Added `is_plan_task()`, `is_internal_call()` guard, `TASK_ENFORCEMENT_CONTEXT` constant. Registered `^Task$` command hook in settings.json. |
|
|
242
|
+
| 2026-02-07 | Deleted `plan_accepted.py` (dead code — PostToolUse:ExitPlanMode never fires due to /clear race). Plan field assignment handled by `session_end.py` fallback. Added `plan_consumed` flag to prevent infinite plan re-staging. |
|
|
243
|
+
| 2026-02-07 | Hook lifecycle diagnostics: all hooks now use `run_hook(main, "hook_name")` entry point. Logs HOOK_START/HOOK_END with template origin, event type, duration_ms, and status. Millisecond timestamps in logger. |
|
|
244
|
+
| 2026-02-07 | Unified logger: all diagnostic logging uses `log_debug/log_info/log_warn/log_error` from `_shared/lib/base/logger.py` instead of eprint/print-to-stderr. Updated debugging and error handling docs. |
|
|
245
|
+
| 2026-02-06 | Merged mark_questions_asked.py into add_plan_context.py. Hook now handles both PostToolUse:AskUserQuestion and PreToolUse:Write. Deleted standalone mark_questions_asked.py. |
|
|
246
|
+
| 2026-02-06 | Fixed add_plan_context.py trigger docs (was PostToolUse: EnterPlanMode, is PreToolUse: Write). Added emit_context/emit_context_and_block utility docs. |
|
|
247
|
+
| 2026-02-03 | Initial creation |
|