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,204 +0,0 @@
1
- """Plan lifecycle management — archival, lookup, and path extraction.
2
-
3
- Provides pure-data operations on plan files:
4
- - archive_plan: copy plan to context plans/ folder, compute hash + signature
5
- - find_latest_plan: locate the most relevant plan for a context
6
- - extract_plan_path_from_result: parse plan path from ExitPlanMode output
7
-
8
- This module does NOT modify mode or state.json. The calling hook
9
- (e.g. archive_plan.py) is responsible for updating mode via
10
- context_store.update_mode() after archival succeeds.
11
- """
12
- import hashlib
13
- import re
14
- import uuid
15
- from datetime import datetime
16
- from pathlib import Path
17
- from typing import List, Optional, Tuple
18
-
19
- from ..base.atomic_write import atomic_write
20
- from ..base.constants import get_context_dir, get_context_plans_dir
21
- from ..base.logger import log_debug, log_info, log_warn, log_error
22
- from ..base.utils import sanitize_title
23
-
24
-
25
- # ---------------------------------------------------------------------------
26
- # Plan archival
27
- # ---------------------------------------------------------------------------
28
-
29
- def archive_plan(
30
- plan_path: str,
31
- context_id: str,
32
- project_root: Path = None,
33
- ) -> Tuple[Optional[str], Optional[str], Optional[str]]:
34
- """Archive a plan file to the context's plans/ folder.
35
-
36
- Copies the plan content to:
37
- _output/contexts/{context_id}/plans/{date}-{slug}.md
38
-
39
- Computes a content hash and signature for change detection and
40
- fallback matching after /clear.
41
-
42
- Does NOT modify state.json or mode — the calling hook handles that
43
- via context_store.update_mode().
44
-
45
- Args:
46
- plan_path: Path to the source plan file.
47
- context_id: Target context identifier.
48
- project_root: Project root directory (default: from env / cwd).
49
-
50
- Returns:
51
- (archived_path, plan_hash, plan_signature) on success.
52
- (None, None, None) on any error.
53
- """
54
- plan_file = Path(plan_path)
55
- if not plan_file.exists():
56
- log_warn("plan_manager", f"Plan file not found: {plan_path}")
57
- return None, None, None
58
-
59
- # Read plan content
60
- try:
61
- content = plan_file.read_text(encoding="utf-8")
62
- except Exception as e:
63
- log_error("plan_manager", f"Failed to read plan: {e}")
64
- return None, None, None
65
-
66
- # Compute hash and signature
67
- plan_hash = hashlib.sha256(content.encode("utf-8")).hexdigest()[:12]
68
- plan_signature = content[:200]
69
-
70
- # Ensure plans directory exists
71
- plans_dir = get_context_plans_dir(context_id, project_root)
72
- plans_dir.mkdir(parents=True, exist_ok=True)
73
-
74
- # Generate archive filename: YYYY-MM-DD-<slug>.md
75
- date_str = datetime.now().strftime("%Y-%m-%d")
76
- slug = sanitize_title(plan_file.stem, max_len=30)
77
- archive_name = f"{date_str}-{slug}.md"
78
- archive_path = plans_dir / archive_name
79
-
80
- # Handle filename collisions with counter suffix
81
- counter = 2
82
- while archive_path.exists():
83
- archive_name = f"{date_str}-{slug}-{counter}.md"
84
- archive_path = plans_dir / archive_name
85
- counter += 1
86
-
87
- # Write archived plan atomically
88
- success, error = atomic_write(archive_path, content)
89
- if not success:
90
- log_error("plan_manager", f"Failed to write archive: {error}")
91
- return None, None, None
92
-
93
- log_info("plan_manager", f"Archived plan to: {archive_path}")
94
- return str(archive_path), plan_hash, plan_signature
95
-
96
-
97
- # ---------------------------------------------------------------------------
98
- # Plan lookup
99
- # ---------------------------------------------------------------------------
100
-
101
- def find_latest_plan(
102
- context_id: str,
103
- project_root: Path = None,
104
- ) -> Optional[str]:
105
- """Find the most relevant plan file for a context.
106
-
107
- Priority:
108
- 1. state.json plan_path — if the file still exists on disk.
109
- 2. Most recent .md in plans/ directory by modification time.
110
- 3. None if no plans found.
111
-
112
- Args:
113
- context_id: Context identifier.
114
- project_root: Project root directory (default: from env / cwd).
115
-
116
- Returns:
117
- Absolute path string to the plan file, or None.
118
- """
119
- # 1. Check state.json plan_path first
120
- try:
121
- from .context_store import load_state
122
- state = load_state(context_id, project_root)
123
- if state and state.plan_path:
124
- plan_path = Path(state.plan_path)
125
- if plan_path.exists():
126
- return str(plan_path)
127
- except Exception as e:
128
- log_warn("plan_manager", f"Failed to check state.json plan_path: {e}")
129
-
130
- # 2. Fall back to most recent .md in plans/ dir by mtime
131
- plans_dir = get_context_plans_dir(context_id, project_root)
132
- if plans_dir.exists():
133
- plans = sorted(
134
- plans_dir.glob("*.md"),
135
- key=lambda p: p.stat().st_mtime,
136
- reverse=True,
137
- )
138
- if plans:
139
- return str(plans[0])
140
-
141
- # 3. No plan found
142
- return None
143
-
144
-
145
- # ---------------------------------------------------------------------------
146
- # Plan identification and normalization
147
- # ---------------------------------------------------------------------------
148
-
149
- def generate_plan_id() -> str:
150
- """Generate a short unique plan identifier (8 hex chars)."""
151
- return uuid.uuid4().hex[:8]
152
-
153
-
154
- def normalize_plan_content(text: str) -> str:
155
- """Aggressively normalize plan content for hashing.
156
-
157
- Strips all XML/HTML tags and collapses whitespace so that
158
- wrapper variations (e.g. <system-reminder>) don't affect the hash.
159
- """
160
- text = re.sub(r'<[^>]+>', '', text)
161
- text = re.sub(r'\s+', ' ', text).strip()
162
- return text
163
-
164
-
165
- def extract_plan_anchors(content: str, max_anchors: int = 5) -> List[str]:
166
- """Extract structural anchors from plan content.
167
-
168
- Returns markdown headings + first substantial paragraph as short strings.
169
- Used for fuzzy matching when hash-based matching fails.
170
- """
171
- anchors = []
172
- for line in content.splitlines():
173
- line = line.strip()
174
- if line.startswith('#') and len(line) > 3:
175
- anchors.append(line[:80])
176
- elif not anchors and len(line) > 20:
177
- anchors.append(line[:80])
178
- if len(anchors) >= max_anchors:
179
- break
180
- return anchors
181
-
182
-
183
- # ---------------------------------------------------------------------------
184
- # Path extraction from tool output
185
- # ---------------------------------------------------------------------------
186
-
187
- def extract_plan_path_from_result(tool_result: str) -> Optional[str]:
188
- """Extract plan file path from ExitPlanMode tool result.
189
-
190
- Parses the pattern: "Your plan has been saved to: <path>"
191
- from the tool_result string returned by ExitPlanMode.
192
-
193
- Args:
194
- tool_result: Raw text output from the ExitPlanMode tool.
195
-
196
- Returns:
197
- Plan file path string (stripped), or None if not found.
198
- """
199
- if not tool_result:
200
- return None
201
- match = re.search(r"Your plan has been saved to:\s*(.+\.md)", tool_result)
202
- if match:
203
- return match.group(1).strip()
204
- return None
@@ -1,188 +0,0 @@
1
- """Task tracker — direct state.json CRUD for tasks.
2
-
3
- Writes tasks directly to the tasks[] array in state.json,
4
- bypassing events.jsonl for faster, simpler task operations.
5
-
6
- All functions do their own I/O to avoid circular imports with
7
- context_store.py.
8
- """
9
- import json
10
- import re
11
- from pathlib import Path
12
- from typing import Dict, List, Optional
13
-
14
- from ..base.atomic_write import atomic_write
15
- from ..base.constants import get_context_dir
16
- from ..base.logger import log_warn
17
- from ..base.utils import now_iso
18
-
19
-
20
- # ---------------------------------------------------------------------------
21
- # Internal I/O (avoids circular import with context_store)
22
- # ---------------------------------------------------------------------------
23
-
24
- def _state_path(context_id: str, project_root: Path = None) -> Path:
25
- return get_context_dir(context_id, project_root) / "state.json"
26
-
27
-
28
- def _load_state(context_id: str, project_root: Path = None) -> Optional[dict]:
29
- sp = _state_path(context_id, project_root)
30
- if not sp.exists():
31
- return None
32
- try:
33
- return json.loads(sp.read_text(encoding="utf-8"))
34
- except Exception as e:
35
- log_warn("task_tracker", f"Failed to read state.json: {e}")
36
- return None
37
-
38
-
39
- def _save_state(context_id: str, state_data: dict, project_root: Path = None) -> bool:
40
- sp = _state_path(context_id, project_root)
41
- content = json.dumps(state_data, indent=2, ensure_ascii=False)
42
- success, error = atomic_write(sp, content)
43
- if not success:
44
- log_warn("task_tracker", f"Failed to write state.json: {error}")
45
- return success
46
-
47
-
48
- # ---------------------------------------------------------------------------
49
- # Public API
50
- # ---------------------------------------------------------------------------
51
-
52
- def generate_next_task_id(context_id: str, project_root: Path = None) -> str:
53
- """Scan tasks[] for highest aiw-N, return aiw-(N+1)."""
54
- state = _load_state(context_id, project_root)
55
- tasks = state.get("tasks", []) if state else []
56
-
57
- max_num = 0
58
- for t in tasks:
59
- tid = t.get("id", "")
60
- m = re.match(r"^aiw-(\d+)$", tid)
61
- if m:
62
- max_num = max(max_num, int(m.group(1)))
63
-
64
- return f"aiw-{max_num + 1}"
65
-
66
-
67
- def add_task(
68
- context_id: str,
69
- subject: str,
70
- description: str = "",
71
- active_form: str = "",
72
- session_id: str = "",
73
- project_root: Path = None,
74
- ) -> Optional[dict]:
75
- """Add a new task to state.json tasks[] and return the task dict."""
76
- state = _load_state(context_id, project_root)
77
- if state is None:
78
- return None
79
-
80
- task_id = generate_next_task_id(context_id, project_root)
81
- task = {
82
- "id": task_id,
83
- "subject": subject,
84
- "description": description,
85
- "active_form": active_form,
86
- "status": "pending",
87
- "created_at": now_iso(),
88
- "completed_at": None,
89
- "evidence": "",
90
- "work_summary": "",
91
- "files_changed": [],
92
- "session_id": session_id,
93
- }
94
-
95
- state.setdefault("tasks", []).append(task)
96
- state["last_active"] = now_iso()
97
-
98
- if _save_state(context_id, state, project_root):
99
- return task
100
- return None
101
-
102
-
103
- def update_task(
104
- context_id: str,
105
- task_id: str,
106
- status: str = None,
107
- evidence: str = "",
108
- work_summary: str = "",
109
- files_changed: List[str] = None,
110
- session_id: str = "",
111
- project_root: Path = None,
112
- ) -> bool:
113
- """Find task by task_id in tasks[], update fields, return True on success."""
114
- state = _load_state(context_id, project_root)
115
- if state is None:
116
- return False
117
-
118
- for task in state.get("tasks", []):
119
- if task.get("id") == task_id:
120
- if status is not None:
121
- task["status"] = status
122
- if status == "completed":
123
- task["completed_at"] = now_iso()
124
- if evidence:
125
- task["evidence"] = evidence
126
- if work_summary:
127
- task["work_summary"] = work_summary
128
- if files_changed is not None:
129
- task["files_changed"] = files_changed
130
- if session_id:
131
- task["session_id"] = session_id
132
- state["last_active"] = now_iso()
133
- return _save_state(context_id, state, project_root)
134
-
135
- log_warn("task_tracker", f"Task '{task_id}' not found in context '{context_id}'")
136
- return False
137
-
138
-
139
- def delete_task(context_id: str, task_id: str, project_root: Path = None) -> bool:
140
- """Remove task from tasks[] and return True on success."""
141
- state = _load_state(context_id, project_root)
142
- if state is None:
143
- return False
144
-
145
- tasks = state.get("tasks", [])
146
- original_len = len(tasks)
147
- state["tasks"] = [t for t in tasks if t.get("id") != task_id]
148
-
149
- if len(state["tasks"]) == original_len:
150
- log_warn("task_tracker", f"Task '{task_id}' not found in context '{context_id}'")
151
- return False
152
-
153
- state["last_active"] = now_iso()
154
- return _save_state(context_id, state, project_root)
155
-
156
-
157
- def get_tasks(context_id: str, project_root: Path = None) -> List[dict]:
158
- """Return tasks[] from state.json."""
159
- state = _load_state(context_id, project_root)
160
- if state is None:
161
- return []
162
- return state.get("tasks", [])
163
-
164
-
165
- def generate_task_summary(context_id: str, project_root: Path = None) -> str:
166
- """Partition tasks and format as markdown checklist."""
167
- tasks = get_tasks(context_id, project_root)
168
- if not tasks:
169
- return "No tasks in this context."
170
-
171
- completed = [t for t in tasks if t.get("status") == "completed"]
172
- in_progress = [t for t in tasks if t.get("status") == "in_progress"]
173
- pending = [t for t in tasks if t.get("status") == "pending"]
174
- blocked = [t for t in tasks if t.get("status") == "blocked"]
175
-
176
- lines = [f"### Tasks ({len(tasks)} total)", ""]
177
-
178
- for t in completed:
179
- ws = f"\n Work: {t['work_summary']}" if t.get("work_summary") else ""
180
- lines.append(f"- [x] {t['id']}: {t['subject']}{ws}")
181
- for t in in_progress:
182
- lines.append(f"- [~] {t['id']}: {t['subject']}")
183
- for t in pending:
184
- lines.append(f"- [ ] {t['id']}: {t['subject']}")
185
- for t in blocked:
186
- lines.append(f"- [!] {t['id']}: {t['subject']}")
187
-
188
- return "\n".join(lines)
@@ -1,22 +0,0 @@
1
- """Handoff utilities for context-aware session management.
2
-
3
- This module provides graceful context degradation when Claude's
4
- context window fills up. Instead of rushing or losing work,
5
- it creates a handoff document and facilitates clean session continuation.
6
-
7
- Components:
8
- - document_generator: Creates handoff documents with work state
9
- - context_monitor hook: Monitors context during tool use and triggers warnings
10
- """
11
-
12
- from .document_generator import (
13
- generate_handoff_document,
14
- get_handoff_continuation_prompt,
15
- HandoffDocument,
16
- )
17
-
18
- __all__ = [
19
- "generate_handoff_document",
20
- "get_handoff_continuation_prompt",
21
- "HandoffDocument",
22
- ]
@@ -1,278 +0,0 @@
1
- """Handoff document generator for context-aware session management.
2
-
3
- Creates structured handoff documents when a session needs to transfer
4
- work to a new session (typically due to context window limits).
5
-
6
- Handoff documents capture:
7
- - Links to active plan and context folder
8
- - Current task state from events.jsonl
9
- - Work in progress summary
10
- - Next steps for continuation
11
- """
12
- import json
13
- import uuid
14
- from dataclasses import dataclass, field
15
- from datetime import datetime
16
- from pathlib import Path
17
- from typing import Any, Dict, List, Optional
18
-
19
- from ..base.atomic_write import atomic_write
20
- from ..base.constants import get_context_handoffs_dir, get_context_dir
21
- from ..base.logger import log_info, log_error
22
- from ..base.utils import now_iso
23
- from ..context.context_store import get_context as _get_context_state, save_state as _save_state
24
- from ..context.task_tracker import get_tasks
25
- from ..templates.formatters import render_task_list, format_continuation_header, format_reason
26
-
27
-
28
- @dataclass
29
- class HandoffDocument:
30
- """Structured handoff document content."""
31
- context_id: str
32
- context_summary: str
33
- session_id: str
34
- reason: str # e.g., "low_context", "user_requested", "error_recovery"
35
- created_at: str
36
-
37
- # Links
38
- plan_path: Optional[str] = None
39
- context_folder: str = ""
40
- events_log_path: str = ""
41
-
42
- # Task state
43
- active_tasks: List[Dict[str, Any]] = field(default_factory=list)
44
- completed_tasks_this_session: List[Dict[str, Any]] = field(default_factory=list)
45
-
46
- # Context summary
47
- work_summary: str = ""
48
- next_steps: List[str] = field(default_factory=list)
49
- important_notes: List[str] = field(default_factory=list)
50
-
51
- # File path (set after saving)
52
- file_path: Optional[str] = None
53
-
54
-
55
- def generate_handoff_document(
56
- context_id: str,
57
- reason: str = "low_context",
58
- work_summary: str = "",
59
- next_steps: Optional[List[str]] = None,
60
- important_notes: Optional[List[str]] = None,
61
- completed_this_session: Optional[List[str]] = None,
62
- project_root: Path = None
63
- ) -> Optional[HandoffDocument]:
64
- """
65
- Generate and save a handoff document for a context.
66
-
67
- This creates a markdown document capturing current work state,
68
- saves it to the context's handoffs folder, and records the event.
69
-
70
- Args:
71
- context_id: Context identifier
72
- reason: Why handoff is happening (low_context, user_requested, etc.)
73
- work_summary: Summary of current work in progress
74
- next_steps: List of next steps for continuation
75
- important_notes: Important decisions or context to preserve
76
- completed_this_session: List of task subjects completed this session
77
- project_root: Project root directory
78
-
79
- Returns:
80
- HandoffDocument with file_path set, or None on failure
81
- """
82
- context = _get_context_state(context_id, project_root)
83
- if not context:
84
- log_error("handoff", f"Context '{context_id}' not found")
85
- return None
86
-
87
- # Generate session ID
88
- session_id = str(uuid.uuid4())[:8]
89
-
90
- # Get pending tasks from state.json
91
- all_tasks = get_tasks(context_id, project_root)
92
- pending_tasks = [t for t in all_tasks if t.get("status") in ("pending", "in_progress", "blocked")]
93
-
94
- # Build document
95
- now = now_iso()
96
- context_dir = get_context_dir(context_id, project_root)
97
-
98
- doc = HandoffDocument(
99
- context_id=context_id,
100
- context_summary=context.summary,
101
- session_id=session_id,
102
- reason=reason,
103
- created_at=now,
104
- plan_path=context.plan_path,
105
- context_folder=str(context_dir),
106
- events_log_path=str(context_dir / "state.json"),
107
- active_tasks=pending_tasks,
108
- completed_tasks_this_session=[
109
- {"subject": s} for s in (completed_this_session or [])
110
- ],
111
- work_summary=work_summary,
112
- next_steps=next_steps or [],
113
- important_notes=important_notes or [],
114
- )
115
-
116
- # Compute file path BEFORE rendering markdown
117
- handoffs_dir = get_context_handoffs_dir(context_id, project_root)
118
- handoffs_dir.mkdir(parents=True, exist_ok=True)
119
-
120
- # Filename: YYYY-MM-DD-session-{session_id}.md
121
- date_str = datetime.now().strftime("%Y-%m-%d")
122
- filename = f"{date_str}-session-{session_id}.md"
123
- file_path = handoffs_dir / filename
124
-
125
- # Set file_path on doc BEFORE rendering markdown
126
- doc.file_path = str(file_path)
127
-
128
- # Generate markdown content
129
- markdown = _render_handoff_markdown(doc)
130
-
131
- # Save to handoffs folder
132
-
133
- success, error = atomic_write(file_path, markdown)
134
- if not success:
135
- log_error("handoff", f"Failed to write handoff document: {error}")
136
- return None
137
-
138
- log_info("handoff", f"Created handoff document: {file_path}")
139
- return doc
140
-
141
-
142
- def _render_handoff_markdown(doc: HandoffDocument) -> str:
143
- """Render handoff document as markdown."""
144
- lines = [
145
- format_continuation_header("handoff", doc.context_id),
146
- "",
147
- f"**Created**: {doc.created_at}",
148
- f"**Context ID**: {doc.context_id}",
149
- f"**Session ID**: {doc.session_id}",
150
- f"**Reason**: {format_reason(doc.reason)}",
151
- "",
152
- "## Links",
153
- "",
154
- ]
155
-
156
- # Plan link
157
- if doc.plan_path:
158
- lines.append(f"- **Plan**: [{Path(doc.plan_path).name}]({doc.plan_path})")
159
-
160
- lines.extend([
161
- f"- **Context Folder**: `{doc.context_folder}`",
162
- f"- **Events Log**: `{doc.events_log_path}`",
163
- "",
164
- "## Current State",
165
- "",
166
- ])
167
-
168
- # Active tasks
169
- lines.append(render_task_list(doc.active_tasks, header="Active Tasks", show_description=True).rstrip())
170
- lines.append("")
171
-
172
- # Completed this session
173
- if doc.completed_tasks_this_session:
174
- lines.append(render_task_list(
175
- doc.completed_tasks_this_session,
176
- header="Completed This Session",
177
- show_description=False
178
- ).rstrip())
179
- lines.append("")
180
-
181
- # Work summary
182
- if doc.work_summary:
183
- lines.extend([
184
- "## Context Summary",
185
- "",
186
- doc.work_summary,
187
- "",
188
- ])
189
-
190
- # Next steps
191
- if doc.next_steps:
192
- lines.extend([
193
- "## Next Steps",
194
- "",
195
- ])
196
- for i, step in enumerate(doc.next_steps, 1):
197
- lines.append(f"{i}. {step}")
198
- lines.append("")
199
-
200
- # Important notes
201
- if doc.important_notes:
202
- lines.extend([
203
- "## Important Notes",
204
- "",
205
- ])
206
- for note in doc.important_notes:
207
- lines.append(f"- {note}")
208
- lines.append("")
209
-
210
- # Continuation prompt
211
- lines.extend([
212
- "---",
213
- "",
214
- "**Continuation Prompt**:",
215
- "```",
216
- f'Continue working on context "{doc.context_id}".',
217
- "",
218
- f"Handoff document: {doc.file_path or 'See above'}",
219
- "",
220
- "Read the handoff document, restore tasks with TaskCreate, and continue implementation.",
221
- "```",
222
- ])
223
-
224
- return "\n".join(lines)
225
-
226
-
227
- def get_handoff_continuation_prompt(doc: HandoffDocument) -> str:
228
- """
229
- Generate the prompt to paste into new session for continuation.
230
-
231
- Args:
232
- doc: HandoffDocument with file_path set
233
-
234
- Returns:
235
- Prompt string for continuing work
236
- """
237
- return f"""Continue working on context "{doc.context_id}".
238
-
239
- Handoff document: {doc.file_path}
240
-
241
- Read the handoff document, restore tasks with TaskCreate, and continue implementation."""
242
-
243
-
244
- def get_low_context_warning(context_remaining_percent: int, context_id: str) -> str:
245
- """
246
- Generate system reminder for low context warning.
247
-
248
- This is injected by the UserPromptSubmit hook when context is low.
249
-
250
- Args:
251
- context_remaining_percent: Percentage of context remaining
252
- context_id: Current context identifier
253
-
254
- Returns:
255
- System reminder markdown
256
- """
257
- return f"""<system-reminder>
258
- ## LOW CONTEXT WARNING ({context_remaining_percent}% remaining)
259
-
260
- Your context window is running low. Please:
261
-
262
- 1. **Finish current task** if 1-2 steps away, OR save current progress
263
- 2. **Create handoff document** by calling:
264
- ```python
265
- from _shared.lib.handoff import generate_handoff_document
266
- doc = generate_handoff_document(
267
- context_id="{context_id}",
268
- reason="low_context",
269
- work_summary="<describe current work>",
270
- next_steps=["<step 1>", "<step 2>"],
271
- important_notes=["<key decision 1>"]
272
- )
273
- ```
274
- 3. **Ask permission** to clear and paste continuation prompt
275
-
276
- After creating handoff, ask the user:
277
- "Context is low. I've created a handoff document. May I clear and continue in a new session?"
278
- </system-reminder>"""