aiwcli 0.10.2 → 0.11.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.
Files changed (249) hide show
  1. package/bin/run.js +1 -1
  2. package/dist/commands/clear.d.ts +11 -6
  3. package/dist/commands/clear.js +229 -381
  4. package/dist/commands/init/index.d.ts +1 -17
  5. package/dist/commands/init/index.js +22 -107
  6. package/dist/lib/gitignore-manager.d.ts +32 -0
  7. package/dist/lib/gitignore-manager.js +141 -2
  8. package/dist/lib/template-installer.d.ts +7 -12
  9. package/dist/lib/template-installer.js +69 -193
  10. package/dist/lib/template-settings-reconstructor.d.ts +35 -0
  11. package/dist/lib/template-settings-reconstructor.js +130 -0
  12. package/dist/templates/CLAUDE.md +8 -8
  13. package/dist/templates/_shared/.claude/commands/handoff-resume.md +64 -0
  14. package/dist/templates/_shared/.claude/commands/handoff.md +16 -10
  15. package/dist/templates/_shared/.claude/settings.json +7 -7
  16. package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +2 -0
  17. package/dist/templates/_shared/hooks-ts/archive_plan.ts +159 -0
  18. package/dist/templates/_shared/hooks-ts/context_monitor.ts +147 -0
  19. package/dist/templates/_shared/hooks-ts/file-suggestion.ts +130 -0
  20. package/dist/templates/_shared/hooks-ts/pre_compact.ts +49 -0
  21. package/dist/templates/_shared/hooks-ts/session_end.ts +104 -0
  22. package/dist/templates/_shared/hooks-ts/session_start.ts +144 -0
  23. package/dist/templates/_shared/hooks-ts/task_create_capture.ts +48 -0
  24. package/dist/templates/_shared/hooks-ts/task_update_capture.ts +74 -0
  25. package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +83 -0
  26. package/dist/templates/_shared/lib-ts/CLAUDE.md +318 -0
  27. package/dist/templates/_shared/lib-ts/base/atomic-write.ts +138 -0
  28. package/dist/templates/_shared/lib-ts/base/constants.ts +306 -0
  29. package/dist/templates/_shared/lib-ts/base/git-state.ts +58 -0
  30. package/dist/templates/_shared/lib-ts/base/hook-utils.ts +439 -0
  31. package/dist/templates/_shared/lib-ts/base/inference.ts +252 -0
  32. package/dist/templates/_shared/lib-ts/base/logger.ts +250 -0
  33. package/dist/templates/_shared/lib-ts/base/state-io.ts +116 -0
  34. package/dist/templates/_shared/lib-ts/base/stop-words.ts +184 -0
  35. package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +162 -0
  36. package/dist/templates/_shared/lib-ts/base/utils.ts +184 -0
  37. package/dist/templates/_shared/lib-ts/context/context-formatter.ts +438 -0
  38. package/dist/templates/_shared/lib-ts/context/context-selector.ts +515 -0
  39. package/dist/templates/_shared/lib-ts/context/context-store.ts +707 -0
  40. package/dist/templates/_shared/lib-ts/context/plan-manager.ts +316 -0
  41. package/dist/templates/_shared/lib-ts/context/task-tracker.ts +185 -0
  42. package/dist/templates/_shared/lib-ts/handoff/document-generator.ts +216 -0
  43. package/dist/templates/_shared/lib-ts/handoff/handoff-reader.ts +159 -0
  44. package/dist/templates/_shared/lib-ts/package.json +21 -0
  45. package/dist/templates/_shared/lib-ts/templates/formatters.ts +104 -0
  46. package/dist/templates/_shared/{lib/templates/plan_context.py → lib-ts/templates/plan-context.ts} +14 -22
  47. package/dist/templates/_shared/lib-ts/tsconfig.json +13 -0
  48. package/dist/templates/_shared/lib-ts/types.ts +164 -0
  49. package/dist/templates/_shared/scripts/resolve_context.ts +24 -0
  50. package/dist/templates/_shared/scripts/resume_handoff.ts +321 -0
  51. package/dist/templates/_shared/scripts/save_handoff.ts +359 -0
  52. package/dist/templates/_shared/scripts/status_line.ts +733 -0
  53. package/dist/templates/cc-native/.claude/settings.json +175 -185
  54. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +15 -17
  55. package/dist/templates/cc-native/_cc-native/agents/ARCH-EVOLUTION.md +63 -0
  56. package/dist/templates/cc-native/_cc-native/agents/ARCH-PATTERNS.md +62 -0
  57. package/dist/templates/cc-native/_cc-native/agents/ARCH-STRUCTURE.md +63 -0
  58. package/dist/templates/cc-native/_cc-native/agents/{ASSUMPTION-CHAIN-TRACER.md → ASSUMPTION-TRACER.md} +6 -10
  59. package/dist/templates/cc-native/_cc-native/agents/CLARITY-AUDITOR.md +6 -10
  60. package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +74 -3
  61. package/dist/templates/cc-native/_cc-native/agents/COMPLETENESS-FEASIBILITY.md +67 -0
  62. package/dist/templates/cc-native/_cc-native/agents/COMPLETENESS-GAPS.md +71 -0
  63. package/dist/templates/cc-native/_cc-native/agents/COMPLETENESS-ORDERING.md +63 -0
  64. package/dist/templates/cc-native/_cc-native/agents/CONSTRAINT-VALIDATOR.md +73 -0
  65. package/dist/templates/cc-native/_cc-native/agents/DESIGN-ADR-VALIDATOR.md +62 -0
  66. package/dist/templates/cc-native/_cc-native/agents/DESIGN-SCALE-MATCHER.md +65 -0
  67. package/dist/templates/cc-native/_cc-native/agents/DEVILS-ADVOCATE.md +6 -9
  68. package/dist/templates/cc-native/_cc-native/agents/DOCUMENTATION-PHILOSOPHY.md +87 -0
  69. package/dist/templates/cc-native/_cc-native/agents/HANDOFF-READINESS.md +5 -9
  70. package/dist/templates/cc-native/_cc-native/agents/{HIDDEN-COMPLEXITY-DETECTOR.md → HIDDEN-COMPLEXITY.md} +6 -10
  71. package/dist/templates/cc-native/_cc-native/agents/INCREMENTAL-DELIVERY.md +67 -0
  72. package/dist/templates/cc-native/_cc-native/agents/PLAN-ORCHESTRATOR.md +91 -18
  73. package/dist/templates/cc-native/_cc-native/agents/RISK-DEPENDENCY.md +63 -0
  74. package/dist/templates/cc-native/_cc-native/agents/RISK-FMEA.md +67 -0
  75. package/dist/templates/cc-native/_cc-native/agents/RISK-PREMORTEM.md +72 -0
  76. package/dist/templates/cc-native/_cc-native/agents/RISK-REVERSIBILITY.md +75 -0
  77. package/dist/templates/cc-native/_cc-native/agents/SCOPE-BOUNDARY.md +78 -0
  78. package/dist/templates/cc-native/_cc-native/agents/SIMPLICITY-GUARDIAN.md +5 -9
  79. package/dist/templates/cc-native/_cc-native/agents/SKEPTIC.md +16 -12
  80. package/dist/templates/cc-native/_cc-native/agents/TESTDRIVEN-BEHAVIOR-AUDITOR.md +62 -0
  81. package/dist/templates/cc-native/_cc-native/agents/TESTDRIVEN-CHARACTERIZATION.md +72 -0
  82. package/dist/templates/cc-native/_cc-native/agents/TESTDRIVEN-FIRST-VALIDATOR.md +62 -0
  83. package/dist/templates/cc-native/_cc-native/agents/TESTDRIVEN-PYRAMID-ANALYZER.md +62 -0
  84. package/dist/templates/cc-native/_cc-native/agents/TRADEOFF-COSTS.md +68 -0
  85. package/dist/templates/cc-native/_cc-native/agents/TRADEOFF-STAKEHOLDERS.md +66 -0
  86. package/dist/templates/cc-native/_cc-native/agents/VERIFY-COVERAGE.md +75 -0
  87. package/dist/templates/cc-native/_cc-native/agents/VERIFY-STRENGTH.md +70 -0
  88. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +109 -135
  89. package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.ts +119 -0
  90. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +921 -0
  91. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +61 -0
  92. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +157 -0
  93. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +709 -0
  94. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +199 -0
  95. package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +124 -0
  96. package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +57 -0
  97. package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +83 -0
  98. package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +80 -0
  99. package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +119 -0
  100. package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +162 -0
  101. package/dist/templates/cc-native/_cc-native/lib-ts/nul +3 -0
  102. package/dist/templates/cc-native/_cc-native/lib-ts/orchestrator.ts +249 -0
  103. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/agent.ts +155 -0
  104. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/codex.ts +130 -0
  105. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/gemini.ts +106 -0
  106. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/index.ts +10 -0
  107. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/types.ts +23 -0
  108. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +243 -0
  109. package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +18 -0
  110. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +310 -0
  111. package/dist/templates/cc-native/_cc-native/lib-ts/verdict.ts +72 -0
  112. package/dist/templates/cc-native/_cc-native/plan-review.config.json +12 -16
  113. package/oclif.manifest.json +1 -1
  114. package/package.json +1 -1
  115. package/dist/lib/template-merger.d.ts +0 -47
  116. package/dist/lib/template-merger.js +0 -162
  117. package/dist/templates/_shared/hooks/__init__.py +0 -16
  118. package/dist/templates/_shared/hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  119. package/dist/templates/_shared/hooks/__pycache__/archive_plan.cpython-313.pyc +0 -0
  120. package/dist/templates/_shared/hooks/__pycache__/context_enforcer.cpython-313.pyc +0 -0
  121. package/dist/templates/_shared/hooks/__pycache__/context_monitor.cpython-313.pyc +0 -0
  122. package/dist/templates/_shared/hooks/__pycache__/file-suggestion.cpython-313.pyc +0 -0
  123. package/dist/templates/_shared/hooks/__pycache__/pre_compact.cpython-313.pyc +0 -0
  124. package/dist/templates/_shared/hooks/__pycache__/session_end.cpython-313.pyc +0 -0
  125. package/dist/templates/_shared/hooks/__pycache__/session_start.cpython-313.pyc +0 -0
  126. package/dist/templates/_shared/hooks/__pycache__/task_create_atomicity.cpython-313.pyc +0 -0
  127. package/dist/templates/_shared/hooks/__pycache__/task_create_capture.cpython-313.pyc +0 -0
  128. package/dist/templates/_shared/hooks/__pycache__/task_update_capture.cpython-313.pyc +0 -0
  129. package/dist/templates/_shared/hooks/__pycache__/user_prompt_submit.cpython-313.pyc +0 -0
  130. package/dist/templates/_shared/hooks/archive_plan.py +0 -169
  131. package/dist/templates/_shared/hooks/context_monitor.py +0 -270
  132. package/dist/templates/_shared/hooks/file-suggestion.py +0 -215
  133. package/dist/templates/_shared/hooks/pre_compact.py +0 -104
  134. package/dist/templates/_shared/hooks/session_end.py +0 -173
  135. package/dist/templates/_shared/hooks/session_start.py +0 -206
  136. package/dist/templates/_shared/hooks/task_create_capture.py +0 -108
  137. package/dist/templates/_shared/hooks/task_update_capture.py +0 -145
  138. package/dist/templates/_shared/hooks/user_prompt_submit.py +0 -139
  139. package/dist/templates/_shared/lib/__init__.py +0 -1
  140. package/dist/templates/_shared/lib/__pycache__/__init__.cpython-313.pyc +0 -0
  141. package/dist/templates/_shared/lib/base/__init__.py +0 -65
  142. package/dist/templates/_shared/lib/base/__pycache__/__init__.cpython-313.pyc +0 -0
  143. package/dist/templates/_shared/lib/base/__pycache__/atomic_write.cpython-313.pyc +0 -0
  144. package/dist/templates/_shared/lib/base/__pycache__/constants.cpython-313.pyc +0 -0
  145. package/dist/templates/_shared/lib/base/__pycache__/hook_utils.cpython-313.pyc +0 -0
  146. package/dist/templates/_shared/lib/base/__pycache__/inference.cpython-313.pyc +0 -0
  147. package/dist/templates/_shared/lib/base/__pycache__/logger.cpython-313.pyc +0 -0
  148. package/dist/templates/_shared/lib/base/__pycache__/stop_words.cpython-313.pyc +0 -0
  149. package/dist/templates/_shared/lib/base/__pycache__/subprocess_utils.cpython-313.pyc +0 -0
  150. package/dist/templates/_shared/lib/base/__pycache__/utils.cpython-313.pyc +0 -0
  151. package/dist/templates/_shared/lib/base/atomic_write.py +0 -180
  152. package/dist/templates/_shared/lib/base/constants.py +0 -358
  153. package/dist/templates/_shared/lib/base/hook_utils.py +0 -341
  154. package/dist/templates/_shared/lib/base/inference.py +0 -318
  155. package/dist/templates/_shared/lib/base/logger.py +0 -291
  156. package/dist/templates/_shared/lib/base/stop_words.py +0 -213
  157. package/dist/templates/_shared/lib/base/subprocess_utils.py +0 -46
  158. package/dist/templates/_shared/lib/base/utils.py +0 -242
  159. package/dist/templates/_shared/lib/context/__init__.py +0 -102
  160. package/dist/templates/_shared/lib/context/__pycache__/__init__.cpython-313.pyc +0 -0
  161. package/dist/templates/_shared/lib/context/__pycache__/cache.cpython-313.pyc +0 -0
  162. package/dist/templates/_shared/lib/context/__pycache__/context_extractor.cpython-313.pyc +0 -0
  163. package/dist/templates/_shared/lib/context/__pycache__/context_formatter.cpython-313.pyc +0 -0
  164. package/dist/templates/_shared/lib/context/__pycache__/context_manager.cpython-313.pyc +0 -0
  165. package/dist/templates/_shared/lib/context/__pycache__/context_selector.cpython-313.pyc +0 -0
  166. package/dist/templates/_shared/lib/context/__pycache__/context_store.cpython-313.pyc +0 -0
  167. package/dist/templates/_shared/lib/context/__pycache__/discovery.cpython-313.pyc +0 -0
  168. package/dist/templates/_shared/lib/context/__pycache__/event_log.cpython-313.pyc +0 -0
  169. package/dist/templates/_shared/lib/context/__pycache__/plan_archive.cpython-313.pyc +0 -0
  170. package/dist/templates/_shared/lib/context/__pycache__/plan_manager.cpython-313.pyc +0 -0
  171. package/dist/templates/_shared/lib/context/__pycache__/task_sync.cpython-313.pyc +0 -0
  172. package/dist/templates/_shared/lib/context/__pycache__/task_tracker.cpython-313.pyc +0 -0
  173. package/dist/templates/_shared/lib/context/context_formatter.py +0 -317
  174. package/dist/templates/_shared/lib/context/context_selector.py +0 -508
  175. package/dist/templates/_shared/lib/context/context_store.py +0 -653
  176. package/dist/templates/_shared/lib/context/plan_manager.py +0 -204
  177. package/dist/templates/_shared/lib/context/task_tracker.py +0 -188
  178. package/dist/templates/_shared/lib/handoff/__init__.py +0 -22
  179. package/dist/templates/_shared/lib/handoff/__pycache__/__init__.cpython-313.pyc +0 -0
  180. package/dist/templates/_shared/lib/handoff/__pycache__/document_generator.cpython-313.pyc +0 -0
  181. package/dist/templates/_shared/lib/handoff/document_generator.py +0 -278
  182. package/dist/templates/_shared/lib/templates/README.md +0 -206
  183. package/dist/templates/_shared/lib/templates/__init__.py +0 -36
  184. package/dist/templates/_shared/lib/templates/__pycache__/__init__.cpython-313.pyc +0 -0
  185. package/dist/templates/_shared/lib/templates/__pycache__/formatters.cpython-313.pyc +0 -0
  186. package/dist/templates/_shared/lib/templates/__pycache__/persona_questions.cpython-313.pyc +0 -0
  187. package/dist/templates/_shared/lib/templates/__pycache__/plan_context.cpython-313.pyc +0 -0
  188. package/dist/templates/_shared/lib/templates/formatters.py +0 -146
  189. package/dist/templates/_shared/scripts/__pycache__/save_handoff.cpython-313.pyc +0 -0
  190. package/dist/templates/_shared/scripts/__pycache__/status_line.cpython-313.pyc +0 -0
  191. package/dist/templates/_shared/scripts/save_handoff.py +0 -357
  192. package/dist/templates/_shared/scripts/status_line.py +0 -701
  193. package/dist/templates/cc-native/.claude/commands/cc-native/fresh-perspective.md +0 -8
  194. package/dist/templates/cc-native/.windsurf/workflows/cc-native/fresh-perspective.md +0 -8
  195. package/dist/templates/cc-native/MIGRATION.md +0 -86
  196. package/dist/templates/cc-native/_cc-native/agents/ACCESSIBILITY-TESTER.md +0 -79
  197. package/dist/templates/cc-native/_cc-native/agents/ARCHITECT-REVIEWER.md +0 -48
  198. package/dist/templates/cc-native/_cc-native/agents/CODE-REVIEWER.md +0 -70
  199. package/dist/templates/cc-native/_cc-native/agents/COMPLETENESS-CHECKER.md +0 -59
  200. package/dist/templates/cc-native/_cc-native/agents/CONTEXT-EXTRACTOR.md +0 -92
  201. package/dist/templates/cc-native/_cc-native/agents/DOCUMENTATION-REVIEWER.md +0 -51
  202. package/dist/templates/cc-native/_cc-native/agents/FEASIBILITY-ANALYST.md +0 -57
  203. package/dist/templates/cc-native/_cc-native/agents/FRESH-PERSPECTIVE.md +0 -54
  204. package/dist/templates/cc-native/_cc-native/agents/INCENTIVE-MAPPER.md +0 -61
  205. package/dist/templates/cc-native/_cc-native/agents/PENETRATION-TESTER.md +0 -79
  206. package/dist/templates/cc-native/_cc-native/agents/PERFORMANCE-ENGINEER.md +0 -75
  207. package/dist/templates/cc-native/_cc-native/agents/PRECEDENT-FINDER.md +0 -70
  208. package/dist/templates/cc-native/_cc-native/agents/REVERSIBILITY-ANALYST.md +0 -61
  209. package/dist/templates/cc-native/_cc-native/agents/RISK-ASSESSOR.md +0 -58
  210. package/dist/templates/cc-native/_cc-native/agents/SECOND-ORDER-ANALYST.md +0 -61
  211. package/dist/templates/cc-native/_cc-native/agents/STAKEHOLDER-ADVOCATE.md +0 -55
  212. package/dist/templates/cc-native/_cc-native/agents/TRADE-OFF-ILLUMINATOR.md +0 -204
  213. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/add_plan_context.cpython-313.pyc +0 -0
  214. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/cc-native-plan-review.cpython-313.pyc +0 -0
  215. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/mark_questions_asked.cpython-313.pyc +0 -0
  216. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_accepted.cpython-313.pyc +0 -0
  217. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/plan_questions_early.cpython-313.pyc +0 -0
  218. package/dist/templates/cc-native/_cc-native/hooks/__pycache__/suggest-fresh-perspective.cpython-313.pyc +0 -0
  219. package/dist/templates/cc-native/_cc-native/hooks/add_plan_context.py +0 -130
  220. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.py +0 -869
  221. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.py +0 -81
  222. package/dist/templates/cc-native/_cc-native/hooks/suggest-fresh-perspective.py +0 -340
  223. package/dist/templates/cc-native/_cc-native/lib/CLAUDE.md +0 -265
  224. package/dist/templates/cc-native/_cc-native/lib/__init__.py +0 -53
  225. package/dist/templates/cc-native/_cc-native/lib/__pycache__/__init__.cpython-313.pyc +0 -0
  226. package/dist/templates/cc-native/_cc-native/lib/__pycache__/atomic_write.cpython-313.pyc +0 -0
  227. package/dist/templates/cc-native/_cc-native/lib/__pycache__/constants.cpython-313.pyc +0 -0
  228. package/dist/templates/cc-native/_cc-native/lib/__pycache__/debug.cpython-313.pyc +0 -0
  229. package/dist/templates/cc-native/_cc-native/lib/__pycache__/orchestrator.cpython-313.pyc +0 -0
  230. package/dist/templates/cc-native/_cc-native/lib/__pycache__/state.cpython-313.pyc +0 -0
  231. package/dist/templates/cc-native/_cc-native/lib/__pycache__/utils.cpython-313.pyc +0 -0
  232. package/dist/templates/cc-native/_cc-native/lib/constants.py +0 -45
  233. package/dist/templates/cc-native/_cc-native/lib/debug.py +0 -139
  234. package/dist/templates/cc-native/_cc-native/lib/orchestrator.py +0 -362
  235. package/dist/templates/cc-native/_cc-native/lib/reviewers/__init__.py +0 -28
  236. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/__init__.cpython-313.pyc +0 -0
  237. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/agent.cpython-313.pyc +0 -0
  238. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/base.cpython-313.pyc +0 -0
  239. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/codex.cpython-313.pyc +0 -0
  240. package/dist/templates/cc-native/_cc-native/lib/reviewers/__pycache__/gemini.cpython-313.pyc +0 -0
  241. package/dist/templates/cc-native/_cc-native/lib/reviewers/agent.py +0 -215
  242. package/dist/templates/cc-native/_cc-native/lib/reviewers/base.py +0 -88
  243. package/dist/templates/cc-native/_cc-native/lib/reviewers/codex.py +0 -124
  244. package/dist/templates/cc-native/_cc-native/lib/reviewers/gemini.py +0 -108
  245. package/dist/templates/cc-native/_cc-native/lib/state.py +0 -268
  246. package/dist/templates/cc-native/_cc-native/lib/utils.py +0 -1027
  247. package/dist/templates/cc-native/_cc-native/scripts/__pycache__/aggregate_agents.cpython-313.pyc +0 -0
  248. package/dist/templates/cc-native/_cc-native/scripts/aggregate_agents.py +0 -168
  249. package/dist/templates/cc-native/_cc-native/workflows/fresh-perspective.md +0 -134
