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
@@ -29,28 +29,12 @@ export default class Init extends BaseCommand {
29
29
  * @returns Template description
30
30
  */
31
31
  private getTemplateDescription;
32
- /**
33
- * Merge settings from multiple method templates into project settings.
34
- * Processes methods in order, allowing later methods to override earlier ones.
35
- *
36
- * @param targetDir - Project directory
37
- * @param methods - Array of method names to merge (e.g., ['_shared', 'cc-native'])
38
- * @param ides - IDEs being configured (for IDE-specific merging)
39
- */
40
- private mergeMethodsSettings;
41
- /**
42
- * Merge Windsurf template hooks into project hooks
43
- *
44
- * @param targetDir - Project directory
45
- * @param templatePath - Template source path
46
- */
47
- private mergeWindsurfTemplateHooks;
48
32
  /**
49
33
  * Perform post-installation actions.
50
34
  *
51
35
  * Handles:
52
36
  * - Method tracking in settings.json
53
- * - Settings/hooks merging for all methods
37
+ * - Settings reconstruction from all active templates
54
38
  * - .gitignore updates
55
39
  *
56
40
  * @param config - Post-install configuration
@@ -4,16 +4,14 @@ import { fileURLToPath } from 'node:url';
4
4
  import { checkbox, confirm, input, select } from '@inquirer/prompts';
5
5
  import { Flags } from '@oclif/core';
6
6
  import BaseCommand from '../../lib/base-command.js';
7
- import { detectUsername } from '../../lib/user-utils.js';
8
- import { updateGitignore } from '../../lib/gitignore-manager.js';
9
- import { mergeClaudeSettings } from '../../lib/hooks-merger.js';
7
+ import { AIW_GITIGNORE_ENTRIES, updateGitignore } from '../../lib/gitignore-manager.js';
10
8
  import { IdePathResolver } from '../../lib/ide-path-resolver.js';
11
9
  import { pathExists } from '../../lib/paths.js';
12
10
  import { getTargetSettingsFile, readClaudeSettings, writeClaudeSettings } from '../../lib/settings-hierarchy.js';
13
11
  import { checkTemplateStatus, installTemplate, shouldExclude } from '../../lib/template-installer.js';
14
12
  import { getAvailableTemplates, getTemplatePath } from '../../lib/template-resolver.js';
15
- import { getTargetHooksFile, readWindsurfHooks, writeWindsurfHooks } from '../../lib/windsurf-hooks-hierarchy.js';
16
- import { mergeWindsurfHooks } from '../../lib/windsurf-hooks-merger.js';
13
+ import { reconstructIdeSettings } from '../../lib/template-settings-reconstructor.js';
14
+ import { detectUsername } from '../../lib/user-utils.js';
17
15
  import { EXIT_CODES } from '../../types/exit-codes.js';
18
16
  /**
19
17
  * Available IDEs for configuration
@@ -93,7 +91,10 @@ export default class Init extends BaseCommand {
93
91
  await fs.mkdir(containerDir, { recursive: true });
94
92
  const sharedDestPath = resolver.getSharedFolder();
95
93
  const sharedExists = await pathExists(sharedDestPath);
96
- if (!sharedExists) {
94
+ if (sharedExists) {
95
+ this.logInfo('✓ _shared folder already exists - skipping');
96
+ }
97
+ else {
97
98
  const currentFilePath = fileURLToPath(import.meta.url);
98
99
  const currentDir = dirname(currentFilePath);
99
100
  const templatesRoot = join(dirname(dirname(currentDir)), 'templates');
@@ -106,14 +107,11 @@ export default class Init extends BaseCommand {
106
107
  await this.copyDirectory(sharedSrcPath, sharedDestPath, true);
107
108
  this.logSuccess('✓ Installed _shared folder');
108
109
  }
109
- else {
110
- this.logInfo('✓ _shared folder already exists - skipping');
111
- }
112
- // Merge settings from _shared template
113
- await this.mergeMethodsSettings(targetDir, ['_shared'], ['claude']);
110
+ // Reconstruct settings from _shared template
111
+ await reconstructIdeSettings(targetDir, [], ['claude']);
114
112
  // Update .gitignore if git repository exists
115
113
  if (hasGit) {
116
- await updateGitignore(targetDir, ['.aiwcli']);
114
+ await updateGitignore(targetDir, [...AIW_GITIGNORE_ENTRIES]);
117
115
  this.logSuccess('✓ .gitignore updated');
118
116
  }
119
117
  this.log('');
@@ -169,7 +167,7 @@ export default class Init extends BaseCommand {
169
167
  // Still update gitignore and merge hooks if needed
170
168
  }
171
169
  this.log('');
172
- // Install template with selective installation (skip existing items)
170
+ // Install template (always overwrites method-owned content)
173
171
  const result = await installTemplate({
174
172
  templateName: method,
175
173
  targetDir,
@@ -177,20 +175,14 @@ export default class Init extends BaseCommand {
177
175
  username,
178
176
  projectName,
179
177
  templatePath,
180
- }, true);
178
+ });
181
179
  // Collect all folders that need gitignore entries
182
180
  // The .aiwcli/ container holds all template infrastructure and runtime data
183
- const foldersForGitignore = ['.aiwcli'];
181
+ const foldersForGitignore = [...AIW_GITIGNORE_ENTRIES];
184
182
  // Report installation results
185
183
  if (result.installedFolders.length > 0) {
186
184
  this.logSuccess(`✓ Installed: ${result.installedFolders.join(', ')}`);
187
185
  }
188
- if (result.mergedFolders.length > 0) {
189
- this.logSuccess(`✓ Merged content into: ${result.mergedFolders.join(', ')} (${result.mergedFileCount} files)`);
190
- }
191
- if (result.skippedFolders.length > 0) {
192
- this.logInfo(`✓ Skipped (already exist): ${result.skippedFolders.join(', ')}`);
193
- }
194
186
  // Perform post-installation actions (settings tracking, hook merging, gitignore updates)
195
187
  await this.performPostInstallActions({
196
188
  targetDir,
@@ -271,94 +263,12 @@ export default class Init extends BaseCommand {
271
263
  };
272
264
  return descriptions[template] || 'Custom template';
273
265
  }
274
- /**
275
- * Merge settings from multiple method templates into project settings.
276
- * Processes methods in order, allowing later methods to override earlier ones.
277
- *
278
- * @param targetDir - Project directory
279
- * @param methods - Array of method names to merge (e.g., ['_shared', 'cc-native'])
280
- * @param ides - IDEs being configured (for IDE-specific merging)
281
- */
282
- async mergeMethodsSettings(targetDir, methods, ides) {
283
- const targetSettingsPath = getTargetSettingsFile(targetDir);
284
- let projectSettings = (await readClaudeSettings(targetSettingsPath)) || {};
285
- for (const method of methods) {
286
- try {
287
- // Get template path for this method
288
- let templatePath;
289
- if (method === '_shared') {
290
- // Special case: _shared is at templates/_shared
291
- const currentFilePath = fileURLToPath(import.meta.url);
292
- const currentDir = dirname(currentFilePath);
293
- const templatesRoot = join(dirname(dirname(currentDir)), 'templates');
294
- templatePath = join(templatesRoot, '_shared');
295
- }
296
- else {
297
- // Named method templates
298
- templatePath = await getTemplatePath(method);
299
- }
300
- // Merge Claude settings if claude IDE is selected
301
- if (ides.includes('claude')) {
302
- const templateSettingsPath = join(templatePath, '.claude', 'settings.json');
303
- const templateSettings = await readClaudeSettings(templateSettingsPath);
304
- if (templateSettings) {
305
- projectSettings = mergeClaudeSettings(projectSettings, templateSettings);
306
- this.logSuccess(`✓ Merged ${method} settings into .claude/settings.json`);
307
- }
308
- }
309
- // Merge Windsurf hooks if windsurf IDE is selected
310
- if (ides.includes('windsurf')) {
311
- await this.mergeWindsurfTemplateHooks(targetDir, templatePath);
312
- }
313
- }
314
- catch (error) {
315
- const err = error;
316
- this.warn(`Failed to merge ${method} settings: ${err.message}`);
317
- }
318
- }
319
- // Write merged Claude settings
320
- if (ides.includes('claude')) {
321
- await writeClaudeSettings(targetSettingsPath, projectSettings);
322
- }
323
- }
324
- /**
325
- * Merge Windsurf template hooks into project hooks
326
- *
327
- * @param targetDir - Project directory
328
- * @param templatePath - Template source path
329
- */
330
- async mergeWindsurfTemplateHooks(targetDir, templatePath) {
331
- try {
332
- // Read template hooks
333
- const templateHooksPath = join(templatePath, '.windsurf', 'hooks.json');
334
- const templateHooks = await readWindsurfHooks(templateHooksPath);
335
- // If template has no hooks, nothing to merge
336
- if (!templateHooks || !templateHooks.hooks || Object.keys(templateHooks.hooks).length === 0) {
337
- this.logInfo('No Windsurf hooks in template to merge');
338
- return;
339
- }
340
- // Get target hooks file path
341
- const targetHooksPath = getTargetHooksFile(targetDir);
342
- // Read existing project hooks
343
- const existingHooks = await readWindsurfHooks(targetHooksPath);
344
- // Merge hooks
345
- const mergedHooks = mergeWindsurfHooks(existingHooks, templateHooks);
346
- // Write merged hooks
347
- await writeWindsurfHooks(targetHooksPath, mergedHooks);
348
- this.logSuccess('✓ Windsurf template hooks merged into project hooks');
349
- }
350
- catch (error) {
351
- const err = error;
352
- this.warn(`Failed to merge Windsurf template hooks: ${err.message}`);
353
- // Don't fail the entire installation if hook merging fails
354
- }
355
- }
356
266
  /**
357
267
  * Perform post-installation actions.
358
268
  *
359
269
  * Handles:
360
270
  * - Method tracking in settings.json
361
- * - Settings/hooks merging for all methods
271
+ * - Settings reconstruction from all active templates
362
272
  * - .gitignore updates
363
273
  *
364
274
  * @param config - Post-install configuration
@@ -370,10 +280,15 @@ export default class Init extends BaseCommand {
370
280
  */
371
281
  async performPostInstallActions(config) {
372
282
  const { targetDir, method, ides, hasGit, foldersForGitignore } = config;
373
- // Track method installation in settings.json
283
+ // Track method installation in settings.json first (so reconstructor can read methods list)
374
284
  await this.trackMethodInstallation(targetDir, method, ides);
375
- // Merge settings from _shared and method templates
376
- await this.mergeMethodsSettings(targetDir, ['_shared', method], ides);
285
+ // Read installed methods to build active templates list
286
+ const settingsPath = getTargetSettingsFile(targetDir);
287
+ const settings = await readClaudeSettings(settingsPath);
288
+ const activeTemplates = settings?.methods ? Object.keys(settings.methods) : [method];
289
+ // Reconstruct IDE settings from all active templates
290
+ await reconstructIdeSettings(targetDir, activeTemplates, ides);
291
+ this.logSuccess('✓ Reconstructed IDE settings from active templates');
377
292
  // Update .gitignore if git repository exists
378
293
  if (hasGit) {
379
294
  await updateGitignore(targetDir, foldersForGitignore);
@@ -1,3 +1,7 @@
1
+ /** Standard gitignore entries managed by AIW */
2
+ export declare const AIW_GITIGNORE_ENTRIES: string[];
3
+ /** Entries that should NEVER be removed from gitignore, even on clear */
4
+ export declare const AIW_PERMANENT_ENTRIES: string[];
1
5
  /**
2
6
  * Prune stale entries from the AIW Installation section in .gitignore.
3
7
  * Checks each entry against disk existence and removes entries whose paths don't exist.
@@ -17,3 +21,31 @@ export declare function pruneGitignoreStaleEntries(targetDir: string): Promise<b
17
21
  * @param folders - List of folder names to add as gitignore patterns (e.g., ['_bmad', '.claude'])
18
22
  */
19
23
  export declare function updateGitignore(targetDir: string, folders: string[]): Promise<void>;
24
+ /**
25
+ * Compute which AIW gitignore entries should be removed during clear.
26
+ * Returns a simulation result — the caller decides whether to apply.
27
+ *
28
+ * Logic per entry:
29
+ * - If in permanentEntries → keep (reason: "permanent")
30
+ * - If directory exists and is non-empty → keep (reason: "directory has content")
31
+ * - Otherwise → mark for removal
32
+ *
33
+ * @param targetDir - Directory containing .gitignore
34
+ * @param permanentEntries - Entries that should never be removed (defaults to AIW_PERMANENT_ENTRIES)
35
+ * @returns Lists of entries to remove and entries to keep with reasons
36
+ */
37
+ export declare function computeGitignoreRemovals(targetDir: string, permanentEntries?: string[]): Promise<{
38
+ toKeep: Array<{
39
+ entry: string;
40
+ reason: string;
41
+ }>;
42
+ toRemove: string[];
43
+ }>;
44
+ /**
45
+ * Remove specific entries from the AIW section in .gitignore.
46
+ * Cleans up the section header if no entries remain.
47
+ *
48
+ * @param targetDir - Directory containing .gitignore
49
+ * @param entriesToRemove - Entry names to remove (without trailing slash)
50
+ */
51
+ export declare function removeGitignoreEntries(targetDir: string, entriesToRemove: string[]): Promise<void>;
@@ -5,6 +5,10 @@ import { pathExists } from './paths.js';
5
5
  * AIW gitignore section header marker
6
6
  */
7
7
  const AIW_GITIGNORE_HEADER = '# AIW Installation';
8
+ /** Standard gitignore entries managed by AIW */
9
+ export const AIW_GITIGNORE_ENTRIES = ['.aiwcli', '_output', '.claude', '.windsurf'];
10
+ /** Entries that should NEVER be removed from gitignore, even on clear */
11
+ export const AIW_PERMANENT_ENTRIES = ['_output'];
8
12
  /**
9
13
  * Prune stale entries from the AIW Installation section in .gitignore.
10
14
  * Checks each entry against disk existence and removes entries whose paths don't exist.
@@ -35,7 +39,7 @@ export async function pruneGitignoreStaleEntries(targetDir) {
35
39
  // AIW section ends at empty line or another comment header
36
40
  if (line === '' || (line.startsWith('#') && line !== AIW_GITIGNORE_HEADER)) {
37
41
  inAiwSection = false;
38
- const { lines: filtered, pruned: sectionPruned } = await pruneSection(aiwSectionLines, targetDir);
42
+ const { lines: filtered, pruned: sectionPruned } = await pruneSection(aiwSectionLines, targetDir); // eslint-disable-line no-await-in-loop
39
43
  if (sectionPruned)
40
44
  pruned = true;
41
45
  newLines.push(...filtered, line);
@@ -88,7 +92,7 @@ async function pruneSection(sectionLines, targetDir) {
88
92
  // Check if the path exists on disk
89
93
  const cleanPath = line.replace(/^\//, '').replace(/\/$/, '');
90
94
  const absPath = join(targetDir, cleanPath);
91
- if (await pathExists(absPath)) {
95
+ if (await pathExists(absPath)) { // eslint-disable-line no-await-in-loop
92
96
  filtered.push(line);
93
97
  }
94
98
  else {
@@ -179,3 +183,138 @@ export async function updateGitignore(targetDir, folders) {
179
183
  await fs.writeFile(gitignorePath, patternsBlock + '\n', 'utf8');
180
184
  }
181
185
  }
186
+ /**
187
+ * Compute which AIW gitignore entries should be removed during clear.
188
+ * Returns a simulation result — the caller decides whether to apply.
189
+ *
190
+ * Logic per entry:
191
+ * - If in permanentEntries → keep (reason: "permanent")
192
+ * - If directory exists and is non-empty → keep (reason: "directory has content")
193
+ * - Otherwise → mark for removal
194
+ *
195
+ * @param targetDir - Directory containing .gitignore
196
+ * @param permanentEntries - Entries that should never be removed (defaults to AIW_PERMANENT_ENTRIES)
197
+ * @returns Lists of entries to remove and entries to keep with reasons
198
+ */
199
+ export async function computeGitignoreRemovals(targetDir, permanentEntries = AIW_PERMANENT_ENTRIES) {
200
+ const gitignorePath = join(targetDir, '.gitignore');
201
+ const toRemove = [];
202
+ const toKeep = [];
203
+ // Read AIW section entries from .gitignore
204
+ let content;
205
+ try {
206
+ content = await fs.readFile(gitignorePath, 'utf8');
207
+ }
208
+ catch {
209
+ return { toRemove, toKeep };
210
+ }
211
+ if (!content.includes(AIW_GITIGNORE_HEADER)) {
212
+ return { toRemove, toKeep };
213
+ }
214
+ // Parse entries from the AIW section
215
+ const lines = content.split('\n');
216
+ let inAiwSection = false;
217
+ const aiwEntries = [];
218
+ for (const line of lines) {
219
+ if (line === AIW_GITIGNORE_HEADER) {
220
+ inAiwSection = true;
221
+ continue;
222
+ }
223
+ if (inAiwSection) {
224
+ if (line === '' || (line.startsWith('#') && line !== AIW_GITIGNORE_HEADER)) {
225
+ inAiwSection = false;
226
+ }
227
+ else {
228
+ // Strip trailing slash to get the directory name
229
+ const entry = line.replace(/\/$/, '');
230
+ if (entry) {
231
+ aiwEntries.push(entry);
232
+ }
233
+ }
234
+ }
235
+ }
236
+ const permanentSet = new Set(permanentEntries);
237
+ // Evaluate each entry
238
+ await Promise.all(aiwEntries.map(async (entry) => {
239
+ if (permanentSet.has(entry)) {
240
+ toKeep.push({ entry, reason: 'permanent' });
241
+ return;
242
+ }
243
+ const dirPath = join(targetDir, entry);
244
+ const exists = await pathExists(dirPath);
245
+ if (exists) {
246
+ // Check if non-empty
247
+ try {
248
+ const entries = await fs.readdir(dirPath);
249
+ if (entries.length > 0) {
250
+ toKeep.push({ entry, reason: 'directory has content' });
251
+ return;
252
+ }
253
+ }
254
+ catch {
255
+ // Can't read — be safe, keep it
256
+ toKeep.push({ entry, reason: 'directory has content' });
257
+ return;
258
+ }
259
+ }
260
+ toRemove.push(entry);
261
+ }));
262
+ return { toRemove, toKeep };
263
+ }
264
+ /**
265
+ * Remove specific entries from the AIW section in .gitignore.
266
+ * Cleans up the section header if no entries remain.
267
+ *
268
+ * @param targetDir - Directory containing .gitignore
269
+ * @param entriesToRemove - Entry names to remove (without trailing slash)
270
+ */
271
+ export async function removeGitignoreEntries(targetDir, entriesToRemove) {
272
+ const gitignorePath = join(targetDir, '.gitignore');
273
+ try {
274
+ const content = await fs.readFile(gitignorePath, 'utf8');
275
+ if (!content.includes(AIW_GITIGNORE_HEADER)) {
276
+ return;
277
+ }
278
+ const patternsToRemove = new Set(entriesToRemove.map((e) => `${e}/`));
279
+ const lines = content.split('\n');
280
+ const newLines = [];
281
+ let inAiwSection = false;
282
+ const aiwSectionLines = [];
283
+ for (const line of lines) {
284
+ if (line === AIW_GITIGNORE_HEADER) {
285
+ inAiwSection = true;
286
+ aiwSectionLines.push(line);
287
+ continue;
288
+ }
289
+ if (inAiwSection) {
290
+ if (line === '' || (line.startsWith('#') && line !== AIW_GITIGNORE_HEADER)) {
291
+ inAiwSection = false;
292
+ // Filter the AIW section
293
+ const filtered = aiwSectionLines.filter((l) => l === AIW_GITIGNORE_HEADER || !patternsToRemove.has(l));
294
+ newLines.push(...filtered, line);
295
+ }
296
+ else {
297
+ aiwSectionLines.push(line);
298
+ }
299
+ }
300
+ else {
301
+ newLines.push(line);
302
+ }
303
+ }
304
+ // Handle AIW section at end of file
305
+ if (inAiwSection) {
306
+ const filtered = aiwSectionLines.filter((l) => l === AIW_GITIGNORE_HEADER || !patternsToRemove.has(l));
307
+ newLines.push(...filtered);
308
+ }
309
+ // Clean up empty AIW section
310
+ let result = cleanupEmptySections(newLines.join('\n'));
311
+ result = result.replace(/\n+$/, '\n');
312
+ if (result.trim() === '') {
313
+ result = '';
314
+ }
315
+ await fs.writeFile(gitignorePath, result, 'utf8');
316
+ }
317
+ catch {
318
+ // .gitignore doesn't exist or can't be read
319
+ }
320
+ }
@@ -45,14 +45,8 @@ export interface TemplateInstallationStatus {
45
45
  export interface InstallationResult {
46
46
  /** List of folder names that were installed (for gitignore) */
47
47
  installedFolders: string[];
48
- /** Number of files that were merged into existing folders */
49
- mergedFileCount: number;
50
- /** List of folder names that had content merged */
51
- mergedFolders: string[];
52
48
  /** Whether shared settings were merged into IDE settings */
53
49
  sharedSettingsMerged: boolean;
54
- /** List of folder names that were skipped (already exist) */
55
- skippedFolders: string[];
56
50
  /** Absolute path to the template that was installed */
57
51
  templatePath: string;
58
52
  }
@@ -87,15 +81,16 @@ export declare function shouldExclude(name: string): boolean;
87
81
  export declare function copyDir(src: string, dest: string, excludeIdeFolders?: boolean): Promise<void>;
88
82
  /**
89
83
  * Install template with IDE-specific folder selection.
90
- * Supports selective installation - only installs items that don't already exist.
91
84
  *
92
85
  * Template structure:
93
- * - Non-dot folders (e.g., _bmad/, GSR/) are installed if not already present
94
- * - Dot folders (e.g., .claude/, .windsurf/) are installed only if matching IDE flag and not already present
86
+ * - Non-dot folders (e.g., _bmad/, GSR/) .aiwcli/ (always overwritten)
87
+ * - _shared/ .aiwcli/_shared/ (always overwritten)
88
+ * - IDE dot folders (e.g., .claude/) → decomposed into method-owned subdirs
89
+ *
90
+ * Settings reconstruction is handled separately by the caller via reconstructIdeSettings().
95
91
  *
96
92
  * @param config - Installation configuration
97
- * @param skipExisting - If true, skip items that already exist (default: true for regeneration support)
98
- * @returns Installation result with list of installed and skipped folders
93
+ * @returns Installation result with list of installed folders
99
94
  * @throws Error if template doesn't exist or requested IDE folder not found
100
95
  */
101
- export declare function installTemplate(config: TemplateInstallConfig, skipExisting?: boolean): Promise<InstallationResult>;
96
+ export declare function installTemplate(config: TemplateInstallConfig): Promise<InstallationResult>;