aiwcli 0.10.3 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/bin/run.js +1 -1
  2. package/dist/commands/clear.js +28 -131
  3. package/dist/commands/init/index.js +3 -3
  4. package/dist/lib/gitignore-manager.d.ts +32 -0
  5. package/dist/lib/gitignore-manager.js +141 -2
  6. package/dist/templates/CLAUDE.md +8 -8
  7. package/dist/templates/_shared/.claude/commands/handoff-resume.md +64 -0
  8. package/dist/templates/_shared/.claude/commands/handoff.md +16 -10
  9. package/dist/templates/_shared/.claude/settings.json +7 -7
  10. package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +2 -0
  11. package/dist/templates/_shared/hooks-ts/archive_plan.ts +159 -0
  12. package/dist/templates/_shared/hooks-ts/context_monitor.ts +147 -0
  13. package/dist/templates/_shared/hooks-ts/file-suggestion.ts +130 -0
  14. package/dist/templates/_shared/hooks-ts/pre_compact.ts +49 -0
  15. package/dist/templates/_shared/hooks-ts/session_end.ts +107 -0
  16. package/dist/templates/_shared/hooks-ts/session_start.ts +144 -0
  17. package/dist/templates/_shared/hooks-ts/task_create_capture.ts +48 -0
  18. package/dist/templates/_shared/hooks-ts/task_update_capture.ts +74 -0
  19. package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +83 -0
  20. package/dist/templates/_shared/lib-ts/CLAUDE.md +318 -0
  21. package/dist/templates/_shared/lib-ts/base/atomic-write.ts +12 -12
  22. package/dist/templates/_shared/lib-ts/base/constants.ts +22 -15
  23. package/dist/templates/_shared/lib-ts/base/git-state.ts +1 -1
  24. package/dist/templates/_shared/lib-ts/base/hook-utils.ts +129 -50
  25. package/dist/templates/_shared/lib-ts/base/inference.ts +28 -21
  26. package/dist/templates/_shared/lib-ts/base/logger.ts +15 -2
  27. package/dist/templates/_shared/lib-ts/base/state-io.ts +9 -7
  28. package/dist/templates/_shared/lib-ts/base/stop-words.ts +131 -131
  29. package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +142 -0
  30. package/dist/templates/_shared/lib-ts/base/utils.ts +69 -69
  31. package/dist/templates/_shared/lib-ts/context/context-formatter.ts +30 -24
  32. package/dist/templates/_shared/lib-ts/context/context-selector.ts +50 -32
  33. package/dist/templates/_shared/lib-ts/context/context-store.ts +76 -48
  34. package/dist/templates/_shared/lib-ts/context/plan-manager.ts +43 -23
  35. package/dist/templates/_shared/lib-ts/context/task-tracker.ts +10 -6
  36. package/dist/templates/_shared/lib-ts/handoff/document-generator.ts +11 -10
  37. package/dist/templates/_shared/lib-ts/handoff/handoff-reader.ts +158 -0
  38. package/dist/templates/_shared/lib-ts/templates/formatters.ts +6 -4
  39. package/dist/templates/_shared/lib-ts/types.ts +68 -55
  40. package/dist/templates/_shared/scripts/resolve_context.ts +24 -0
  41. package/dist/templates/_shared/scripts/resume_handoff.ts +345 -0
  42. package/dist/templates/_shared/scripts/save_handoff.ts +3 -3
  43. package/dist/templates/_shared/scripts/status_line.ts +687 -0
  44. package/dist/templates/cc-native/.claude/settings.json +175 -185
  45. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +15 -17
  46. package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +0 -2
  47. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +109 -135
  48. package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.ts +119 -0
  49. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +1027 -0
  50. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +61 -0
  51. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +156 -0
  52. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +792 -0
  53. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +199 -0
  54. package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +144 -0
  55. package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +57 -0
  56. package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +83 -0
  57. package/dist/templates/cc-native/_cc-native/lib-ts/corroboration.ts +115 -0
  58. package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +80 -0
  59. package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +120 -0
  60. package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +168 -0
  61. package/dist/templates/cc-native/_cc-native/lib-ts/nul +3 -0
  62. package/dist/templates/cc-native/_cc-native/lib-ts/orchestrator.ts +250 -0
  63. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/agent.ts +275 -0
  64. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/codex.ts +130 -0
  65. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/gemini.ts +107 -0
  66. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/index.ts +10 -0
  67. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/types.ts +23 -0
  68. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +240 -0
  69. package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +18 -0
  70. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +385 -0
  71. package/dist/templates/cc-native/_cc-native/lib-ts/verdict.ts +72 -0
  72. package/dist/templates/cc-native/_cc-native/plan-review.config.json +14 -1
  73. package/oclif.manifest.json +1 -1
  74. package/package.json +2 -2
  75. package/dist/templates/_shared/hooks/__init__.py +0 -16
  76. package/dist/templates/_shared/hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  77. package/dist/templates/_shared/hooks/__pycache__/archive_plan.cpython-313.pyc +0 -0
  78. package/dist/templates/_shared/hooks/__pycache__/context_enforcer.cpython-313.pyc +0 -0
  79. package/dist/templates/_shared/hooks/__pycache__/context_monitor.cpython-313.pyc +0 -0
  80. package/dist/templates/_shared/hooks/__pycache__/file-suggestion.cpython-313.pyc +0 -0
  81. package/dist/templates/_shared/hooks/__pycache__/pre_compact.cpython-313.pyc +0 -0
  82. package/dist/templates/_shared/hooks/__pycache__/session_end.cpython-313.pyc +0 -0
  83. package/dist/templates/_shared/hooks/__pycache__/session_start.cpython-313.pyc +0 -0
  84. package/dist/templates/_shared/hooks/__pycache__/task_create_atomicity.cpython-313.pyc +0 -0
  85. package/dist/templates/_shared/hooks/__pycache__/task_create_capture.cpython-313.pyc +0 -0
  86. package/dist/templates/_shared/hooks/__pycache__/task_update_capture.cpython-313.pyc +0 -0
  87. package/dist/templates/_shared/hooks/__pycache__/user_prompt_submit.cpython-313.pyc +0 -0
  88. package/dist/templates/_shared/hooks/archive_plan.py +0 -177
  89. package/dist/templates/_shared/hooks/context_monitor.py +0 -270
  90. package/dist/templates/_shared/hooks/file-suggestion.py +0 -215
  91. package/dist/templates/_shared/hooks/pre_compact.py +0 -104
  92. package/dist/templates/_shared/hooks/session_end.py +0 -173
  93. package/dist/templates/_shared/hooks/session_start.py +0 -206
  94. package/dist/templates/_shared/hooks/task_create_capture.py +0 -108
  95. package/dist/templates/_shared/hooks/task_update_capture.py +0 -145
  96. package/dist/templates/_shared/hooks/user_prompt_submit.py +0 -139
  97. package/dist/templates/_shared/lib/__init__.py +0 -1
  98. package/dist/templates/_shared/lib/__pycache__/__init__.cpython-313.pyc +0 -0
  99. package/dist/templates/_shared/lib/base/__init__.py +0 -65
  100. package/dist/templates/_shared/lib/base/__pycache__/__init__.cpython-313.pyc +0 -0
  101. package/dist/templates/_shared/lib/base/__pycache__/atomic_write.cpython-313.pyc +0 -0
  102. package/dist/templates/_shared/lib/base/__pycache__/constants.cpython-313.pyc +0 -0
  103. package/dist/templates/_shared/lib/base/__pycache__/hook_utils.cpython-313.pyc +0 -0
  104. package/dist/templates/_shared/lib/base/__pycache__/inference.cpython-313.pyc +0 -0
  105. package/dist/templates/_shared/lib/base/__pycache__/logger.cpython-313.pyc +0 -0
  106. package/dist/templates/_shared/lib/base/__pycache__/stop_words.cpython-313.pyc +0 -0
  107. package/dist/templates/_shared/lib/base/__pycache__/subprocess_utils.cpython-313.pyc +0 -0
  108. package/dist/templates/_shared/lib/base/__pycache__/utils.cpython-313.pyc +0 -0
  109. package/dist/templates/_shared/lib/base/atomic_write.py +0 -180
  110. package/dist/templates/_shared/lib/base/constants.py +0 -358
  111. package/dist/templates/_shared/lib/base/hook_utils.py +0 -339
  112. package/dist/templates/_shared/lib/base/inference.py +0 -307
  113. package/dist/templates/_shared/lib/base/logger.py +0 -305
  114. package/dist/templates/_shared/lib/base/stop_words.py +0 -221
  115. package/dist/templates/_shared/lib/base/subprocess_utils.py +0 -46
  116. package/dist/templates/_shared/lib/base/utils.py +0 -263
  117. package/dist/templates/_shared/lib/context/__init__.py +0 -102
  118. package/dist/templates/_shared/lib/context/__pycache__/__init__.cpython-313.pyc +0 -0
  119. package/dist/templates/_shared/lib/context/__pycache__/cache.cpython-313.pyc +0 -0
  120. package/dist/templates/_shared/lib/context/__pycache__/context_extractor.cpython-313.pyc +0 -0
  121. package/dist/templates/_shared/lib/context/__pycache__/context_formatter.cpython-313.pyc +0 -0
  122. package/dist/templates/_shared/lib/context/__pycache__/context_manager.cpython-313.pyc +0 -0
  123. package/dist/templates/_shared/lib/context/__pycache__/context_selector.cpython-313.pyc +0 -0
  124. package/dist/templates/_shared/lib/context/__pycache__/context_store.cpython-313.pyc +0 -0
  125. package/dist/templates/_shared/lib/context/__pycache__/discovery.cpython-313.pyc +0 -0
  126. package/dist/templates/_shared/lib/context/__pycache__/event_log.cpython-313.pyc +0 -0
  127. package/dist/templates/_shared/lib/context/__pycache__/plan_archive.cpython-313.pyc +0 -0
  128. package/dist/templates/_shared/lib/context/__pycache__/plan_manager.cpython-313.pyc +0 -0
  129. package/dist/templates/_shared/lib/context/__pycache__/task_sync.cpython-313.pyc +0 -0
  130. package/dist/templates/_shared/lib/context/__pycache__/task_tracker.cpython-313.pyc +0 -0
  131. package/dist/templates/_shared/lib/context/context_formatter.py +0 -317
  132. package/dist/templates/_shared/lib/context/context_selector.py +0 -508
  133. package/dist/templates/_shared/lib/context/context_store.py +0 -653
  134. package/dist/templates/_shared/lib/context/plan_manager.py +0 -303
  135. package/dist/templates/_shared/lib/context/task_tracker.py +0 -188
  136. package/dist/templates/_shared/lib/handoff/__init__.py +0 -22
  137. package/dist/templates/_shared/lib/handoff/__pycache__/__init__.cpython-313.pyc +0 -0
  138. package/dist/templates/_shared/lib/handoff/__pycache__/document_generator.cpython-313.pyc +0 -0
  139. package/dist/templates/_shared/lib/handoff/document_generator.py +0 -278
  140. package/dist/templates/_shared/lib/templates/README.md +0 -206
  141. package/dist/templates/_shared/lib/templates/__init__.py +0 -36
  142. package/dist/templates/_shared/lib/templates/__pycache__/__init__.cpython-313.pyc +0 -0
  143. package/dist/templates/_shared/lib/templates/__pycache__/formatters.cpython-313.pyc +0 -0
  144. package/dist/templates/_shared/lib/templates/__pycache__/persona_questions.cpython-313.pyc +0 -0
  145. package/dist/templates/_shared/lib/templates/__pycache__/plan_context.cpython-313.pyc +0 -0
  146. package/dist/templates/_shared/lib/templates/formatters.py +0 -146
  147. package/dist/templates/_shared/lib/templates/plan_context.py +0 -73
  148. package/dist/templates/_shared/scripts/__pycache__/save_handoff.cpython-313.pyc +0 -0
  149. package/dist/templates/_shared/scripts/__pycache__/status_line.cpython-313.pyc +0 -0
  150. package/dist/templates/_shared/scripts/save_handoff.py +0 -357
  151. package/dist/templates/_shared/scripts/status_line.py +0 -716
  152. package/dist/templates/cc-native/.claude/commands/cc-native/fresh-perspective.md +0 -8
  153. package/dist/templates/cc-native/.windsurf/workflows/cc-native/fresh-perspective.md +0 -8
  154. package/dist/templates/cc-native/MIGRATION.md +0 -86
  155. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/add_plan_context.cpython-313.pyc +0 -0
  156. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/cc-native-plan-review.cpython-313.pyc +0 -0
  157. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/mark_questions_asked.cpython-313.pyc +0 -0
  158. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_accepted.cpython-313.pyc +0 -0
  159. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_questions_early.cpython-313.pyc +0 -0
  160. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/suggest-fresh-perspective.cpython-313.pyc +0 -0
  161. package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.py +0 -130
  162. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.py +0 -954
  163. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.py +0 -81
  164. package/dist/templates/cc-native/_cc-native/hooks/suggest-fresh-perspective.py +0 -340
  165. package/dist/templates/cc-native/_cc-native/lib/CLAUDE.md +0 -265
  166. package/dist/templates/cc-native/_cc-native/lib/__init__.py +0 -53
  167. package/dist/templates/cc-native/_cc-native/lib/__pycache__/__init__.cpython-313.pyc +0 -0
  168. package/dist/templates/cc-native/_cc-native/lib/__pycache__/atomic_write.cpython-313.pyc +0 -0
  169. package/dist/templates/cc-native/_cc-native/lib/__pycache__/constants.cpython-313.pyc +0 -0
  170. package/dist/templates/cc-native/_cc-native/lib/__pycache__/debug.cpython-313.pyc +0 -0
  171. package/dist/templates/cc-native/_cc-native/lib/__pycache__/orchestrator.cpython-313.pyc +0 -0
  172. package/dist/templates/cc-native/_cc-native/lib/__pycache__/state.cpython-313.pyc +0 -0
  173. package/dist/templates/cc-native/_cc-native/lib/__pycache__/utils.cpython-313.pyc +0 -0
  174. package/dist/templates/cc-native/_cc-native/lib/constants.py +0 -45
  175. package/dist/templates/cc-native/_cc-native/lib/debug.py +0 -139
  176. package/dist/templates/cc-native/_cc-native/lib/orchestrator.py +0 -362
  177. package/dist/templates/cc-native/_cc-native/lib/reviewers/__init__.py +0 -28
  178. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/__init__.cpython-313.pyc +0 -0
  179. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/agent.cpython-313.pyc +0 -0
  180. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/base.cpython-313.pyc +0 -0
  181. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/codex.cpython-313.pyc +0 -0
  182. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/gemini.cpython-313.pyc +0 -0
  183. package/dist/templates/cc-native/_cc-native/lib/reviewers/agent.py +0 -215
  184. package/dist/templates/cc-native/_cc-native/lib/reviewers/base.py +0 -88
  185. package/dist/templates/cc-native/_cc-native/lib/reviewers/codex.py +0 -124
  186. package/dist/templates/cc-native/_cc-native/lib/reviewers/gemini.py +0 -108
  187. package/dist/templates/cc-native/_cc-native/lib/state.py +0 -268
  188. package/dist/templates/cc-native/_cc-native/lib/utils.py +0 -1071
  189. package/dist/templates/cc-native/_cc-native/scripts/__pycache__/aggregate_agents.cpython-313.pyc +0 -0
  190. package/dist/templates/cc-native/_cc-native/scripts/aggregate_agents.py +0 -168
  191. package/dist/templates/cc-native/_cc-native/workflows/fresh-perspective.md +0 -134