@@ -1,104 +0,0 @@
1
- #!/usr/bin/env python3
2
- """PreCompact hook - saves auto-state before context compaction.
3
-
4
- Critical: saves state before context compaction destroys token history.
5
- After compaction, SessionStart fires with source="compact" and the
6
- restored auto-state provides continuity context.
7
-
8
- Hook input (from Claude Code):
9
- {
10
- "hook_event_name": "PreCompact",
11
- "session_id": "abc123",
12
- "transcript_path": "/path/to/transcript.jsonl",
13
- "cwd": "/path/to/project",
14
- ...
15
- }
16
-
17
- Hook output:
18
- - Silent (no stdout output needed)
19
- - Logs to stderr for debugging
20
- """
21
- import sys
22
- from pathlib import Path
23
-
24
- # Add parent directories to path for imports
25
- SCRIPT_DIR = Path(__file__).resolve().parent
26
- SHARED_LIB = SCRIPT_DIR.parent / "lib"
27
- sys.path.insert(0, str(SHARED_LIB.parent))
28
-
29
- from lib.base.hook_utils import load_hook_input, log_debug, log_info, log_error
30
- from lib.base.utils import project_dir
31
- from lib.context.context_store import get_context_by_session_id, save_state
32
-
33
-
34
- def main():
35
- """Save auto-state before compaction."""
36
- try:
37
- hook_input = load_hook_input()
38
- if not hook_input:
39
- return
40
-
41
- session_id = hook_input.get("session_id", "")
42
- transcript_path = hook_input.get("transcript_path")
43
- project_root = project_dir(hook_input)
44
-
45
- if not session_id:
46
- log_debug("pre_compact", "No session_id, skipping")
47
- return
48
-
49
- log_info("pre_compact", f"Saving state before compaction: {session_id[:8]}...")
50
-
51
- # Find context bound to this session
52
- context = get_context_by_session_id(session_id, project_root)
53
- if not context:
54
- log_debug("pre_compact", "No context bound to this session, skipping")
55
- return
56
-
57
- # Save last_session snapshot directly to state.json
58
- import subprocess
59
- git_state = {}
60
- try:
61
- branch = subprocess.run(
62
- ["git", "rev-parse", "--abbrev-ref", "HEAD"],
63
- capture_output=True, text=True, timeout=5
64
- )
65
- git_state["branch"] = branch.stdout.strip() if branch.returncode == 0 else "unknown"
66
-
67
- status = subprocess.run(
68
- ["git", "status", "--short"],
69
- capture_output=True, text=True, timeout=5
70
- )
71
- if status.returncode == 0 and status.stdout.strip():
72
- git_state["uncommitted_files"] = [
73
- line.split(None, 1)[-1] for line in status.stdout.strip().split("\n")[:10]
74
- ]
75
-
76
- log = subprocess.run(
77
- ["git", "log", "-1", "--format=%h %s"],
78
- capture_output=True, text=True, timeout=5
79
- )
80
- if log.returncode == 0:
81
- git_state["last_commit_short"] = log.stdout.strip()
82
- except Exception:
83
- pass
84
-
85
- from lib.base.utils import now_iso
86
- context.last_session = {
87
- "session_id": session_id,
88
- "saved_at": now_iso(),
89
- "save_reason": "pre_compact",
90
- "git_state": git_state,
91
- }
92
- save_state(context, project_root)
93
- log_info("pre_compact", f"State saved for {context.id}")
94
-
95
- except Exception as e:
96
- import traceback
97
- tb = traceback.format_exc()
98
- from lib.base.hook_utils import log_hook_error
99
- log_hook_error("pre_compact", e, "PreCompact", traceback_str=tb)
100
-
101
-
102
- if __name__ == "__main__":
103
- from lib.base.hook_utils import run_hook
104
- run_hook(main, "pre_compact")
@@ -1,173 +0,0 @@
1
- #!/usr/bin/env python3
2
- """SessionEnd hook - saves session state to state.json.
3
-
4
- Fires when session terminates (quit, /clear, logout). Saves last_session
5
- data directly to state.json for restoration on next session.
6
-
7
- Hook input (from Claude Code):
8
- {
9
- "hook_event_name": "SessionEnd",
10
- "session_id": "abc123",
11
- "source": "prompt_input_exit", # or "clear", "logout", "compact"
12
- "transcript_path": "/path/to/transcript.jsonl",
13
- "cwd": "/path/to/project",
14
- ...
15
- }
16
-
17
- Hook output:
18
- - Silent (no stdout output needed for SessionEnd)
19
- - Logs to stderr for debugging
20
- """
21
- import hashlib
22
- import subprocess
23
- import sys
24
- from pathlib import Path
25
-
26
- # Add parent directories to path for imports
27
- SCRIPT_DIR = Path(__file__).resolve().parent
28
- SHARED_LIB = SCRIPT_DIR.parent / "lib"
29
- sys.path.insert(0, str(SHARED_LIB.parent))
30
-
31
- from lib.base.hook_utils import load_hook_input, log_debug, log_info, log_warn, log_error, log_diagnostic
32
- from lib.base.utils import now_iso, project_dir
33
- from lib.context.context_store import get_context_by_session_id, save_state
34
- from lib.context.plan_manager import find_latest_plan, normalize_plan_content, generate_plan_id, extract_plan_anchors
35
-
36
-
37
- def _get_git_state(project_root: Path) -> dict:
38
- """Capture current git state for restoration."""
39
- git_state = {}
40
- try:
41
- result = subprocess.run(
42
- ["git", "rev-parse", "--abbrev-ref", "HEAD"],
43
- capture_output=True, text=True, cwd=str(project_root), timeout=5,
44
- )
45
- if result.returncode == 0:
46
- git_state["branch"] = result.stdout.strip()
47
-
48
- result = subprocess.run(
49
- ["git", "diff", "--name-only"],
50
- capture_output=True, text=True, cwd=str(project_root), timeout=5,
51
- )
52
- if result.returncode == 0:
53
- files = [f for f in result.stdout.strip().split("\n") if f]
54
- git_state["uncommitted_files"] = files
55
-
56
- result = subprocess.run(
57
- ["git", "log", "-1", "--oneline"],
58
- capture_output=True, text=True, cwd=str(project_root), timeout=5,
59
- )
60
- if result.returncode == 0:
61
- git_state["last_commit_short"] = result.stdout.strip()
62
- except Exception as e:
63
- log_warn("session_end", f"Git state capture error (non-fatal): {e}")
64
-
65
- return git_state
66
-
67
-
68
- def main():
69
- """Save session state to state.json."""
70
- try:
71
- hook_input = load_hook_input()
72
- if not hook_input:
73
- return
74
-
75
- session_id = hook_input.get("session_id", "")
76
- source = hook_input.get("source", "other")
77
- transcript_path = hook_input.get("transcript_path")
78
- project_root = project_dir(hook_input)
79
-
80
- if not session_id:
81
- log_debug("session_end", "No session_id, skipping")
82
- return
83
-
84
- log_info("session_end", f"Session ending: {session_id[:8]}... reason={source}")
85
- log_diagnostic("session_end", "receive", f"session={session_id[:8]}, source={source}",
86
- inputs={"session_id": session_id[:12], "source": source})
87
-
88
- # Find context bound to this session
89
- state = get_context_by_session_id(session_id, project_root)
90
- if not state:
91
- log_debug("session_end", "No context bound to this session, skipping")
92
- return
93
-
94
- log_info("session_end", f"Found context: {state.id}")
95
-
96
- # Capture git state
97
- git_state = _get_git_state(project_root)
98
-
99
- # Save last_session directly to state.json
100
- state.last_session = {
101
- "session_id": session_id,
102
- "save_reason": source,
103
- "saved_at": now_iso(),
104
- "transcript_path": transcript_path,
105
- "git_state": git_state,
106
- }
107
- state.last_active = now_iso()
108
-
109
- # Only assign plan fields and stage if NOT in plan mode.
110
- # If permission_mode == "plan", ExitPlanMode was rejected (user pressed Escape),
111
- # so we should not stage the archived plan for the next session.
112
- permission_mode = hook_input.get("permission_mode", "default")
113
-
114
- if permission_mode != "plan":
115
- # Fallback: assign plan fields if PostToolUse:ExitPlanMode didn't fire.
116
- # When ExitPlanMode triggers /clear, the session terminates before PostToolUse
117
- # hooks can run, so plan_accepted.py never fires. Detect this by checking
118
- # for an archived plan that hasn't been assigned yet.
119
- if not state.plan_hash:
120
- latest_plan_path = find_latest_plan(state.id, project_root)
121
- if latest_plan_path:
122
- try:
123
- content = Path(latest_plan_path).read_text(encoding="utf-8")
124
- normalized = normalize_plan_content(content)
125
- state.plan_hash = hashlib.sha256(normalized.encode("utf-8")).hexdigest()[:12]
126
- state.plan_path = latest_plan_path
127
- state.plan_signature = content[:200]
128
- state.plan_id = generate_plan_id()
129
- state.plan_anchors = extract_plan_anchors(content)
130
- state.plan_consumed = False
131
- log_info("session_end", f"Fallback: assigned archived plan for {state.id} (hash: {state.plan_hash})")
132
- except Exception as e:
133
- log_warn("session_end", f"Fallback plan assignment failed: {e}")
134
-
135
- # If a plan is assigned, not yet consumed, and mode is active, stage it for next session
136
- if state.plan_hash and state.mode == "active" and not state.plan_consumed:
137
- state.mode = "has_plan"
138
- log_info("session_end", f"Staged plan for next session: {state.id} -> has_plan")
139
- elif state.plan_hash and state.mode == "active" and state.plan_consumed:
140
- log_debug("session_end", f"Plan already consumed for {state.id}, not re-staging")
141
- log_diagnostic("session_end", "decide", f"Skipping re-stage for {state.id}",
142
- decision="skip_restage", reasoning="plan_hash exists but plan_consumed=True",
143
- inputs={"plan_hash": state.plan_hash, "plan_consumed": True})
144
- else:
145
- log_info("session_end", f"Plan mode active (rejected), skipping plan staging for {state.id}")
146
-
147
- # Handoff staging (mirrors plan staging above)
148
- # Note: if plan already set has_plan, mode != "active" so handoff check skips (plan takes priority)
149
- if state.handoff_path and state.mode == "active" and not state.handoff_consumed:
150
- state.mode = "has_handoff"
151
- log_info("session_end", f"Staged handoff for next session: {state.id} -> has_handoff")
152
- elif state.handoff_path and state.mode == "active" and state.handoff_consumed:
153
- log_debug("session_end", f"Handoff already consumed for {state.id}, not re-staging")
154
-
155
- if save_state(state, project_root):
156
- log_info("session_end", f"Saved last_session for {state.id}")
157
- log_diagnostic("session_end", "result", f"Saved state for {state.id}",
158
- decision="saved", inputs={"context_id": state.id, "mode": state.mode,
159
- "has_plan_hash": bool(state.plan_hash),
160
- "git_files": len(git_state.get("uncommitted_files", []))})
161
- else:
162
- log_error("session_end", f"Failed to save state for {state.id}")
163
-
164
- except Exception as e:
165
- import traceback
166
- tb = traceback.format_exc()
167
- from lib.base.hook_utils import log_hook_error
168
- log_hook_error("session_end", e, "SessionEnd", traceback_str=tb)
169
-
170
-
171
- if __name__ == "__main__":
172
- from lib.base.hook_utils import run_hook
173
- run_hook(main, "session_end")
@@ -1,206 +0,0 @@
1
- #!/usr/bin/env python3
2
- """SessionStart hook for post-compaction and post-clear restore.
3
-
4
- This hook fires when a new session starts. It handles:
5
-
6
- 1. Post-clear restore (source="clear"): After ExitPlanMode "clear context",
7
- Claude Code runs /clear and auto-pastes the plan. The auto-paste bypasses
8
- all hooks (UserPromptSubmit never fires), so this hook bridges the gap:
9
- find the has_plan context (set by session_end moments ago), bind the new
10
- session, transition has_plan → active, and inject restoration context.
11
-
12
- 2. Post-compaction restore (source="compact"): The session is already bound
13
- to a context. Load state and inject rich restoration context so Claude
14
- can continue seamlessly after compaction.
15
-
16
- Hook input:
17
- {
18
- "hook_event_name": "SessionStart",
19
- "session_id": "abc123",
20
- "source": "clear", # or "startup", "resume", "compact"
21
- "permission_mode": "bypassPermissions",
22
- "model": "...",
23
- ...
24
- }
25
- """
26
- import sys
27
- from pathlib import Path
28
-
29
- # Add parent directories to path for imports
30
- SCRIPT_DIR = Path(__file__).resolve().parent
31
- SHARED_LIB = SCRIPT_DIR.parent / "lib"
32
- sys.path.insert(0, str(SHARED_LIB.parent))
33
-
34
- from lib.base.hook_utils import emit_context, load_hook_input, log_debug, log_info, log_error, log_diagnostic
35
- from lib.base.utils import project_dir
36
- from lib.context.context_store import get_context_by_session_id, get_all_contexts, bind_session, update_mode
37
- from lib.context.context_formatter import _build_restore_sections, format_handoff_continuation
38
-
39
-
40
- def _handle_compact_restore(hook_input, session_id, project_root):
41
- """
42
- Handle post-compaction restore.
43
-
44
- After compaction, the session is already bound to a context.
45
- Load state and inject rich restoration context via additionalContext.
46
- """
47
- state = get_context_by_session_id(session_id, project_root)
48
- if not state:
49
- log_debug("session_start", "No context bound to session after compact")
50
- return
51
-
52
- log_info("session_start", f"Post-compaction restore for context: {state.id}")
53
-
54
- # Build restoration context
55
- mode_display = state.mode.replace("_", " ").title() if state.mode != "idle" else "Active"
56
-
57
- lines = [
58
- f"## Resuming Context After Compaction: {state.id}",
59
- "",
60
- f"**Summary:** {state.summary}",
61
- f"**Mode:** {mode_display}",
62
- ]
63
-
64
- # Add restore sections (tasks, git state, plan content)
65
- # inline_plan=True because plan content is NOT auto-pasted after compaction
66
- restore = _build_restore_sections(state, project_root, inline_plan=True)
67
- if restore:
68
- lines.append(restore)
69
-
70
- lines.extend([
71
- "",
72
- "---",
73
- "",
74
- "**Instructions:**",
75
- "Context was compacted to free memory. Your previous conversation has been summarized.",
76
- "1. Review the previous work above",
77
- "2. Continue from where you left off",
78
- ])
79
-
80
- restore_context = "\n".join(lines)
81
- emit_context(restore_context)
82
- log_info("session_start", f"Injected post-compaction restore context for {state.id}")
83
- log_diagnostic("session_start", "result", f"Compact restore complete for {state.id}",
84
- decision="injected", inputs={"context_id": state.id, "mode": state.mode})
85
-
86
-
87
- def _handle_clear_restore(hook_input, session_id, project_root):
88
- """
89
- Handle plan context restoration after /clear.
90
-
91
- After ExitPlanMode "clear context", Claude Code auto-pastes the plan
92
- but the auto-paste bypasses all hooks — UserPromptSubmit never fires.
93
- This means the new session is never bound to a context.
94
-
95
- Fix: find the has_plan context (set by session_end moments ago),
96
- bind the new session to it, and inject restoration context.
97
- """
98
- # Find has_plan contexts (sorted by last_active descending)
99
- has_plan = [
100
- c for c in get_all_contexts(status="active", project_root=project_root)
101
- if c.mode == "has_plan"
102
- ]
103
-
104
- if not has_plan:
105
- # Check for has_handoff contexts (mirrors plan logic)
106
- has_handoff = [
107
- c for c in get_all_contexts(status="active", project_root=project_root)
108
- if c.mode == "has_handoff"
109
- ]
110
- if has_handoff:
111
- target = has_handoff[0]
112
- log_info("session_start", f"Found has_handoff context after /clear: {target.id}")
113
- bind_session(target.id, session_id, project_root)
114
- log_info("session_start", f"Bound session {session_id[:8]}... to {target.id}")
115
- update_mode(target.id, "active", project_root=project_root, handoff_consumed=True)
116
- log_info("session_start", f"Transitioned {target.id}: has_handoff -> active (handoff_consumed=True)")
117
- restore_context = format_handoff_continuation(target, project_root)
118
- emit_context(restore_context)
119
- log_info("session_start", f"Injected handoff-restore context for {target.id}")
120
- return
121
-
122
- log_debug("session_start", "No has_plan or has_handoff contexts found after /clear")
123
- return
124
-
125
- # Pick the most recently active one (first in list, already sorted)
126
- target = has_plan[0]
127
- log_info("session_start", f"Found has_plan context after /clear: {target.id}")
128
-
129
- # Bind new session to this context
130
- bind_session(target.id, session_id, project_root)
131
- log_info("session_start", f"Bound session {session_id[:8]}... to {target.id}")
132
-
133
- # Transition has_plan → active (consume the transient state)
134
- update_mode(target.id, "active", project_root=project_root, plan_consumed=True)
135
- log_info("session_start", f"Transitioned {target.id}: has_plan -> active (plan_consumed=True)")
136
-
137
- # Inject restoration context (tasks, git state, plan path reference)
138
- # Plan CONTENT is not injected — Claude Code auto-pastes it after /clear
139
- mode_display = "Active (Plan Restored)"
140
- lines = [
141
- f"## Resuming Context After Plan Clear: {target.id}",
142
- "",
143
- f"**Summary:** {target.summary}",
144
- f"**Mode:** {mode_display}",
145
- ]
146
-
147
- restore = _build_restore_sections(target, project_root)
148
- if restore:
149
- lines.append(restore)
150
-
151
- lines.extend([
152
- "",
153
- "---",
154
- "",
155
- "**Instructions:**",
156
- "Context was cleared for plan implementation. Your plan content has been pasted above.",
157
- "1. Review the plan content above",
158
- "2. Implement the plan step by step",
159
- ])
160
-
161
- restore_context = "\n".join(lines)
162
- emit_context(restore_context)
163
- log_info("session_start", f"Injected clear-restore context for {target.id}")
164
- log_diagnostic("session_start", "result", f"Clear restore complete for {target.id}",
165
- decision="injected", inputs={"context_id": target.id, "mode_transition": "has_plan->active"})
166
-
167
-
168
- def main():
169
- """Handle post-compaction and post-clear restore on session start."""
170
- try:
171
- hook_input = load_hook_input()
172
- if not hook_input:
173
- return
174
-
175
- source = hook_input.get("source", "unknown")
176
- permission_mode = hook_input.get("permission_mode", "default")
177
- session_id = hook_input.get("session_id", "unknown")
178
- project_root = project_dir(hook_input)
179
-
180
- log_info("session_start", f"source={source}, permission_mode={permission_mode}, session={session_id[:8]}...")
181
- log_diagnostic("session_start", "receive", f"source={source}, session={session_id[:8]}",
182
- inputs={"source": source, "session_id": session_id[:12], "permission_mode": permission_mode})
183
-
184
- if source == "compact":
185
- log_diagnostic("session_start", "decide", "Taking compact restore path",
186
- decision="compact_restore", reasoning="source=compact")
187
- _handle_compact_restore(hook_input, session_id, project_root)
188
- elif source == "clear":
189
- log_diagnostic("session_start", "decide", "Taking clear restore path",
190
- decision="clear_restore", reasoning="source=clear, looking for has_plan context")
191
- _handle_clear_restore(hook_input, session_id, project_root)
192
- else:
193
- log_diagnostic("session_start", "decide", f"No action for source={source}",
194
- decision="skip", reasoning=f"source={source} has no handler")
195
- log_debug("session_start", f"No action for source='{source}'")
196
-
197
- except Exception as e:
198
- import traceback
199
- tb = traceback.format_exc()
200
- from lib.base.hook_utils import log_hook_error
201
- log_hook_error("session_start", e, "SessionStart", traceback_str=tb)
202
-
203
-
204
- if __name__ == "__main__":
205
- from lib.base.hook_utils import run_hook
206
- run_hook(main, "session_start")
@@ -1,108 +0,0 @@
1
- #!/usr/bin/env python3
2
- """PostToolUse hook - captures TaskCreate operations for persistence.
3
-
4
- This hook runs after Claude uses the TaskCreate tool and automatically
5
- records the task in the context's state.json.
6
-
7
- Hook input (from Claude Code):
8
- {
9
- "hook_event_name": "PostToolUse",
10
- "tool_name": "TaskCreate",
11
- "tool_input": {
12
- "subject": "Task subject",
13
- "description": "Task description",
14
- "activeForm": "Present continuous form",
15
- "metadata": {"context": "context-id", ...}
16
- },
17
- "tool_response": {"task": {"id": "1", "subject": "..."}},
18
- "session_id": "abc123",
19
- "cwd": "/path/to/project"
20
- }
21
-
22
- Hook output:
23
- - Silent on success (no stdout output)
24
- - Logs to stderr for debugging
25
- """
26
- import sys
27
- from pathlib import Path
28
-
29
- # Add parent directories to path for imports
30
- SCRIPT_DIR = Path(__file__).resolve().parent
31
- SHARED_LIB = SCRIPT_DIR.parent / "lib"
32
- sys.path.insert(0, str(SHARED_LIB.parent))
33
-
34
- from lib.base.hook_utils import (
35
- load_hook_input,
36
- validate_hook_event,
37
- get_tool_input,
38
- check_skip_persistence,
39
- safe_hook_main,
40
- run_hook,
41
- log_debug,
42
- log_info,
43
- log_warn,
44
- log_error,
45
- )
46
- from lib.base.utils import project_dir
47
- from lib.context.context_store import get_context_by_session_id
48
- from lib.context.task_tracker import add_task, generate_next_task_id
49
-
50
-
51
- @safe_hook_main("task_create_capture")
52
- def main() -> int:
53
- """Main hook entry point."""
54
- payload = load_hook_input()
55
- if not payload:
56
- return 0
57
-
58
- if not validate_hook_event(payload, "PostToolUse", "TaskCreate"):
59
- return 0
60
-
61
- tool_input = get_tool_input(payload)
62
- if not tool_input:
63
- log_warn("task_create_capture", "Invalid tool_input: not a dict")
64
- return 0
65
-
66
- if check_skip_persistence(payload, "task_create_capture"):
67
- return 0
68
-
69
- project_root = project_dir(payload)
70
- session_id = payload.get("session_id", "")
71
-
72
- # Find context by session ID
73
- state = get_context_by_session_id(session_id, project_root)
74
- if not state:
75
- log_debug("task_create_capture", "No context available - skipping persistence")
76
- return 0
77
-
78
- context_id = state.id
79
-
80
- # Extract task data
81
- subject = tool_input.get("subject", "")
82
- if not subject:
83
- log_warn("task_create_capture", "Missing required field: subject")
84
- return 0
85
-
86
- description = tool_input.get("description", "")
87
- active_form = tool_input.get("activeForm", "")
88
-
89
- # Add task to state.json
90
- task = add_task(
91
- context_id=context_id,
92
- subject=subject,
93
- description=description,
94
- active_form=active_form,
95
- session_id=session_id,
96
- project_root=project_root,
97
- )
98
-
99
- if task:
100
- log_info("task_create_capture", f"Recorded task: {task['id']} in {context_id}")
101
- else:
102
- log_error("task_create_capture", f"Failed to add task in {context_id}")
103
-
104
- return 0
105
-
106
-
107
- if __name__ == "__main__":
108
- run_hook(main, "task_create_capture")