aiwcli 0.9.7 → 0.10.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/bin/run.js +5 -2
- package/dist/lib/claude-settings-types.d.ts +2 -0
- package/dist/templates/CLAUDE.md +49 -18
- package/dist/templates/_shared/.claude/settings.json +4 -0
- package/dist/templates/_shared/hooks/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/archive_plan.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/context_enforcer.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/context_monitor.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/file-suggestion.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/pre_compact.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/session_end.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/session_start.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/task_create_atomicity.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/task_create_capture.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/task_update_capture.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/__pycache__/user_prompt_submit.cpython-313.pyc +0 -0
- package/dist/templates/_shared/hooks/archive_plan.py +87 -178
- package/dist/templates/_shared/hooks/context_monitor.py +128 -194
- package/dist/templates/_shared/hooks/file-suggestion.py +26 -23
- package/dist/templates/_shared/hooks/pre_compact.py +104 -0
- package/dist/templates/_shared/hooks/session_end.py +154 -0
- package/dist/templates/_shared/hooks/session_start.py +145 -59
- package/dist/templates/_shared/hooks/task_create_capture.py +26 -49
- package/dist/templates/_shared/hooks/task_update_capture.py +42 -100
- package/dist/templates/_shared/hooks/user_prompt_submit.py +63 -77
- package/dist/templates/_shared/lib/base/__init__.py +16 -0
- package/dist/templates/_shared/lib/base/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/constants.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/hook_utils.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/inference.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/logger.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/__pycache__/utils.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/base/constants.py +18 -4
- package/dist/templates/_shared/lib/base/hook_utils.py +199 -11
- package/dist/templates/_shared/lib/base/inference.py +121 -0
- package/dist/templates/_shared/lib/base/logger.py +291 -0
- package/dist/templates/_shared/lib/base/utils.py +49 -11
- package/dist/templates/_shared/lib/context/__init__.py +72 -80
- package/dist/templates/_shared/lib/context/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_formatter.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_manager.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_selector.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/context_store.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/discovery.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/plan_manager.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/__pycache__/task_tracker.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/context/context_formatter.py +316 -0
- package/dist/templates/_shared/lib/context/context_selector.py +491 -0
- package/dist/templates/_shared/lib/context/context_store.py +636 -0
- package/dist/templates/_shared/lib/context/plan_manager.py +204 -0
- package/dist/templates/_shared/lib/context/task_tracker.py +188 -0
- package/dist/templates/_shared/lib/handoff/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/handoff/__pycache__/document_generator.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/handoff/document_generator.py +14 -40
- package/dist/templates/_shared/lib/templates/README.md +5 -13
- package/dist/templates/_shared/lib/templates/__init__.py +2 -6
- package/dist/templates/_shared/lib/templates/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/templates/__pycache__/formatters.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/templates/__pycache__/plan_context.cpython-313.pyc +0 -0
- package/dist/templates/_shared/lib/templates/plan_context.py +25 -79
- package/dist/templates/_shared/scripts/__pycache__/save_handoff.cpython-313.pyc +0 -0
- package/dist/templates/_shared/scripts/__pycache__/status_line.cpython-313.pyc +0 -0
- package/dist/templates/_shared/scripts/save_handoff.py +39 -19
- package/dist/templates/_shared/scripts/status_line.py +701 -0
- package/dist/templates/_shared/workflows/handoff.md +9 -3
- package/dist/templates/cc-native/.claude/settings.json +64 -9
- package/dist/templates/cc-native/CC-NATIVE-README.md +25 -28
- package/dist/templates/cc-native/MIGRATION.md +1 -1
- package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +14 -39
- package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +1 -1
- package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +57 -22
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/add_plan_context.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/cc-native-plan-review.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/mark_questions_asked.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_accepted.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_questions_early.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/suggest-fresh-perspective.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.py +57 -57
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.py +208 -158
- package/dist/templates/cc-native/_cc-native/hooks/plan_accepted.py +127 -0
- package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.py +81 -0
- package/dist/templates/cc-native/_cc-native/hooks/suggest-fresh-perspective.py +26 -25
- package/dist/templates/cc-native/_cc-native/lib/CLAUDE.md +35 -10
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/constants.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/debug.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/orchestrator.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/state.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/__pycache__/utils.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/debug.py +37 -22
- package/dist/templates/cc-native/_cc-native/lib/orchestrator.py +103 -42
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/__init__.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/agent.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/base.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/codex.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/gemini.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/reviewers/agent.py +26 -21
- package/dist/templates/cc-native/_cc-native/lib/reviewers/codex.py +12 -7
- package/dist/templates/cc-native/_cc-native/lib/reviewers/gemini.py +12 -7
- package/dist/templates/cc-native/_cc-native/lib/state.py +31 -16
- package/dist/templates/cc-native/_cc-native/lib/utils.py +210 -43
- package/dist/templates/cc-native/_cc-native/plan-review.config.json +1 -2
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
- package/dist/templates/_shared/hooks/context_enforcer.py +0 -625
- package/dist/templates/_shared/hooks/task_create_atomicity.py +0 -205
- package/dist/templates/_shared/lib/context/cache.py +0 -444
- package/dist/templates/_shared/lib/context/context_extractor.py +0 -115
- package/dist/templates/_shared/lib/context/context_manager.py +0 -1054
- package/dist/templates/_shared/lib/context/discovery.py +0 -444
- package/dist/templates/_shared/lib/context/event_log.py +0 -308
- package/dist/templates/_shared/lib/context/plan_archive.py +0 -101
- package/dist/templates/_shared/lib/context/task_sync.py +0 -290
- package/dist/templates/_shared/lib/templates/persona_questions.py +0 -113
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/archive_plan.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/cc-native-agent-review.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/hooks/__pycache__/test_permission_request.cpython-313.pyc +0 -0
- package/dist/templates/cc-native/_cc-native/lib/async_archive.py +0 -68
- package/dist/templates/cc-native/_cc-native/lib/atomic_write.py +0 -98
|
@@ -19,7 +19,7 @@ Generate a handoff document summarizing the current session's work, decisions, a
|
|
|
19
19
|
|
|
20
20
|
### Step 1: Get Context ID
|
|
21
21
|
|
|
22
|
-
Extract the `context_id` from the system reminder injected by the
|
|
22
|
+
Extract the `context_id` from the system reminder injected by the user_prompt_submit hook.
|
|
23
23
|
|
|
24
24
|
Look for the pattern in the system reminder:
|
|
25
25
|
```
|
|
@@ -160,8 +160,14 @@ This script:
|
|
|
160
160
|
2. Parses sections and writes sharded files (index.md, completed-work.md, dead-ends.md, etc.)
|
|
161
161
|
3. Copies the current plan (if any) to plan.md
|
|
162
162
|
4. Records the event in the context's event log (informational only)
|
|
163
|
-
|
|
164
|
-
|
|
163
|
+
5. Sets the context to dormant (`mode="idle"`) so it won't auto-select in new sessions
|
|
164
|
+
|
|
165
|
+
**After handoff is saved, the context becomes dormant:**
|
|
166
|
+
- It will **not** auto-select when starting new sessions — new work gets a fresh context
|
|
167
|
+
- It remains visible in the context picker (`^`) with a `[Handoff Ready]` label
|
|
168
|
+
- To resume, use `^N` (where N is the context number) to explicitly select it
|
|
169
|
+
- When selected via `^N`, the handoff content is automatically injected into the session
|
|
170
|
+
- The `handoff_path` is cleared after injection to prevent re-injection
|
|
165
171
|
|
|
166
172
|
## Dead Ends Section Guidelines
|
|
167
173
|
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
+
"statusLine": {
|
|
3
|
+
"type": "command",
|
|
4
|
+
"command": "python .aiwcli/_shared/scripts/status_line.py"
|
|
5
|
+
},
|
|
2
6
|
"permissions": {
|
|
3
7
|
"allow": [],
|
|
4
8
|
"deny": []
|
|
@@ -14,7 +18,7 @@
|
|
|
14
18
|
"ides": [
|
|
15
19
|
"claude"
|
|
16
20
|
],
|
|
17
|
-
"installedAt": "
|
|
21
|
+
"installedAt": "2026-01-29T01:59:02.558Z"
|
|
18
22
|
}
|
|
19
23
|
},
|
|
20
24
|
"hooks": {
|
|
@@ -29,13 +33,44 @@
|
|
|
29
33
|
]
|
|
30
34
|
}
|
|
31
35
|
],
|
|
36
|
+
"SessionEnd": [
|
|
37
|
+
{
|
|
38
|
+
"hooks": [
|
|
39
|
+
{
|
|
40
|
+
"type": "command",
|
|
41
|
+
"command": "python .aiwcli/_shared/hooks/session_end.py",
|
|
42
|
+
"timeout": 5000
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
],
|
|
47
|
+
"PreCompact": [
|
|
48
|
+
{
|
|
49
|
+
"hooks": [
|
|
50
|
+
{
|
|
51
|
+
"type": "command",
|
|
52
|
+
"command": "python .aiwcli/_shared/hooks/pre_compact.py",
|
|
53
|
+
"timeout": 5000
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
],
|
|
32
58
|
"UserPromptSubmit": [
|
|
33
59
|
{
|
|
34
60
|
"hooks": [
|
|
35
61
|
{
|
|
36
62
|
"type": "command",
|
|
37
63
|
"command": "python .aiwcli/_shared/hooks/user_prompt_submit.py",
|
|
38
|
-
"timeout":
|
|
64
|
+
"timeout": 10000
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"hooks": [
|
|
70
|
+
{
|
|
71
|
+
"type": "command",
|
|
72
|
+
"command": "python .aiwcli/_cc-native/hooks/plan_questions_early.py",
|
|
73
|
+
"timeout": 3000
|
|
39
74
|
}
|
|
40
75
|
]
|
|
41
76
|
}
|
|
@@ -57,7 +92,8 @@
|
|
|
57
92
|
{
|
|
58
93
|
"type": "command",
|
|
59
94
|
"command": "python .aiwcli/_shared/hooks/task_create_capture.py",
|
|
60
|
-
"timeout": 3000
|
|
95
|
+
"timeout": 3000,
|
|
96
|
+
"async": true
|
|
61
97
|
}
|
|
62
98
|
]
|
|
63
99
|
},
|
|
@@ -67,7 +103,8 @@
|
|
|
67
103
|
{
|
|
68
104
|
"type": "command",
|
|
69
105
|
"command": "python .aiwcli/_shared/hooks/task_update_capture.py",
|
|
70
|
-
"timeout": 3000
|
|
106
|
+
"timeout": 3000,
|
|
107
|
+
"async": true
|
|
71
108
|
}
|
|
72
109
|
]
|
|
73
110
|
},
|
|
@@ -76,7 +113,7 @@
|
|
|
76
113
|
"hooks": [
|
|
77
114
|
{
|
|
78
115
|
"type": "command",
|
|
79
|
-
"command": "python .aiwcli/
|
|
116
|
+
"command": "python .aiwcli/_cc-native/hooks/plan_accepted.py",
|
|
80
117
|
"timeout": 5000
|
|
81
118
|
}
|
|
82
119
|
]
|
|
@@ -90,6 +127,16 @@
|
|
|
90
127
|
"timeout": 5000
|
|
91
128
|
}
|
|
92
129
|
]
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"matcher": "AskUserQuestion",
|
|
133
|
+
"hooks": [
|
|
134
|
+
{
|
|
135
|
+
"type": "command",
|
|
136
|
+
"command": "python .aiwcli/_cc-native/hooks/add_plan_context.py",
|
|
137
|
+
"timeout": 3000
|
|
138
|
+
}
|
|
139
|
+
]
|
|
93
140
|
}
|
|
94
141
|
],
|
|
95
142
|
"PermissionRequest": [
|
|
@@ -106,12 +153,20 @@
|
|
|
106
153
|
],
|
|
107
154
|
"PreToolUse": [
|
|
108
155
|
{
|
|
109
|
-
"matcher": "TaskCreate",
|
|
156
|
+
"matcher": "^TaskCreate$",
|
|
110
157
|
"hooks": [
|
|
111
158
|
{
|
|
112
|
-
"type": "
|
|
113
|
-
"
|
|
114
|
-
|
|
159
|
+
"type": "prompt",
|
|
160
|
+
"prompt": "Evaluate this TaskCreate call for atomicity. Tasks become ISC criteria checked during verification — vague criteria cannot be verified, so precision matters. A well-specified task includes: (1) Explicit file paths like 'src/lib/auth.py' instead of 'the file above' or 'as discussed', (2) Specific function or component names instead of pronouns like 'it' or 'the function', (3) Clear expected state or behavior that is binary-testable in 2 seconds, (4) Concrete scope — one concern per task, not compound goals. If all four criteria are met and an agent with zero conversation history could verify the task was completed, return ok:true. If any criterion is missing, return ok:false with a response like: 'Missing context: [list each gap — e.g., no file path specified for the auth module, expected behavior is vague: what does fix the bug mean specifically, compound task should be split into separate criteria]'. When returning ok:false, end your response with: 'Retry: Re-invoke TaskCreate with a revised subject and description that address the gaps above.' This directive ensures the calling agent corrects and retries rather than abandoning the task."
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"matcher": "^Task$",
|
|
166
|
+
"hooks": [
|
|
167
|
+
{
|
|
168
|
+
"type": "prompt",
|
|
169
|
+
"prompt": "The sub-agent receives ONLY the prompt text — no conversation history, no prior context.\n\nCheck 1 — Dangling References: Does the prompt use pronouns or demonstratives that ONLY make sense with prior conversation? Violations: 'the file we looked at', 'as discussed above', 'that approach we chose', 'the error from earlier', 'fix the issue mentioned above'. NOT violations: relative paths ('_output/', 'src/lib/'), search terms ('context-manager', 'auth module'), directory exploration ('find files matching X'), tool names, or any concrete noun — even if imprecise. Only flag references that are truly UNRESOLVABLE without conversation history.\n\nCheck 2 — Implicit Contract: Does the prompt have ANY discernible goal? 'Explore the _output directory and find context files' IS a clear goal. 'Search for hooks that handle Task events' IS a clear goal. 'Read and summarize all files in X' IS a clear goal. Only flag if the prompt is truly goalless — e.g., a sentence fragment with no verb, or pure context with no request.\n\nIf both checks pass, return ok:true. When in doubt, pass — false negatives (letting a vague prompt through) are far less costly than false positives (blocking legitimate work).\n\nWhen returning ok:false, end your response with: 'Retry: Re-invoke the Task tool with a revised prompt that resolves the issues above.'"
|
|
115
170
|
}
|
|
116
171
|
]
|
|
117
172
|
},
|
|
@@ -92,29 +92,26 @@ The brackets indicate optional steps. Research only needs Clarify → Explore
|
|
|
92
92
|
|
|
93
93
|
---
|
|
94
94
|
|
|
95
|
-
## Context Management (Phase
|
|
95
|
+
## Context Management (Phase 2 - Shared Infrastructure)
|
|
96
96
|
|
|
97
|
-
CC-Native uses **
|
|
97
|
+
CC-Native uses **direct-state context management** via shared infrastructure in `_shared/`:
|
|
98
98
|
|
|
99
99
|
```
|
|
100
100
|
_output/contexts/
|
|
101
101
|
├── feature-auth/ # Context folder (method-agnostic)
|
|
102
|
-
│ ├──
|
|
103
|
-
│ ├── events.jsonl # SOURCE OF TRUTH (append-only)
|
|
102
|
+
│ ├── state.json # SOURCE OF TRUTH (direct read/write)
|
|
104
103
|
│ └── plans/ # Archived plans for this context
|
|
105
104
|
│ └── 2026-01-25-auth-plan.md
|
|
106
105
|
└── another-context/
|
|
107
|
-
|
|
108
|
-
└── events.jsonl
|
|
106
|
+
└── state.json
|
|
109
107
|
```
|
|
110
108
|
|
|
111
109
|
### Data Hierarchy
|
|
112
110
|
|
|
113
111
|
| File | Role | Notes |
|
|
114
112
|
|------|------|-------|
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
| `_output/index.json` | Global cache | Aggregates all contexts |
|
|
113
|
+
| `state.json` | **Source of truth** | Direct read/write per context |
|
|
114
|
+
| `_output/index.json` | Global cache | Fast session-to-context lookup |
|
|
118
115
|
|
|
119
116
|
### Context Schema
|
|
120
117
|
|
|
@@ -124,27 +121,25 @@ _output/contexts/
|
|
|
124
121
|
"status": "active",
|
|
125
122
|
"summary": "JWT authentication system",
|
|
126
123
|
"method": "cc-native",
|
|
127
|
-
"
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
124
|
+
"mode": "active",
|
|
125
|
+
"plan_path": "_output/contexts/feature-auth/plans/2026-01-25-auth.md",
|
|
126
|
+
"plan_hash": "a1b2c3d4",
|
|
127
|
+
"plan_signature": "approved"
|
|
132
128
|
}
|
|
133
129
|
```
|
|
134
130
|
|
|
135
|
-
###
|
|
131
|
+
### Context Modes
|
|
136
132
|
|
|
137
133
|
| Mode | Meaning |
|
|
138
134
|
|------|---------|
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `implementing` | Implementation in progress |
|
|
135
|
+
| `idle` | No active plan or work in progress |
|
|
136
|
+
| `has_plan` | Plan exists but not yet being implemented |
|
|
137
|
+
| `active` | Implementation in progress |
|
|
143
138
|
|
|
144
|
-
### Why
|
|
139
|
+
### Why 2-Layer Architecture?
|
|
145
140
|
|
|
146
|
-
- **
|
|
147
|
-
- **
|
|
141
|
+
- **Simple reads**: `state.json` is read directly, no event replay needed
|
|
142
|
+
- **Fast lookup**: `index.json` provides global session-to-context mapping without scanning directories
|
|
148
143
|
- **No orphan state**: Contexts always visible (no "in_progress" limbo)
|
|
149
144
|
- **Cross-session**: State persists across `/clear` and session restarts
|
|
150
145
|
|
|
@@ -158,7 +153,7 @@ _output/contexts/
|
|
|
158
153
|
|
|
159
154
|
**Check:**
|
|
160
155
|
1. Context exists: `ls _output/contexts/`
|
|
161
|
-
2.
|
|
156
|
+
2. State file exists: `cat _output/contexts/{id}/state.json`
|
|
162
157
|
3. Hook logs in terminal output
|
|
163
158
|
|
|
164
159
|
**Solutions:**
|
|
@@ -167,13 +162,15 @@ _output/contexts/
|
|
|
167
162
|
|
|
168
163
|
### Context Recovery
|
|
169
164
|
|
|
170
|
-
**Symptom:** `
|
|
165
|
+
**Symptom:** `state.json` appears corrupted
|
|
171
166
|
|
|
172
|
-
**
|
|
167
|
+
**WARNING:** Do NOT delete `state.json` -- it IS the source of truth and cannot be rebuilt.
|
|
168
|
+
|
|
169
|
+
**Fix:** Edit `state.json` directly to correct invalid fields, or restore from a backup:
|
|
173
170
|
```bash
|
|
174
|
-
#
|
|
175
|
-
#
|
|
176
|
-
|
|
171
|
+
# state.json is the source of truth - do NOT delete it
|
|
172
|
+
# Instead, inspect and fix the JSON manually
|
|
173
|
+
cat _output/contexts/{id}/state.json
|
|
177
174
|
```
|
|
178
175
|
|
|
179
176
|
### Notification Issues
|
|
@@ -41,7 +41,7 @@ mv config.json plan-review.config.json
|
|
|
41
41
|
### Context-Integrated Reviews (v1.5.0)
|
|
42
42
|
- Reviews written to `_output/contexts/{context_id}/reviews/`
|
|
43
43
|
- Iteration state persists across sessions in context folder
|
|
44
|
-
- Automatic context
|
|
44
|
+
- Automatic context selection via session_id or single active context
|
|
45
45
|
|
|
46
46
|
### Atomic Writes
|
|
47
47
|
- Cross-platform atomic file writes (Windows + POSIX)
|
|
@@ -10,18 +10,6 @@ CC-Native uses Claude Code's native tools with minimal workflow overhead. Plan r
|
|
|
10
10
|
|
|
11
11
|
```
|
|
12
12
|
packages/cli/src/templates/cc-native/
|
|
13
|
-
├── _shared/ # SHARED: Cross-method infrastructure (Phase 1)
|
|
14
|
-
│ ├── lib/
|
|
15
|
-
│ │ ├── base/ # Base utilities
|
|
16
|
-
│ │ │ ├── atomic_write.py # Cross-platform atomic file writes
|
|
17
|
-
│ │ │ ├── constants.py # Security and configuration constants
|
|
18
|
-
│ │ │ └── utils.py # Common functions
|
|
19
|
-
│ │ └── context/ # Context management
|
|
20
|
-
│ │ ├── context_manager.py # Context CRUD operations
|
|
21
|
-
│ │ ├── event_log.py # JSONL append/read utilities
|
|
22
|
-
│ │ └── cache.py # Cache rebuild utilities
|
|
23
|
-
│ └── hooks/
|
|
24
|
-
│ └── session_start.py # SessionStart hook (context discovery)
|
|
25
13
|
├── _cc-native/ # METHOD-SPECIFIC: CC-Native template code
|
|
26
14
|
│ ├── workflows/*.md # Workflow definitions
|
|
27
15
|
│ ├── hooks/ # Hook scripts
|
|
@@ -77,8 +65,7 @@ _output/
|
|
|
77
65
|
├── index.json # Global context cache
|
|
78
66
|
├── contexts/ # Context folders (method-agnostic)
|
|
79
67
|
│ └── {context-id}/
|
|
80
|
-
│ ├──
|
|
81
|
-
│ ├── events.jsonl # Event log (source of truth)
|
|
68
|
+
│ ├── state.json # Context state (source of truth)
|
|
82
69
|
│ └── plans/ # Archived plans for this context
|
|
83
70
|
│ └── YYYY-MM-DD-{slug}.md
|
|
84
71
|
├── cc-native/ # CC-Native specific outputs
|
|
@@ -159,7 +146,7 @@ CC-Native settings are stored in `_cc-native/plan-review.config.json`:
|
|
|
159
146
|
|
|
160
147
|
---
|
|
161
148
|
|
|
162
|
-
## Context Management (Phase 1 -
|
|
149
|
+
## Context Management (Phase 1 - State Based)
|
|
163
150
|
|
|
164
151
|
CC-Native uses **shared infrastructure** for cross-session context persistence:
|
|
165
152
|
|
|
@@ -168,22 +155,19 @@ _output/
|
|
|
168
155
|
├── index.json # CACHE: Aggregates all contexts
|
|
169
156
|
└── contexts/ # All contexts (method-agnostic)
|
|
170
157
|
├── feature-auth/
|
|
171
|
-
│ ├──
|
|
172
|
-
│ ├── events.jsonl # SOURCE OF TRUTH (append-only)
|
|
158
|
+
│ ├── state.json # SOURCE OF TRUTH: Context state
|
|
173
159
|
│ └── plans/ # Archived plans for this context
|
|
174
160
|
│ └── 2026-01-25-auth.md
|
|
175
161
|
└── another-context/
|
|
176
|
-
|
|
177
|
-
└── events.jsonl
|
|
162
|
+
└── state.json
|
|
178
163
|
```
|
|
179
164
|
|
|
180
165
|
### Data Hierarchy
|
|
181
166
|
|
|
182
167
|
| Level | File | Role | Recovery |
|
|
183
168
|
|-------|------|------|----------|
|
|
184
|
-
| 1 (Truth) | `
|
|
185
|
-
| 2 (Cache) | `
|
|
186
|
-
| 3 (Cache) | `index.json` | Global context index | Rebuild from context files |
|
|
169
|
+
| 1 (Truth) | `state.json` | Context state (source of truth) | Cannot be rebuilt |
|
|
170
|
+
| 2 (Cache) | `index.json` | Global context index | Rebuild from state files |
|
|
187
171
|
|
|
188
172
|
### Context Schema
|
|
189
173
|
|
|
@@ -213,16 +197,6 @@ _output/
|
|
|
213
197
|
| `pending_implementation` | Plan approved | Auto-continue implementation |
|
|
214
198
|
| `implementing` | Implementation active | Continue implementation |
|
|
215
199
|
|
|
216
|
-
### Event Types
|
|
217
|
-
|
|
218
|
-
```jsonl
|
|
219
|
-
{"event":"context_created","timestamp":"2026-01-20T10:00:00Z","summary":"JWT auth","method":"cc-native"}
|
|
220
|
-
{"event":"task_added","task_id":"aiw-1","subject":"Add JWT middleware","timestamp":"..."}
|
|
221
|
-
{"event":"task_completed","task_id":"aiw-1","evidence":"tests pass","timestamp":"..."}
|
|
222
|
-
{"event":"plan_created","path":"_output/contexts/.../plans/...","hash":"a1b2c3","timestamp":"..."}
|
|
223
|
-
{"event":"context_completed","timestamp":"..."}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
200
|
### Robust Writes
|
|
227
201
|
|
|
228
202
|
When `CC_NATIVE_ROBUST_WRITES=true` (default):
|
|
@@ -255,12 +229,14 @@ Hook scripts live in `_cc-native/hooks/`. IDE-specific wiring in `.claude/settin
|
|
|
255
229
|
}
|
|
256
230
|
```
|
|
257
231
|
|
|
258
|
-
**Hook order matters:**
|
|
232
|
+
**Hook order matters:** Archive runs on PermissionRequest:ExitPlanMode before reviews. If a review blocks, the archived plan is available for reference. Only plans that pass all reviews proceed to implementation.
|
|
259
233
|
|
|
260
234
|
| Hook | Trigger | Purpose |
|
|
261
235
|
|------|---------|---------|
|
|
262
236
|
| `cc-native-plan-review.py` | ExitPlanMode | Unified review: CLI + orchestrator + agents |
|
|
263
|
-
| `archive_plan.py` |
|
|
237
|
+
| `archive_plan.py` | PermissionRequest:ExitPlanMode | Archives plan content and stores hash/signature before user acceptance |
|
|
238
|
+
| `plan_accepted.py` | PostToolUse:ExitPlanMode | Sets context mode to has_plan |
|
|
239
|
+
| `plan_questions_early.py` | UserPromptSubmit | Injects Phase A clarification in plan mode |
|
|
264
240
|
|
|
265
241
|
### Claude Feedback Mechanism
|
|
266
242
|
|
|
@@ -269,11 +245,10 @@ The unified review hook returns structured JSON to Claude Code:
|
|
|
269
245
|
```json
|
|
270
246
|
{
|
|
271
247
|
"hookSpecificOutput": {
|
|
272
|
-
"
|
|
273
|
-
"
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
"reason": "Reason for blocking..."
|
|
248
|
+
"additionalContext": "Review results and recommendations...",
|
|
249
|
+
"permissionDecision": "deny",
|
|
250
|
+
"permissionDecisionReason": "Reason for blocking..."
|
|
251
|
+
}
|
|
277
252
|
}
|
|
278
253
|
```
|
|
279
254
|
|
|
@@ -21,7 +21,7 @@ Each agent file has:
|
|
|
21
21
|
- **Frontmatter (YAML):** name, model, focus, categories, enabled
|
|
22
22
|
- **Body (Markdown):** Full persona content → becomes `system_prompt` for `--system-prompt` flag
|
|
23
23
|
|
|
24
|
-
The `aggregate_agents.py` script extracts both parts. The body becomes `AgentConfig.system_prompt`.
|
|
24
|
+
The `aggregate_agents.py` script (`_cc-native/scripts/aggregate_agents.py`) extracts both parts. The body becomes `AgentConfig.system_prompt`.
|
|
25
25
|
|
|
26
26
|
## --setting-sources "" Requirement
|
|
27
27
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
| Hook | Trigger | Purpose |
|
|
10
10
|
|------|---------|---------|
|
|
11
11
|
| `cc-native-plan-review.py` | PreToolUse: ExitPlanMode | Review plans before user approval |
|
|
12
|
-
| `add_plan_context.py` | PostToolUse:
|
|
12
|
+
| `add_plan_context.py` | PostToolUse: AskUserQuestion, PreToolUse: Write | Mark questions asked; add context when writing plan files |
|
|
13
13
|
| `suggest-fresh-perspective.py` | PostToolUse | Suggest fresh perspective workflow |
|
|
14
14
|
|
|
15
15
|
---
|
|
@@ -32,6 +32,7 @@ sys.path.insert(0, str(_shared))
|
|
|
32
32
|
|
|
33
33
|
from utils import eprint, ReviewerResult
|
|
34
34
|
from lib.base.subprocess_utils import is_internal_call
|
|
35
|
+
from debug import log_debug # Context-folder debug logging
|
|
35
36
|
```
|
|
36
37
|
|
|
37
38
|
```python
|
|
@@ -70,7 +71,6 @@ import json
|
|
|
70
71
|
|
|
71
72
|
out = {
|
|
72
73
|
"hookSpecificOutput": {
|
|
73
|
-
"hookEventName": "PreToolUse",
|
|
74
74
|
"additionalContext": "Information for Claude to see...",
|
|
75
75
|
}
|
|
76
76
|
}
|
|
@@ -90,25 +90,52 @@ print(json.dumps(out, ensure_ascii=False))
|
|
|
90
90
|
|
|
91
91
|
**Key insight:** The old `decision`/`reason` format fails silently. If your hook isn't affecting Claude's behavior, check the output format first.
|
|
92
92
|
|
|
93
|
+
### Using Hook Utilities (Preferred)
|
|
94
|
+
|
|
95
|
+
Instead of manually constructing hookSpecificOutput dicts, use the shared utilities from `base.hook_utils`:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from base.hook_utils import emit_context, emit_context_and_block
|
|
99
|
+
|
|
100
|
+
# Inject context without blocking:
|
|
101
|
+
emit_context("Information for Claude to see...")
|
|
102
|
+
|
|
103
|
+
# Block the tool call with context and reason:
|
|
104
|
+
emit_context_and_block(
|
|
105
|
+
"Review feedback for Claude to see...",
|
|
106
|
+
"Reason shown to Claude for the denial"
|
|
107
|
+
)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
These handle the JSON serialization and stdout printing. `emit_context` defaults to `ensure_ascii=False`; `emit_context_and_block` defaults to `ensure_ascii=True` (safe for Windows cp1252).
|
|
111
|
+
|
|
93
112
|
---
|
|
94
113
|
|
|
95
114
|
## Debugging Output
|
|
96
115
|
|
|
97
|
-
Hooks communicate via stdout (JSON) and stderr (logs). Use
|
|
116
|
+
Hooks communicate via stdout (JSON) and stderr (logs). Use the unified logger for all diagnostic output:
|
|
98
117
|
|
|
99
118
|
```python
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
119
|
+
from base.hook_utils import log_debug, log_info, log_warn, log_error
|
|
120
|
+
|
|
121
|
+
# CORRECT - unified logger: writes to stderr AND _output/hook-log.jsonl
|
|
122
|
+
log_debug("hook-name", f"Found {len(items)} items")
|
|
123
|
+
log_info("hook-name", "Starting hook...")
|
|
124
|
+
log_warn("hook-name", f"Fallback used: {reason}")
|
|
125
|
+
log_error("hook-name", f"Failed: {e}", traceback_str=tb)
|
|
126
|
+
```
|
|
103
127
|
|
|
104
|
-
|
|
105
|
-
eprint(
|
|
128
|
+
```python
|
|
129
|
+
# ACCEPTABLE - eprint() for terminal-only UX (usage help, progress)
|
|
130
|
+
eprint("Usage: python hook.py <args>")
|
|
106
131
|
```
|
|
107
132
|
|
|
108
133
|
```python
|
|
109
134
|
# WRONG - print() goes to stdout, corrupts JSON output
|
|
110
135
|
print("Debug info") # Breaks JSON parsing
|
|
111
|
-
|
|
136
|
+
|
|
137
|
+
# WRONG - raw print to stderr instead of logger
|
|
138
|
+
print(f"Error: {e}", file=sys.stderr) # Use log_error() instead
|
|
112
139
|
```
|
|
113
140
|
|
|
114
141
|
---
|
|
@@ -140,9 +167,9 @@ reviews_dir = get_context_reviews_dir(context.id, project_root)
|
|
|
140
167
|
If context isn't found, add diagnostic logging:
|
|
141
168
|
|
|
142
169
|
```python
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
170
|
+
log_debug("hook", f"Session ID: {session_id}")
|
|
171
|
+
log_debug("hook", f"In-flight contexts: {len(in_flight)}")
|
|
172
|
+
log_debug("hook", f"Modes: {[c.in_flight.mode for c in in_flight]}")
|
|
146
173
|
```
|
|
147
174
|
|
|
148
175
|
---
|
|
@@ -152,27 +179,24 @@ eprint(f"[hook] Modes: {[c.in_flight.mode for c in in_flight]}")
|
|
|
152
179
|
Hooks should fail gracefully - a broken hook shouldn't break the user's workflow:
|
|
153
180
|
|
|
154
181
|
```python
|
|
182
|
+
from base.hook_utils import log_error, run_hook
|
|
183
|
+
|
|
155
184
|
def main() -> int:
|
|
156
185
|
try:
|
|
157
186
|
# Hook logic...
|
|
158
187
|
return 0
|
|
159
188
|
except Exception as e:
|
|
160
|
-
|
|
189
|
+
import traceback
|
|
190
|
+
tb = traceback.format_exc()
|
|
191
|
+
log_error("hook-name", str(e), traceback_str=tb)
|
|
161
192
|
# Return 0 to not block the user
|
|
162
193
|
return 0
|
|
163
194
|
|
|
164
195
|
if __name__ == "__main__":
|
|
165
|
-
|
|
166
|
-
raise SystemExit(main())
|
|
167
|
-
except Exception as e:
|
|
168
|
-
import traceback
|
|
169
|
-
eprint(f"[hook-name] FATAL: {e}")
|
|
170
|
-
traceback.print_exc(file=sys.stderr)
|
|
171
|
-
# Still exit 0 to not block - or exit 1 if blocking is intentional
|
|
172
|
-
raise SystemExit(0)
|
|
196
|
+
run_hook(main, "hook-name")
|
|
173
197
|
```
|
|
174
198
|
|
|
175
|
-
Use `sys.exit(1)` only for intentional blocking (e.g.,
|
|
199
|
+
Use `sys.exit(1)` only for intentional blocking (e.g., two-stage review decision denies the plan).
|
|
176
200
|
|
|
177
201
|
---
|
|
178
202
|
|
|
@@ -195,7 +219,14 @@ These are reminders based on past issues. Not enforcement rules.
|
|
|
195
219
|
Always validate Python syntax after editing hooks:
|
|
196
220
|
|
|
197
221
|
```bash
|
|
222
|
+
# Validate working copy
|
|
223
|
+
python -m py_compile .aiwcli/_cc-native/hooks/cc-native-plan-review.py
|
|
224
|
+
|
|
225
|
+
# Validate template copy (after sync)
|
|
198
226
|
python -m py_compile packages/cli/src/templates/cc-native/_cc-native/hooks/cc-native-plan-review.py
|
|
227
|
+
|
|
228
|
+
# Validate all shared hooks (loop required — py_compile doesn't accept globs)
|
|
229
|
+
for f in .aiwcli/_shared/hooks/*.py; do python -m py_compile "$f"; done
|
|
199
230
|
```
|
|
200
231
|
|
|
201
232
|
Hooks fail silently on syntax errors - this catches them before they reach production.
|
|
@@ -208,4 +239,8 @@ Hooks fail silently on syntax errors - this catches them before they reach produ
|
|
|
208
239
|
|
|
209
240
|
| Date | Change |
|
|
210
241
|
|------|--------|
|
|
242
|
+
| 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. |
|
|
243
|
+
| 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. |
|
|
244
|
+
| 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. |
|
|
245
|
+
| 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. |
|
|
211
246
|
| 2026-02-03 | Initial creation |
|
package/dist/templates/cc-native/_cc-native/hooks/__pycache__/add_plan_context.cpython-313.pyc
CHANGED
|
Binary file
|
package/dist/templates/cc-native/_cc-native/hooks/__pycache__/cc-native-plan-review.cpython-313.pyc
CHANGED
|
Binary file
|
package/dist/templates/cc-native/_cc-native/hooks/__pycache__/mark_questions_asked.cpython-313.pyc
ADDED
|
Binary file
|
|
Binary file
|