@@ -1,8 +0,0 @@
1
- ---
2
- description: Get an unbiased perspective on a problem without code context
3
- ---
4
- # Fresh Perspective
5
-
6
- Get a fresh, unbiased perspective on a problem by stripping away implementation details that could anchor your thinking to current patterns.
7
-
8
- Load and execute `_cc-native/workflows/fresh-perspective.md`.
@@ -1,8 +0,0 @@
1
- ---
2
- description: Get an unbiased perspective on a problem without code context
3
- ---
4
- # Fresh Perspective
5
-
6
- Get a fresh, unbiased perspective on a problem by stripping away implementation details that could anchor your thinking to current patterns.
7
-
8
- Load and execute `_cc-native/workflows/fresh-perspective.md`.
@@ -1,86 +0,0 @@
1
- # CC-Native v1.5.0 Migration Guide
2
-
3
- ## Breaking Change: Context-Integrated Plan Review
4
-
5
- **Before (v1.4.0):** Reviews stored in `_output/cc-native/plans/{date}/{slug}/reviews/`
6
- **After (v1.5.0):** Reviews stored in `_output/contexts/{context_id}/reviews/`
7
-
8
- ### What Changed
9
-
10
- 1. **Removed `set_plan_state.py`** - No longer needed. Plan review now integrates with the shared context system.
11
-
12
- 2. **Iteration state** - Now stored in `_output/contexts/{context_id}/reviews/iteration.json` instead of `~/.claude/plans/*.state.json`
13
-
14
- 3. **Review output** - Written to context reviews folder when a context is active, with legacy fallback for backward compatibility.
15
-
16
- ### Migration Steps
17
-
18
- **Automatic migration** - No action required. The hook will:
19
- - Use context reviews folder when an active context exists
20
- - Fall back to legacy path if no context found
21
- - Existing reviews remain in their original locations
22
-
23
- ---
24
-
25
- ## v1.4.0 Migration (Previous)
26
-
27
- ### Configuration File Rename
28
-
29
- **Before (v1.3.0):** `_cc-native/config.json`
30
- **After (v1.4.0):** `_cc-native/plan-review.config.json`
31
-
32
- ```bash
33
- cd _cc-native
34
- mv config.json plan-review.config.json
35
- ```
36
-
37
- ---
38
-
39
- ## Features
40
-
41
- ### Context-Integrated Reviews (v1.5.0)
42
- - Reviews written to `_output/contexts/{context_id}/reviews/`
43
- - Iteration state persists across sessions in context folder
44
- - Automatic context selection via session_id or single active context
45
-
46
- ### Atomic Writes
47
- - Cross-platform atomic file writes (Windows + POSIX)
48
- - Retry logic with backoff
49
- - Error markers for debugging
50
-
51
- **No action required** - Enabled by default via `CC_NATIVE_ROBUST_WRITES=true`.
52
-
53
- ---
54
-
55
- ## Upgrade Checklist
56
-
57
- - [ ] Test plan workflow: exit plan mode → review → archive
58
- - [ ] Verify reviews appear in `_output/contexts/{context_id}/reviews/`
59
- - [ ] Check iteration tracking persists across plan revisions
60
-
61
- ---
62
-
63
- ## Rollback
64
-
65
- If you need to revert to v1.4.0:
66
-
67
- ```bash
68
- git checkout v1.4.0 -- _cc-native/
69
- ```
70
-
71
- **Note:** Existing reviews in context folders will remain but won't be used.
72
-
73
- ---
74
-
75
- ## What Stays the Same
76
-
77
- - Workflow files (`_cc-native/workflows/*.md`)
78
- - Agent definitions (`.claude/agents/cc-native/`)
79
- - All slash commands (`/cc-native:*`)
80
- - Plan archiving behavior (`archive_plan.py`)
81
-
82
- ---
83
-
84
- ## Questions?
85
-
86
- See TEMPLATE-SCHEMA.md for full documentation or report issues at the project repository.
@@ -1,130 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Plan context hook - handles question marking and advisory question nudges.
4
-
5
- Registered for two events:
6
- - PostToolUse: AskUserQuestion — marks that questions were asked this session.
7
- - PreToolUse: Task — nudges Plan subagent to ask questions first (advisory, never blocks).
8
-
9
- All enforcement is advisory: injects additionalContext to guide Claude toward asking
10
- non-obvious questions, but never blocks the tool call. Claude can proceed regardless.
11
-
12
- Fail-safe: Any error allows the action silently.
13
- """
14
-
15
- import json
16
- import sys
17
- from pathlib import Path
18
- from typing import Any, Dict
19
-
20
- # Add lib directories to path for imports
21
- _hook_dir = Path(__file__).resolve().parent
22
- _cc_native_lib_dir = _hook_dir.parent / "lib"
23
- _shared_lib_dir = _hook_dir.parent.parent / "_shared" / "lib"
24
- sys.path.insert(0, str(_cc_native_lib_dir))
25
- sys.path.insert(0, str(_shared_lib_dir))
26
-
27
- from utils import (
28
- mark_questions_asked,
29
- was_questions_asked,
30
- )
31
- from base.hook_utils import emit_context
32
- from base.subprocess_utils import is_internal_call
33
- from base.logger import log_debug, log_info, log_warn, log_error, log_diagnostic
34
- from templates.plan_context import get_evaluation_context_reminder
35
-
36
-
37
- def is_plan_task(payload: Dict[str, Any]) -> bool:
38
- """Check if this Task call spawns a Plan subagent."""
39
- tool_input = payload.get("tool_input", {})
40
- return str(tool_input.get("subagent_type", "")) == "Plan"
41
-
42
-
43
- CONTEXT_REMINDER = get_evaluation_context_reminder()
44
-
45
-
46
- def inject_evaluation_context() -> int:
47
- """Inject evaluation context reminder without blocking."""
48
- emit_context(CONTEXT_REMINDER)
49
- return 0
50
-
51
-
52
- TASK_ENFORCEMENT_CONTEXT = (
53
- "Before spawning a Plan agent, consider asking the user non-obvious questions "
54
- "via AskUserQuestion. Code exploration reveals WHAT exists — questions reveal WHAT MATTERS.\n\n"
55
- "Generate 5+ candidate questions across these categories, then keep only 3-4 where "
56
- "different answers would lead to meaningfully different plans:\n\n"
57
- "1. INTENT & SUCCESS CRITERIA — What does 'done well' look like? Are there multiple "
58
- "interpretations of this request? What's a 10 vs a 6?\n\n"
59
- "2. CONSTRAINTS & HISTORY — Has this been attempted before? Are there off-limits areas, "
60
- "performance requirements, or security considerations not visible in the code?\n\n"
61
- "3. TRADE-OFF PREFERENCES — Speed vs thoroughness? Minimal change vs clean architecture? "
62
- "Backward compatibility vs clean break?\n\n"
63
- "Frame each question with 2-3 concrete options so the user can choose rather than compose. "
64
- "Use AskUserQuestion with structured options — never ask questions as inline text."
65
- )
66
-
67
-
68
- def nudge_task_questions() -> int:
69
- """Advise Claude to ask questions before spawning Plan agent (never blocks)."""
70
- emit_context(TASK_ENFORCEMENT_CONTEXT)
71
- return 0
72
-
73
-
74
- def main() -> int:
75
- # Guard: skip for internal subprocess calls (prevents recursive hook execution)
76
- if is_internal_call():
77
- return 0
78
-
79
- try:
80
- payload = json.load(sys.stdin)
81
- except json.JSONDecodeError:
82
- return 0 # Fail-safe
83
-
84
- tool_name = payload.get("tool_name")
85
- hook_event = payload.get("hook_event_name", "unknown")
86
- log_diagnostic("add_plan_context", "receive", f"tool={tool_name}, event={hook_event}",
87
- inputs={"tool_name": tool_name, "hook_event": hook_event})
88
-
89
- # PostToolUse: AskUserQuestion — mark that questions were asked
90
- if tool_name == "AskUserQuestion":
91
- session_id = str(payload.get("session_id", ""))
92
- if session_id:
93
- mark_questions_asked(session_id)
94
- log_info("add_plan_context", f"Marked questions asked for session {session_id[:8]}...")
95
- return 0
96
-
97
- # PreToolUse: Task — nudge Plan subagent to ask questions first (advisory)
98
- if tool_name == "Task":
99
- if not is_plan_task(payload):
100
- return 0 # Only gate Plan subagent spawns
101
-
102
- permission_mode = payload.get("permission_mode", "")
103
- if permission_mode != "plan":
104
- return 0 # Only enforce during plan mode
105
-
106
- session_id = payload.get("session_id")
107
- if not session_id:
108
- log_debug("add_plan_context", "No session_id for Task gate, skipping enforcement")
109
- return 0
110
-
111
- session_id_str = str(session_id)
112
-
113
- if was_questions_asked(session_id_str):
114
- log_info("add_plan_context", "Questions asked, allowing Plan Task with eval context")
115
- log_diagnostic("add_plan_context", "decide", "Questions asked, allowing Plan Task",
116
- decision="allow_with_context", reasoning="was_questions_asked=True")
117
- return inject_evaluation_context()
118
-
119
- # Questions NOT asked: nudge toward asking questions (advisory only)
120
- log_info("add_plan_context", "Questions not asked - nudging Plan Task to ask first")
121
- log_diagnostic("add_plan_context", "decide", "Questions not asked, nudging Plan Task",
122
- decision="nudge", reasoning="was_questions_asked=False, advisory context")
123
- return nudge_task_questions()
124
-
125
- return 0
126
-
127
-
128
- if __name__ == "__main__":
129
- from base.hook_utils import run_hook
130
- run_hook(main, "add_plan_context")