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,169 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Plan archival hook for ExitPlanMode PermissionRequest event.
3
-
4
- This hook runs when ExitPlanMode is requested (BEFORE user accepts/rejects),
5
- extracting the plan path from the tool input and archiving it to the
6
- context's plans/ folder. It does NOT modify state.json plan fields or mode.
7
-
8
- Separation of concerns:
9
- - archive_plan.py (PermissionRequest) -> archives file only, no state.json changes
10
- - plan_accepted.py (PostToolUse) -> assigns plan fields (hash/signature/path) to state.json
11
- - session_end.py (SessionEnd) -> transitions active -> has_plan when plan is assigned
12
- - context_selector.py -> matches plan content, transitions has_plan -> active
13
-
14
- Usage in .claude/settings.json:
15
- {
16
- "hooks": {
17
- "PermissionRequest": [{
18
- "matcher": "ExitPlanMode",
19
- "hooks": [{
20
- "type": "command",
21
- "command": "python .aiwcli/_shared/hooks/archive_plan.py",
22
- "timeout": 5000
23
- }]
24
- }]
25
- }
26
- }
27
- """
28
- import re
29
- import sys
30
- from pathlib import Path
31
- from typing import Optional
32
-
33
- # Add parent directories to path for imports
34
- SCRIPT_DIR = Path(__file__).resolve().parent
35
- SHARED_LIB = SCRIPT_DIR.parent / "lib"
36
- sys.path.insert(0, str(SHARED_LIB.parent))
37
-
38
- from lib.base.hook_utils import load_hook_input, log_debug, log_info, log_warn, log_error
39
- from lib.base.utils import project_dir
40
- from lib.base.constants import get_context_dir
41
- from lib.context.context_store import get_context_by_session_id
42
- from lib.context.plan_manager import archive_plan, extract_plan_path_from_result
43
-
44
- # Import debug cleanup function from cc-native lib
45
- _cc_native_lib = SCRIPT_DIR.parent / "_cc-native" / "lib"
46
- sys.path.insert(0, str(_cc_native_lib))
47
- try:
48
- from debug import cleanup_debug_folder
49
- except ImportError:
50
- def cleanup_debug_folder(context_path):
51
- pass
52
-
53
-
54
- def _find_plan_path(hook_input: dict, project_root: Path) -> Optional[str]:
55
- """Find the plan file path from hook input or standard locations."""
56
- tool_input = hook_input.get("tool_input", {})
57
- tool_result = hook_input.get("tool_result", "")
58
- hook_event = hook_input.get("hook_event_name", "")
59
- tool_name = hook_input.get("tool_name", "")
60
-
61
- plan_path = None
62
-
63
- # For ExitPlanMode, extract from tool result
64
- if tool_name == "ExitPlanMode" and tool_result:
65
- plan_path = extract_plan_path_from_result(tool_result)
66
- if plan_path:
67
- log_info("archive_plan", f"Extracted plan path from result: {plan_path}")
68
-
69
- # Check tool_input for plan path
70
- if not plan_path:
71
- plan_path = tool_input.get("plan_path") or tool_input.get("planPath")
72
-
73
- # Search standard locations
74
- if not plan_path:
75
- log_debug("archive_plan", "No plan_path found, searching standard locations...")
76
- claude_plans_dir = Path.home() / ".claude" / "plans"
77
- if claude_plans_dir.exists():
78
- claude_plans = sorted(
79
- claude_plans_dir.glob("*.md"),
80
- key=lambda p: p.stat().st_mtime,
81
- reverse=True,
82
- )
83
- if claude_plans:
84
- plan_path = str(claude_plans[0])
85
-
86
- if not plan_path:
87
- for fallback in [
88
- project_root / "_output" / "cc-native" / "plans" / "current-plan.md",
89
- project_root / "_output" / "plans" / "current-plan.md",
90
- project_root / "plan.md",
91
- ]:
92
- if fallback.exists():
93
- plan_path = str(fallback)
94
- break
95
-
96
- return plan_path
97
-
98
-
99
- def on_plan_archive():
100
- """Archive plan on PermissionRequest:ExitPlanMode — file archival only, no state.json changes."""
101
- hook_input = load_hook_input()
102
- if not hook_input:
103
- log_warn("archive_plan", "No valid JSON input")
104
- return
105
-
106
- hook_event = hook_input.get("hook_event_name", "unknown")
107
- tool_name = hook_input.get("tool_name", "")
108
-
109
- log_info("archive_plan", f"Hook triggered: {hook_event}, tool: {tool_name}")
110
-
111
- # Only handle PermissionRequest for ExitPlanMode
112
- if not (hook_event == "PermissionRequest" and tool_name == "ExitPlanMode"):
113
- log_debug("archive_plan", "Skipping: not PermissionRequest:ExitPlanMode")
114
- return
115
-
116
- if hook_input.get("stop_hook_active", False):
117
- log_debug("archive_plan", "Stop hook active, skipping")
118
- return
119
-
120
- project_root = project_dir(hook_input)
121
- plan_path = _find_plan_path(hook_input, project_root)
122
-
123
- if not plan_path:
124
- log_warn("archive_plan", "Could not find plan file, skipping archival")
125
- return
126
-
127
- # Resolve plan path
128
- plan_file = Path(plan_path)
129
- if not plan_file.is_absolute():
130
- plan_file = project_root / plan_path
131
-
132
- log_debug("archive_plan", f"Resolved plan file: {plan_file}")
133
-
134
- if not plan_file.exists():
135
- log_error("archive_plan", f"Plan file not found: {plan_file}")
136
- return
137
-
138
- # Find context by session ID
139
- session_id = hook_input.get("session_id", "unknown")
140
- state = get_context_by_session_id(session_id, project_root)
141
-
142
- if not state:
143
- log_warn("archive_plan", "Could not determine context for session")
144
- return
145
-
146
- context_id = state.id
147
-
148
- # Archive the plan file (returns path, hash, signature)
149
- archived_path, plan_hash, plan_signature = archive_plan(
150
- str(plan_file), context_id, project_root
151
- )
152
-
153
- if archived_path:
154
- # Clean up debug logs
155
- try:
156
- context_path = get_context_dir(context_id, project_root)
157
- cleanup_debug_folder(context_path)
158
- except Exception as e:
159
- log_warn("archive_plan", f"could not clean debug folder: {e}")
160
-
161
- log_info("archive_plan", f"SUCCESS: archived plan for {context_id}")
162
- log_debug("archive_plan", f"Path: {archived_path}, hash: {plan_hash}")
163
- else:
164
- log_error("archive_plan", f"Could not archive plan for '{context_id}'")
165
-
166
-
167
- if __name__ == "__main__":
168
- from lib.base.hook_utils import run_hook
169
- run_hook(on_plan_archive, "archive_plan")
@@ -1,270 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Context monitor hook for proactive handoff warnings.
3
-
4
- This hook runs on PostToolUse for context-heavy tools and monitors
5
- context window usage. When context drops below a threshold, it injects
6
- a system reminder instructing Claude to wrap up and create a handoff document.
7
-
8
- Unlike UserPromptSubmit hooks, this fires DURING Claude's work,
9
- allowing proactive intervention without waiting for user input.
10
-
11
- Monitored tools (configured via settings.json matcher):
12
- - Task: Subagent responses can be huge
13
- - Read: File content loads into context
14
- - Bash: Command output can be large
15
- - WebFetch: Web content loads into context
16
-
17
- Hook input (from Claude Code):
18
- {
19
- "hook_event_name": "PostToolUse",
20
- "tool_name": "Task",
21
- "tool_input": {...},
22
- "tool_result": {...},
23
- "transcript_path": "/path/to/transcript.jsonl",
24
- "session_id": "abc123",
25
- "context_window": {
26
- "current_usage": {
27
- "cache_read_input_tokens": 0,
28
- "input_tokens": 12345,
29
- "cache_creation_input_tokens": 0,
30
- "output_tokens": 6789
31
- },
32
- "context_window_size": 200000
33
- },
34
- ...
35
- }
36
-
37
- Hook output:
38
- - Outputs JSON with additionalContext if context is low
39
- - This injects a system reminder into Claude's context
40
- - Plain stdout from PostToolUse only goes to verbose mode, not Claude
41
- - Using additionalContext ensures Claude sees and responds to the warning
42
-
43
- KNOWN LIMITATION: Context percentage won't match /context exactly.
44
- Hook JSON excludes system prompt, tools, MCP tokens. We add a baseline
45
- to compensate (~22.6k tokens typical). See:
46
- https://github.com/anthropics/claude-code/issues/13783
47
- """
48
- import sys
49
- from pathlib import Path
50
- from typing import Optional
51
-
52
- # Add parent directories to path for imports
53
- SCRIPT_DIR = Path(__file__).resolve().parent
54
- SHARED_LIB = SCRIPT_DIR.parent / "lib"
55
- sys.path.insert(0, str(SHARED_LIB.parent))
56
-
57
- from lib.base.hook_utils import emit_context, load_hook_input, get_context_percent_remaining, log_debug, log_info, log_warn, log_error, log_diagnostic
58
- from lib.base.utils import now_iso, project_dir
59
- from lib.context.context_store import (
60
- get_all_contexts,
61
- get_context_by_session_id,
62
- maybe_activate,
63
- save_state,
64
- )
65
-
66
- # Module-level flag: only save auto-state once per process lifetime
67
- _PROGRESSIVE_SAVE_MARKER = ".progressive-save-done"
68
-
69
- # Configuration
70
- SAVE_STATE_THRESHOLD = 60 # Silently save auto-state at 60% remaining
71
- HANDOFF_SUGGEST_THRESHOLD = 30 # Gentle nudge at 30% remaining (70% used)
72
- HANDOFF_PREPARE_THRESHOLD = 20 # Stronger warning at 20% remaining (80% used)
73
- CRITICAL_CONTEXT_THRESHOLD = 10 # Urgent warning at 10% remaining (90% used)
74
-
75
-
76
- def get_current_context_id(project_root: Path = None) -> Optional[str]:
77
- """Determine the current active context (most recently active)."""
78
- contexts = get_all_contexts(status="active", project_root=project_root)
79
- if contexts:
80
- return contexts[0].id
81
- return None
82
-
83
-
84
- def get_context_warning(
85
- percent_remaining: int,
86
- tokens_used: Optional[int],
87
- max_tokens: Optional[int],
88
- context_id: Optional[str],
89
- tool_name: str
90
- ) -> str:
91
- """Generate appropriate warning based on context level."""
92
- if tokens_used is not None and max_tokens is not None:
93
- tokens_used_k = tokens_used // 1000
94
- max_tokens_k = max_tokens // 1000
95
- usage_line = f"**Estimated usage**: ~{tokens_used_k}k / {max_tokens_k}k tokens"
96
- else:
97
- usage_line = f"**Estimated usage**: ~{percent_remaining}% remaining"
98
-
99
- context_line = f"\nContext ID: `{context_id}`" if context_id else ""
100
-
101
- if percent_remaining <= CRITICAL_CONTEXT_THRESHOLD:
102
- return f"""<system-reminder>
103
- ## CRITICAL CONTEXT WARNING ({percent_remaining}% remaining)
104
-
105
- {usage_line}
106
- **Triggered by**: {tool_name} tool completion
107
-
108
- **CRITICAL: Run `/handoff` now before context is compacted.**
109
- {context_line}
110
-
111
- You are about to lose context. Stop all other work and run `/handoff` immediately.
112
- </system-reminder>"""
113
-
114
- elif percent_remaining <= HANDOFF_PREPARE_THRESHOLD:
115
- return f"""<system-reminder>
116
- ## LOW CONTEXT WARNING ({percent_remaining}% remaining)
117
-
118
- {usage_line}
119
- **Triggered by**: {tool_name} tool completion
120
-
121
- **Context is getting low. Please finish your current task and run `/handoff`.**
122
- {context_line}
123
-
124
- **Actions:**
125
- 1. Complete your current atomic task (if 1-2 steps away)
126
- 2. Do NOT start new multi-step work
127
- 3. Run `/handoff` to generate a handoff document
128
- </system-reminder>"""
129
-
130
- else:
131
- return f"""<system-reminder>
132
- ## CONTEXT NOTICE ({percent_remaining}% remaining)
133
-
134
- {usage_line}
135
- **Triggered by**: {tool_name} tool completion
136
-
137
- **Consider preparing a handoff soon. When ready, run `/handoff` to generate a handoff document.**
138
- {context_line}
139
-
140
- Continue your current work, but avoid starting large new tasks.
141
- </system-reminder>"""
142
-
143
-
144
- def check_and_transition_mode(hook_input: dict) -> None:
145
- """
146
- Check if context mode needs to transition based on tool usage.
147
-
148
- Handles:
149
- - has_plan + implementation tool -> active (started implementing)
150
- - idle + implementation tool -> active
151
- """
152
- project_root = project_dir(hook_input)
153
- session_id = hook_input.get("session_id")
154
-
155
- if not session_id:
156
- return
157
-
158
- state = get_context_by_session_id(session_id, project_root)
159
- if not state:
160
- return
161
-
162
- # Implementation transitions only trigger on implementation tools
163
- implementation_tools = {"Edit", "Write", "Bash", "NotebookEdit"}
164
- tool_name = hook_input.get("tool_name", "")
165
-
166
- if tool_name not in implementation_tools:
167
- return
168
-
169
- permission_mode = hook_input.get("permission_mode", "default")
170
- maybe_activate(state.id, permission_mode, project_root=project_root, caller="context_monitor")
171
-
172
-
173
- def _try_progressive_save(hook_input: dict, percent_remaining: int) -> None:
174
- """Silently save state at SAVE_STATE_THRESHOLD (60%)."""
175
- try:
176
- session_id = hook_input.get("session_id", "")
177
- if not session_id:
178
- return
179
-
180
- project_root = project_dir(hook_input)
181
- state = get_context_by_session_id(session_id, project_root)
182
- if not state:
183
- return
184
-
185
- from lib.base.constants import get_context_dir
186
- marker_path = get_context_dir(state.id, project_root) / _PROGRESSIVE_SAVE_MARKER
187
- if marker_path.exists():
188
- try:
189
- saved_session = marker_path.read_text(encoding="utf-8").strip()
190
- if saved_session == session_id:
191
- return
192
- except OSError:
193
- pass
194
-
195
- log_info("context_monitor", f"Progressive save at {percent_remaining}% remaining")
196
-
197
- # Just update last_active and save state
198
- state.last_active = now_iso()
199
- save_state(state, project_root)
200
-
201
- try:
202
- marker_path.write_text(session_id, encoding="utf-8")
203
- except OSError:
204
- pass
205
-
206
- except Exception as e:
207
- log_warn("context_monitor", f"Progressive save error (non-fatal): {e}")
208
-
209
-
210
- def check_context_level(hook_input: dict) -> Optional[str]:
211
- """Check context level and return warning if low."""
212
- tool_name = hook_input.get("tool_name", "Unknown")
213
- percent_remaining, tokens_used, max_tokens = get_context_percent_remaining(hook_input)
214
-
215
- log_diagnostic("context_monitor", "receive", f"tool={tool_name}, pct_remaining={percent_remaining}",
216
- inputs={"tool_name": tool_name, "percent_remaining": percent_remaining,
217
- "tokens_used": tokens_used, "max_tokens": max_tokens})
218
-
219
- if percent_remaining is None:
220
- return None
221
-
222
- if percent_remaining > SAVE_STATE_THRESHOLD:
223
- return None
224
-
225
- if percent_remaining > HANDOFF_SUGGEST_THRESHOLD:
226
- _try_progressive_save(hook_input, percent_remaining)
227
- return None
228
-
229
- if tokens_used is not None and max_tokens is not None:
230
- log_info("context_monitor", f"Context: {percent_remaining}% remaining "
231
- f"(~{tokens_used//1000}k/{max_tokens//1000}k tokens)")
232
- else:
233
- log_info("context_monitor", f"Context: ~{percent_remaining}% remaining (from context.json)")
234
-
235
- project_root = project_dir(hook_input)
236
- context_id = get_current_context_id(project_root)
237
-
238
- threshold = ("critical" if percent_remaining <= CRITICAL_CONTEXT_THRESHOLD
239
- else "prepare" if percent_remaining <= HANDOFF_PREPARE_THRESHOLD
240
- else "suggest")
241
- log_diagnostic("context_monitor", "decide", f"Threshold={threshold} at {percent_remaining}%",
242
- decision=threshold, reasoning=f"{percent_remaining}% remaining",
243
- inputs={"context_id": context_id, "percent_remaining": percent_remaining})
244
-
245
- return get_context_warning(percent_remaining, tokens_used, max_tokens, context_id, tool_name)
246
-
247
-
248
- def main():
249
- """Main entry point for PostToolUse hook."""
250
- try:
251
- hook_input = load_hook_input()
252
- if not hook_input:
253
- return
254
-
255
- check_and_transition_mode(hook_input)
256
-
257
- warning = check_context_level(hook_input)
258
- if warning:
259
- emit_context(warning)
260
-
261
- except Exception as e:
262
- import traceback
263
- tb = traceback.format_exc()
264
- from lib.base.hook_utils import log_hook_error
265
- log_hook_error("context_monitor", e, "PostToolUse", traceback_str=tb)
266
-
267
-
268
- if __name__ == "__main__":
269
- from lib.base.hook_utils import run_hook
270
- run_hook(main, "context_monitor")
@@ -1,215 +0,0 @@
1
- #!/usr/bin/env python3
2
- """File suggestion hook for Claude Code.
3
-
4
- Suggests relevant files to include in context based on the current session:
5
- - Context file (context.json) for the active context
6
- - Plans from the active context's plans/ directory
7
- - Handoffs from the active context's handoffs/ directory
8
- - Reviews from the active context's reviews/ directory (including cc-native subdirectory)
9
-
10
- Hook input (from Claude Code):
11
- {
12
- "session_id": "abc123",
13
- "cwd": "/path/to/project",
14
- ...
15
- }
16
-
17
- Hook output:
18
- JSON array of file paths to suggest, or empty array if no suggestions.
19
- ["/path/to/file1.md", "/path/to/file2.md"]
20
- """
21
- import json
22
- import sys
23
- from pathlib import Path
24
- from typing import List, Optional
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_error
32
- from lib.base.utils import project_dir
33
- from lib.base.constants import (
34
- get_context_plans_dir,
35
- get_context_handoffs_dir,
36
- get_context_reviews_dir,
37
- get_context_file_path,
38
- )
39
- from lib.context.context_store import (
40
- get_context_by_session_id,
41
- get_all_contexts,
42
- get_context,
43
- )
44
-
45
-
46
- def get_context_files(context_id: str, project_root: Path) -> List[str]:
47
- """
48
- Get all relevant files for a context.
49
-
50
- Collects:
51
- - Context file (context.json)
52
- - Plans (most recent first)
53
- - Handoffs: index.md from subdirectories (folder-based) OR flat .md files (legacy)
54
- - Reviews: index.md from subdirectories (folder-based) OR flat review.md (legacy)
55
-
56
- Args:
57
- context_id: Context identifier
58
- project_root: Project root path
59
-
60
- Returns:
61
- List of absolute file paths, sorted by modification time (most recent first)
62
- """
63
- files = []
64
-
65
- # Get context.json file first
66
- context_file = get_context_file_path(context_id, project_root)
67
- if context_file.exists():
68
- files.append(str(context_file))
69
- log_debug("file-suggestion", f"Found context file for {context_id}")
70
-
71
- # Get plans directory
72
- plans_dir = get_context_plans_dir(context_id, project_root)
73
- if plans_dir.exists():
74
- plan_files = list(plans_dir.glob("*.md"))
75
- # Sort by modification time, most recent first
76
- plan_files.sort(key=lambda p: p.stat().st_mtime, reverse=True)
77
- files.extend([str(p) for p in plan_files])
78
- log_debug("file-suggestion", f"Found {len(plan_files)} plans in {context_id}")
79
-
80
- # Get handoffs - prefer folder-based (index.md in subdirectories), fall back to legacy
81
- handoffs_dir = get_context_handoffs_dir(context_id, project_root)
82
- if handoffs_dir.exists():
83
- # Find handoff folders (named like YYYY-MM-DD-HHMM or YYYY-MM-DD-HHMM-N)
84
- handoff_folders = sorted(
85
- [d for d in handoffs_dir.iterdir() if d.is_dir()],
86
- key=lambda d: d.name,
87
- reverse=True # Most recent first (alphabetically sorts by date)
88
- )
89
-
90
- if handoff_folders:
91
- # Use folder-based: get index.md from most recent folder only
92
- index_file = handoff_folders[0] / "index.md"
93
- if index_file.exists():
94
- files.append(str(index_file))
95
- log_debug("file-suggestion", f"Found handoff folder: {handoff_folders[0].name}")
96
- else:
97
- # Legacy support: flat .md files directly in handoffs/
98
- legacy_handoffs = [f for f in handoffs_dir.glob("*.md") if f.is_file()]
99
- legacy_handoffs.sort(key=lambda p: p.stat().st_mtime, reverse=True)
100
- if legacy_handoffs:
101
- files.append(str(legacy_handoffs[0])) # Only most recent legacy
102
- log_debug("file-suggestion", f"Found {len(legacy_handoffs)} legacy handoffs in {context_id}")
103
-
104
- # Get reviews - prefer folder-based (index.md in subdirectories), fall back to legacy
105
- reviews_dir = get_context_reviews_dir(context_id, project_root) / "cc-native"
106
- if reviews_dir.exists():
107
- # Find review folders (named like YYYY-MM-DD-HHMM-iteration-N)
108
- review_folders = sorted(
109
- [d for d in reviews_dir.iterdir() if d.is_dir()],
110
- key=lambda d: d.name,
111
- reverse=True # Most recent first
112
- )
113
-
114
- if review_folders:
115
- # Use folder-based: get index.md from most recent folder only
116
- index_file = review_folders[0] / "index.md"
117
- if index_file.exists():
118
- files.append(str(index_file))
119
- log_debug("file-suggestion", f"Found review folder: {review_folders[0].name}")
120
- else:
121
- # Legacy support: flat review.md directly in cc-native/
122
- legacy_review = reviews_dir / "review.md"
123
- if legacy_review.exists():
124
- files.append(str(legacy_review))
125
- log_debug("file-suggestion", f"Found legacy review.md in {context_id}")
126
-
127
- return files
128
-
129
-
130
- def get_active_context_id(session_id: str, project_root: Path) -> Optional[str]:
131
- """
132
- Determine the active context for suggestions.
133
-
134
- Priority:
135
- 1. Context bound to current session_id
136
- 2. Single in-flight context (if only one exists)
137
- 3. None (no suggestions if ambiguous)
138
-
139
- Args:
140
- session_id: Current session identifier
141
- project_root: Project root path
142
-
143
- Returns:
144
- Context ID or None
145
- """
146
- # Try session_id lookup first
147
- if session_id and session_id != "unknown":
148
- context = get_context_by_session_id(session_id, project_root)
149
- if context:
150
- log_debug("file-suggestion", f"Found context by session: {context.id}")
151
- return context.id
152
-
153
- # Fall back to single active (non-idle) context
154
- active = [c for c in get_all_contexts(status="active", project_root=project_root)
155
- if c.mode != "idle"]
156
- if len(active) == 1:
157
- log_debug("file-suggestion", f"Using single active context: {active[0].id}")
158
- return active[0].id
159
-
160
- log_debug("file-suggestion", f"No unique context found (active: {len(active)})")
161
- return None
162
-
163
-
164
- def main():
165
- """
166
- Main entry point for file suggestion hook.
167
-
168
- Reads hook input from stdin, determines active context,
169
- and outputs file suggestions as JSON array.
170
- """
171
- try:
172
- # Read hook input using shared utility
173
- hook_input = load_hook_input()
174
-
175
- if not hook_input:
176
- print("[]")
177
- return
178
-
179
- # Get project root and session ID
180
- project_root = project_dir(hook_input)
181
- session_id = hook_input.get("session_id", "unknown")
182
-
183
- log_debug("file-suggestion", f"Session: {session_id[:8]}..., Project: {project_root}")
184
-
185
- # Determine active context
186
- context_id = get_active_context_id(session_id, project_root)
187
-
188
- if not context_id:
189
- print("[]")
190
- return
191
-
192
- # Collect file suggestions
193
- suggestions = get_context_files(context_id, project_root)
194
-
195
- # Limit suggestions to prevent overwhelming the context
196
- MAX_SUGGESTIONS = 10
197
- if len(suggestions) > MAX_SUGGESTIONS:
198
- log_debug("file-suggestion", f"Limiting suggestions to {MAX_SUGGESTIONS} (was {len(suggestions)})")
199
- suggestions = suggestions[:MAX_SUGGESTIONS]
200
-
201
- # Output suggestions as JSON array
202
- log_info("file-suggestion", f"Suggesting {len(suggestions)} files")
203
- print(json.dumps(suggestions))
204
-
205
- except Exception as e:
206
- import traceback
207
- tb = traceback.format_exc()
208
- from lib.base.hook_utils import log_hook_error
209
- log_hook_error("file-suggestion", e, "SessionStart", traceback_str=tb)
210
- print("[]")
211
-
212
-
213
- if __name__ == "__main__":
214
- from lib.base.hook_utils import run_hook
215
- run_hook(main, "file_suggestion")