@ncoderz/awa 0.2.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 (329) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +234 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +1353 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +75 -0
  7. package/templates/awa/.agent/skills/awa-architecture/SKILL.md +3 -0
  8. package/templates/awa/.agent/skills/awa-brainstorm/SKILL.md +3 -0
  9. package/templates/awa/.agent/skills/awa-code/SKILL.md +3 -0
  10. package/templates/awa/.agent/skills/awa-design/SKILL.md +3 -0
  11. package/templates/awa/.agent/skills/awa-documentation/SKILL.md +3 -0
  12. package/templates/awa/.agent/skills/awa-examples/SKILL.md +3 -0
  13. package/templates/awa/.agent/skills/awa-feature/SKILL.md +3 -0
  14. package/templates/awa/.agent/skills/awa-plan/SKILL.md +3 -0
  15. package/templates/awa/.agent/skills/awa-refactor/SKILL.md +3 -0
  16. package/templates/awa/.agent/skills/awa-requirements/SKILL.md +3 -0
  17. package/templates/awa/.agent/skills/awa-tasks/SKILL.md +3 -0
  18. package/templates/awa/.agent/skills/awa-upgrade/SKILL.md +3 -0
  19. package/templates/awa/.agent/skills/awa-validate-alignment/SKILL.md +3 -0
  20. package/templates/awa/.agent/skills/awa-vibe/SKILL.md +3 -0
  21. package/templates/awa/.agent/workflows/awa-architecture.md +3 -0
  22. package/templates/awa/.agent/workflows/awa-brainstorm.md +3 -0
  23. package/templates/awa/.agent/workflows/awa-code.md +3 -0
  24. package/templates/awa/.agent/workflows/awa-design.md +3 -0
  25. package/templates/awa/.agent/workflows/awa-documentation.md +3 -0
  26. package/templates/awa/.agent/workflows/awa-examples.md +3 -0
  27. package/templates/awa/.agent/workflows/awa-feature.md +3 -0
  28. package/templates/awa/.agent/workflows/awa-plan.md +3 -0
  29. package/templates/awa/.agent/workflows/awa-refactor.md +3 -0
  30. package/templates/awa/.agent/workflows/awa-requirements.md +3 -0
  31. package/templates/awa/.agent/workflows/awa-tasks.md +3 -0
  32. package/templates/awa/.agent/workflows/awa-upgrade.md +3 -0
  33. package/templates/awa/.agent/workflows/awa-validate-alignment.md +3 -0
  34. package/templates/awa/.agent/workflows/awa-vibe.md +3 -0
  35. package/templates/awa/.agents/skills/awa-architecture/SKILL.md +3 -0
  36. package/templates/awa/.agents/skills/awa-brainstorm/SKILL.md +3 -0
  37. package/templates/awa/.agents/skills/awa-code/SKILL.md +3 -0
  38. package/templates/awa/.agents/skills/awa-design/SKILL.md +3 -0
  39. package/templates/awa/.agents/skills/awa-documentation/SKILL.md +3 -0
  40. package/templates/awa/.agents/skills/awa-examples/SKILL.md +3 -0
  41. package/templates/awa/.agents/skills/awa-feature/SKILL.md +3 -0
  42. package/templates/awa/.agents/skills/awa-plan/SKILL.md +3 -0
  43. package/templates/awa/.agents/skills/awa-refactor/SKILL.md +3 -0
  44. package/templates/awa/.agents/skills/awa-requirements/SKILL.md +3 -0
  45. package/templates/awa/.agents/skills/awa-tasks/SKILL.md +3 -0
  46. package/templates/awa/.agents/skills/awa-upgrade/SKILL.md +3 -0
  47. package/templates/awa/.agents/skills/awa-validate-alignment/SKILL.md +3 -0
  48. package/templates/awa/.agents/skills/awa-vibe/SKILL.md +3 -0
  49. package/templates/awa/.awa/.agent/awa.core.md +1 -0
  50. package/templates/awa/.awa/.agent/schemas/ALIGN_REPORT.schema.md +156 -0
  51. package/templates/awa/.awa/.agent/schemas/API.schema.md +4 -0
  52. package/templates/awa/.awa/.agent/schemas/ARCHITECTURE.schema.md +176 -0
  53. package/templates/awa/.awa/.agent/schemas/DESIGN.schema.md +253 -0
  54. package/templates/awa/.awa/.agent/schemas/EXAMPLES.schema.md +51 -0
  55. package/templates/awa/.awa/.agent/schemas/FEAT.schema.md +61 -0
  56. package/templates/awa/.awa/.agent/schemas/PLAN.schema.md +8 -0
  57. package/templates/awa/.awa/.agent/schemas/README.schema.md +133 -0
  58. package/templates/awa/.awa/.agent/schemas/REQ.schema.md +125 -0
  59. package/templates/awa/.awa/.agent/schemas/TASK.schema.md +137 -0
  60. package/templates/awa/.claude/agents/awa.md +14 -0
  61. package/templates/awa/.claude/skills/awa-architecture/SKILL.md +3 -0
  62. package/templates/awa/.claude/skills/awa-brainstorm/SKILL.md +3 -0
  63. package/templates/awa/.claude/skills/awa-code/SKILL.md +3 -0
  64. package/templates/awa/.claude/skills/awa-design/SKILL.md +3 -0
  65. package/templates/awa/.claude/skills/awa-documentation/SKILL.md +3 -0
  66. package/templates/awa/.claude/skills/awa-examples/SKILL.md +3 -0
  67. package/templates/awa/.claude/skills/awa-feature/SKILL.md +3 -0
  68. package/templates/awa/.claude/skills/awa-plan/SKILL.md +3 -0
  69. package/templates/awa/.claude/skills/awa-refactor/SKILL.md +3 -0
  70. package/templates/awa/.claude/skills/awa-requirements/SKILL.md +3 -0
  71. package/templates/awa/.claude/skills/awa-tasks/SKILL.md +3 -0
  72. package/templates/awa/.claude/skills/awa-upgrade/SKILL.md +3 -0
  73. package/templates/awa/.claude/skills/awa-validate-alignment/SKILL.md +3 -0
  74. package/templates/awa/.claude/skills/awa-vibe/SKILL.md +3 -0
  75. package/templates/awa/.codex/prompts/awa-architecture.md +3 -0
  76. package/templates/awa/.codex/prompts/awa-brainstorm.md +3 -0
  77. package/templates/awa/.codex/prompts/awa-code.md +3 -0
  78. package/templates/awa/.codex/prompts/awa-design.md +3 -0
  79. package/templates/awa/.codex/prompts/awa-documentation.md +3 -0
  80. package/templates/awa/.codex/prompts/awa-examples.md +3 -0
  81. package/templates/awa/.codex/prompts/awa-feature.md +3 -0
  82. package/templates/awa/.codex/prompts/awa-plan.md +3 -0
  83. package/templates/awa/.codex/prompts/awa-refactor.md +3 -0
  84. package/templates/awa/.codex/prompts/awa-requirements.md +3 -0
  85. package/templates/awa/.codex/prompts/awa-tasks.md +3 -0
  86. package/templates/awa/.codex/prompts/awa-upgrade.md +3 -0
  87. package/templates/awa/.codex/prompts/awa-validate-alignment.md +3 -0
  88. package/templates/awa/.codex/prompts/awa-vibe.md +3 -0
  89. package/templates/awa/.cursor/rules/awa-agent.md +14 -0
  90. package/templates/awa/.cursor/rules/awa-architecture.md +8 -0
  91. package/templates/awa/.cursor/rules/awa-brainstorm.md +8 -0
  92. package/templates/awa/.cursor/rules/awa-code.md +8 -0
  93. package/templates/awa/.cursor/rules/awa-design.md +8 -0
  94. package/templates/awa/.cursor/rules/awa-documentation.md +8 -0
  95. package/templates/awa/.cursor/rules/awa-examples.md +8 -0
  96. package/templates/awa/.cursor/rules/awa-feature.md +8 -0
  97. package/templates/awa/.cursor/rules/awa-plan.md +8 -0
  98. package/templates/awa/.cursor/rules/awa-refactor.md +8 -0
  99. package/templates/awa/.cursor/rules/awa-requirements.md +8 -0
  100. package/templates/awa/.cursor/rules/awa-tasks.md +8 -0
  101. package/templates/awa/.cursor/rules/awa-upgrade.md +8 -0
  102. package/templates/awa/.cursor/rules/awa-validate-alignment.md +8 -0
  103. package/templates/awa/.cursor/rules/awa-vibe.md +8 -0
  104. package/templates/awa/.gemini/commands/awa-architecture.md +3 -0
  105. package/templates/awa/.gemini/commands/awa-brainstorm.md +3 -0
  106. package/templates/awa/.gemini/commands/awa-code.md +3 -0
  107. package/templates/awa/.gemini/commands/awa-design.md +3 -0
  108. package/templates/awa/.gemini/commands/awa-documentation.md +3 -0
  109. package/templates/awa/.gemini/commands/awa-examples.md +3 -0
  110. package/templates/awa/.gemini/commands/awa-feature.md +3 -0
  111. package/templates/awa/.gemini/commands/awa-plan.md +3 -0
  112. package/templates/awa/.gemini/commands/awa-refactor.md +3 -0
  113. package/templates/awa/.gemini/commands/awa-requirements.md +3 -0
  114. package/templates/awa/.gemini/commands/awa-tasks.md +3 -0
  115. package/templates/awa/.gemini/commands/awa-upgrade.md +3 -0
  116. package/templates/awa/.gemini/commands/awa-validate-alignment.md +3 -0
  117. package/templates/awa/.gemini/commands/awa-vibe.md +3 -0
  118. package/templates/awa/.gemini/skills/awa-architecture/SKILL.md +3 -0
  119. package/templates/awa/.gemini/skills/awa-brainstorm/SKILL.md +3 -0
  120. package/templates/awa/.gemini/skills/awa-code/SKILL.md +3 -0
  121. package/templates/awa/.gemini/skills/awa-design/SKILL.md +3 -0
  122. package/templates/awa/.gemini/skills/awa-documentation/SKILL.md +3 -0
  123. package/templates/awa/.gemini/skills/awa-examples/SKILL.md +3 -0
  124. package/templates/awa/.gemini/skills/awa-feature/SKILL.md +3 -0
  125. package/templates/awa/.gemini/skills/awa-plan/SKILL.md +3 -0
  126. package/templates/awa/.gemini/skills/awa-refactor/SKILL.md +3 -0
  127. package/templates/awa/.gemini/skills/awa-requirements/SKILL.md +3 -0
  128. package/templates/awa/.gemini/skills/awa-tasks/SKILL.md +3 -0
  129. package/templates/awa/.gemini/skills/awa-upgrade/SKILL.md +3 -0
  130. package/templates/awa/.gemini/skills/awa-validate-alignment/SKILL.md +3 -0
  131. package/templates/awa/.gemini/skills/awa-vibe/SKILL.md +3 -0
  132. package/templates/awa/.github/agents/awa.agent.md +14 -0
  133. package/templates/awa/.github/prompts/awa.architecture.prompt.md +8 -0
  134. package/templates/awa/.github/prompts/awa.brainstorm.prompt.md +8 -0
  135. package/templates/awa/.github/prompts/awa.code.prompt.md +8 -0
  136. package/templates/awa/.github/prompts/awa.design.prompt.md +8 -0
  137. package/templates/awa/.github/prompts/awa.documentation.prompt.md +8 -0
  138. package/templates/awa/.github/prompts/awa.examples.prompt.md +8 -0
  139. package/templates/awa/.github/prompts/awa.feature.prompt.md +8 -0
  140. package/templates/awa/.github/prompts/awa.plan.prompt.md +8 -0
  141. package/templates/awa/.github/prompts/awa.refactor.prompt.md +8 -0
  142. package/templates/awa/.github/prompts/awa.requirements.prompt.md +8 -0
  143. package/templates/awa/.github/prompts/awa.tasks.prompt.md +8 -0
  144. package/templates/awa/.github/prompts/awa.upgrade.prompt.md +8 -0
  145. package/templates/awa/.github/prompts/awa.validate-alignment.prompt.md +8 -0
  146. package/templates/awa/.github/prompts/awa.vibe.prompt.md +8 -0
  147. package/templates/awa/.github/skills/awa-architecture/SKILL.md +8 -0
  148. package/templates/awa/.github/skills/awa-brainstorm/SKILL.md +8 -0
  149. package/templates/awa/.github/skills/awa-code/SKILL.md +8 -0
  150. package/templates/awa/.github/skills/awa-design/SKILL.md +8 -0
  151. package/templates/awa/.github/skills/awa-documentation/SKILL.md +8 -0
  152. package/templates/awa/.github/skills/awa-examples/SKILL.md +8 -0
  153. package/templates/awa/.github/skills/awa-feature/SKILL.md +8 -0
  154. package/templates/awa/.github/skills/awa-plan/SKILL.md +8 -0
  155. package/templates/awa/.github/skills/awa-refactor/SKILL.md +8 -0
  156. package/templates/awa/.github/skills/awa-requirements/SKILL.md +8 -0
  157. package/templates/awa/.github/skills/awa-tasks/SKILL.md +8 -0
  158. package/templates/awa/.github/skills/awa-upgrade/SKILL.md +8 -0
  159. package/templates/awa/.github/skills/awa-validate-alignment/SKILL.md +8 -0
  160. package/templates/awa/.github/skills/awa-vibe/SKILL.md +8 -0
  161. package/templates/awa/.kilocode/rules/awa-agent.md +13 -0
  162. package/templates/awa/.kilocode/skills/awa-architecture/SKILL.md +3 -0
  163. package/templates/awa/.kilocode/skills/awa-brainstorm/SKILL.md +3 -0
  164. package/templates/awa/.kilocode/skills/awa-code/SKILL.md +3 -0
  165. package/templates/awa/.kilocode/skills/awa-design/SKILL.md +3 -0
  166. package/templates/awa/.kilocode/skills/awa-documentation/SKILL.md +3 -0
  167. package/templates/awa/.kilocode/skills/awa-examples/SKILL.md +3 -0
  168. package/templates/awa/.kilocode/skills/awa-feature/SKILL.md +3 -0
  169. package/templates/awa/.kilocode/skills/awa-plan/SKILL.md +3 -0
  170. package/templates/awa/.kilocode/skills/awa-refactor/SKILL.md +3 -0
  171. package/templates/awa/.kilocode/skills/awa-requirements/SKILL.md +3 -0
  172. package/templates/awa/.kilocode/skills/awa-tasks/SKILL.md +3 -0
  173. package/templates/awa/.kilocode/skills/awa-upgrade/SKILL.md +3 -0
  174. package/templates/awa/.kilocode/skills/awa-validate-alignment/SKILL.md +3 -0
  175. package/templates/awa/.kilocode/skills/awa-vibe/SKILL.md +3 -0
  176. package/templates/awa/.kilocode/workflows/awa-architecture.md +3 -0
  177. package/templates/awa/.kilocode/workflows/awa-brainstorm.md +3 -0
  178. package/templates/awa/.kilocode/workflows/awa-code.md +3 -0
  179. package/templates/awa/.kilocode/workflows/awa-design.md +3 -0
  180. package/templates/awa/.kilocode/workflows/awa-documentation.md +3 -0
  181. package/templates/awa/.kilocode/workflows/awa-examples.md +3 -0
  182. package/templates/awa/.kilocode/workflows/awa-feature.md +3 -0
  183. package/templates/awa/.kilocode/workflows/awa-plan.md +3 -0
  184. package/templates/awa/.kilocode/workflows/awa-refactor.md +3 -0
  185. package/templates/awa/.kilocode/workflows/awa-requirements.md +3 -0
  186. package/templates/awa/.kilocode/workflows/awa-tasks.md +3 -0
  187. package/templates/awa/.kilocode/workflows/awa-upgrade.md +3 -0
  188. package/templates/awa/.kilocode/workflows/awa-validate-alignment.md +3 -0
  189. package/templates/awa/.kilocode/workflows/awa-vibe.md +3 -0
  190. package/templates/awa/.opencode/agents/awa.md +14 -0
  191. package/templates/awa/.opencode/commands/awa-architecture.md +3 -0
  192. package/templates/awa/.opencode/commands/awa-brainstorm.md +3 -0
  193. package/templates/awa/.opencode/commands/awa-code.md +3 -0
  194. package/templates/awa/.opencode/commands/awa-design.md +3 -0
  195. package/templates/awa/.opencode/commands/awa-documentation.md +3 -0
  196. package/templates/awa/.opencode/commands/awa-examples.md +3 -0
  197. package/templates/awa/.opencode/commands/awa-feature.md +3 -0
  198. package/templates/awa/.opencode/commands/awa-plan.md +3 -0
  199. package/templates/awa/.opencode/commands/awa-refactor.md +3 -0
  200. package/templates/awa/.opencode/commands/awa-requirements.md +3 -0
  201. package/templates/awa/.opencode/commands/awa-tasks.md +3 -0
  202. package/templates/awa/.opencode/commands/awa-upgrade.md +3 -0
  203. package/templates/awa/.opencode/commands/awa-validate-alignment.md +3 -0
  204. package/templates/awa/.opencode/commands/awa-vibe.md +3 -0
  205. package/templates/awa/.opencode/skills/awa-architecture/SKILL.md +3 -0
  206. package/templates/awa/.opencode/skills/awa-brainstorm/SKILL.md +3 -0
  207. package/templates/awa/.opencode/skills/awa-code/SKILL.md +3 -0
  208. package/templates/awa/.opencode/skills/awa-design/SKILL.md +3 -0
  209. package/templates/awa/.opencode/skills/awa-documentation/SKILL.md +3 -0
  210. package/templates/awa/.opencode/skills/awa-examples/SKILL.md +3 -0
  211. package/templates/awa/.opencode/skills/awa-feature/SKILL.md +3 -0
  212. package/templates/awa/.opencode/skills/awa-plan/SKILL.md +3 -0
  213. package/templates/awa/.opencode/skills/awa-refactor/SKILL.md +3 -0
  214. package/templates/awa/.opencode/skills/awa-requirements/SKILL.md +3 -0
  215. package/templates/awa/.opencode/skills/awa-tasks/SKILL.md +3 -0
  216. package/templates/awa/.opencode/skills/awa-upgrade/SKILL.md +3 -0
  217. package/templates/awa/.opencode/skills/awa-validate-alignment/SKILL.md +3 -0
  218. package/templates/awa/.opencode/skills/awa-vibe/SKILL.md +3 -0
  219. package/templates/awa/.qwen/commands/awa-architecture.md +3 -0
  220. package/templates/awa/.qwen/commands/awa-brainstorm.md +3 -0
  221. package/templates/awa/.qwen/commands/awa-code.md +3 -0
  222. package/templates/awa/.qwen/commands/awa-design.md +3 -0
  223. package/templates/awa/.qwen/commands/awa-documentation.md +3 -0
  224. package/templates/awa/.qwen/commands/awa-examples.md +3 -0
  225. package/templates/awa/.qwen/commands/awa-feature.md +3 -0
  226. package/templates/awa/.qwen/commands/awa-plan.md +3 -0
  227. package/templates/awa/.qwen/commands/awa-refactor.md +3 -0
  228. package/templates/awa/.qwen/commands/awa-requirements.md +3 -0
  229. package/templates/awa/.qwen/commands/awa-tasks.md +3 -0
  230. package/templates/awa/.qwen/commands/awa-upgrade.md +3 -0
  231. package/templates/awa/.qwen/commands/awa-validate-alignment.md +3 -0
  232. package/templates/awa/.qwen/commands/awa-vibe.md +3 -0
  233. package/templates/awa/.qwen/skills/awa-architecture/SKILL.md +3 -0
  234. package/templates/awa/.qwen/skills/awa-brainstorm/SKILL.md +3 -0
  235. package/templates/awa/.qwen/skills/awa-code/SKILL.md +3 -0
  236. package/templates/awa/.qwen/skills/awa-design/SKILL.md +3 -0
  237. package/templates/awa/.qwen/skills/awa-documentation/SKILL.md +3 -0
  238. package/templates/awa/.qwen/skills/awa-examples/SKILL.md +3 -0
  239. package/templates/awa/.qwen/skills/awa-feature/SKILL.md +3 -0
  240. package/templates/awa/.qwen/skills/awa-plan/SKILL.md +3 -0
  241. package/templates/awa/.qwen/skills/awa-refactor/SKILL.md +3 -0
  242. package/templates/awa/.qwen/skills/awa-requirements/SKILL.md +3 -0
  243. package/templates/awa/.qwen/skills/awa-tasks/SKILL.md +3 -0
  244. package/templates/awa/.qwen/skills/awa-upgrade/SKILL.md +3 -0
  245. package/templates/awa/.qwen/skills/awa-validate-alignment/SKILL.md +3 -0
  246. package/templates/awa/.qwen/skills/awa-vibe/SKILL.md +3 -0
  247. package/templates/awa/.roo/rules/awa-agent.md +13 -0
  248. package/templates/awa/.roo/skills/awa-architecture/SKILL.md +3 -0
  249. package/templates/awa/.roo/skills/awa-brainstorm/SKILL.md +3 -0
  250. package/templates/awa/.roo/skills/awa-code/SKILL.md +3 -0
  251. package/templates/awa/.roo/skills/awa-design/SKILL.md +3 -0
  252. package/templates/awa/.roo/skills/awa-documentation/SKILL.md +3 -0
  253. package/templates/awa/.roo/skills/awa-examples/SKILL.md +3 -0
  254. package/templates/awa/.roo/skills/awa-feature/SKILL.md +3 -0
  255. package/templates/awa/.roo/skills/awa-plan/SKILL.md +3 -0
  256. package/templates/awa/.roo/skills/awa-refactor/SKILL.md +3 -0
  257. package/templates/awa/.roo/skills/awa-requirements/SKILL.md +3 -0
  258. package/templates/awa/.roo/skills/awa-tasks/SKILL.md +3 -0
  259. package/templates/awa/.roo/skills/awa-upgrade/SKILL.md +3 -0
  260. package/templates/awa/.roo/skills/awa-validate-alignment/SKILL.md +3 -0
  261. package/templates/awa/.roo/skills/awa-vibe/SKILL.md +3 -0
  262. package/templates/awa/.windsurf/rules/awa-agent.md +14 -0
  263. package/templates/awa/.windsurf/skills/awa-architecture/SKILL.md +3 -0
  264. package/templates/awa/.windsurf/skills/awa-brainstorm/SKILL.md +3 -0
  265. package/templates/awa/.windsurf/skills/awa-code/SKILL.md +3 -0
  266. package/templates/awa/.windsurf/skills/awa-design/SKILL.md +3 -0
  267. package/templates/awa/.windsurf/skills/awa-documentation/SKILL.md +3 -0
  268. package/templates/awa/.windsurf/skills/awa-examples/SKILL.md +3 -0
  269. package/templates/awa/.windsurf/skills/awa-feature/SKILL.md +3 -0
  270. package/templates/awa/.windsurf/skills/awa-plan/SKILL.md +3 -0
  271. package/templates/awa/.windsurf/skills/awa-refactor/SKILL.md +3 -0
  272. package/templates/awa/.windsurf/skills/awa-requirements/SKILL.md +3 -0
  273. package/templates/awa/.windsurf/skills/awa-tasks/SKILL.md +3 -0
  274. package/templates/awa/.windsurf/skills/awa-upgrade/SKILL.md +3 -0
  275. package/templates/awa/.windsurf/skills/awa-validate-alignment/SKILL.md +3 -0
  276. package/templates/awa/.windsurf/skills/awa-vibe/SKILL.md +3 -0
  277. package/templates/awa/AGENTS.md +9 -0
  278. package/templates/awa/CLAUDE.md +9 -0
  279. package/templates/awa/GEMINI.md +9 -0
  280. package/templates/awa/QWEN.md +9 -0
  281. package/templates/awa/_README.md +86 -0
  282. package/templates/awa/_delete.txt +300 -0
  283. package/templates/awa/_partials/_cmd.awa-architecture.md +6 -0
  284. package/templates/awa/_partials/_cmd.awa-brainstorm.md +6 -0
  285. package/templates/awa/_partials/_cmd.awa-code.md +6 -0
  286. package/templates/awa/_partials/_cmd.awa-design.md +6 -0
  287. package/templates/awa/_partials/_cmd.awa-documentation.md +6 -0
  288. package/templates/awa/_partials/_cmd.awa-examples.md +6 -0
  289. package/templates/awa/_partials/_cmd.awa-feature.md +6 -0
  290. package/templates/awa/_partials/_cmd.awa-plan.md +6 -0
  291. package/templates/awa/_partials/_cmd.awa-refactor.md +6 -0
  292. package/templates/awa/_partials/_cmd.awa-requirements.md +6 -0
  293. package/templates/awa/_partials/_cmd.awa-tasks.md +6 -0
  294. package/templates/awa/_partials/_cmd.awa-upgrade.md +6 -0
  295. package/templates/awa/_partials/_cmd.awa-validate-alignment.md +6 -0
  296. package/templates/awa/_partials/_cmd.awa-vibe.md +6 -0
  297. package/templates/awa/_partials/_skill.awa-architecture.md +6 -0
  298. package/templates/awa/_partials/_skill.awa-brainstorm.md +6 -0
  299. package/templates/awa/_partials/_skill.awa-code.md +6 -0
  300. package/templates/awa/_partials/_skill.awa-design.md +6 -0
  301. package/templates/awa/_partials/_skill.awa-documentation.md +6 -0
  302. package/templates/awa/_partials/_skill.awa-examples.md +6 -0
  303. package/templates/awa/_partials/_skill.awa-feature.md +6 -0
  304. package/templates/awa/_partials/_skill.awa-plan.md +6 -0
  305. package/templates/awa/_partials/_skill.awa-refactor.md +6 -0
  306. package/templates/awa/_partials/_skill.awa-requirements.md +6 -0
  307. package/templates/awa/_partials/_skill.awa-tasks.md +6 -0
  308. package/templates/awa/_partials/_skill.awa-upgrade.md +6 -0
  309. package/templates/awa/_partials/_skill.awa-validate-alignment.md +6 -0
  310. package/templates/awa/_partials/_skill.awa-vibe.md +6 -0
  311. package/templates/awa/_partials/awa.architecture.md +45 -0
  312. package/templates/awa/_partials/awa.brainstorm.md +52 -0
  313. package/templates/awa/_partials/awa.code.md +167 -0
  314. package/templates/awa/_partials/awa.core.md +100 -0
  315. package/templates/awa/_partials/awa.design.md +55 -0
  316. package/templates/awa/_partials/awa.documentation.md +86 -0
  317. package/templates/awa/_partials/awa.examples.md +53 -0
  318. package/templates/awa/_partials/awa.feature.md +50 -0
  319. package/templates/awa/_partials/awa.plan.md +48 -0
  320. package/templates/awa/_partials/awa.refactor.md +46 -0
  321. package/templates/awa/_partials/awa.requirements.md +50 -0
  322. package/templates/awa/_partials/awa.tasks.md +147 -0
  323. package/templates/awa/_partials/awa.upgrade.md +63 -0
  324. package/templates/awa/_partials/awa.validate-alignment.md +62 -0
  325. package/templates/awa/_partials/awa.vibe.md +64 -0
  326. package/templates/example/.github/agents/example.agent.md +14 -0
  327. package/templates/example/_README.md +43 -0
  328. package/templates/example/_partials/planning.md +5 -0
  329. package/templates/example/agent.md +72 -0
package/dist/index.js ADDED
@@ -0,0 +1,1353 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli/index.ts
4
+ import { Command } from "commander";
5
+
6
+ // src/_generated/package_info.ts
7
+ var PACKAGE_INFO = {
8
+ "name": "@ncoderz/awa",
9
+ "version": "0.2.0",
10
+ "author": "Richard Sewell <richard.sewell@ncoderz.com>",
11
+ "license": "MIT",
12
+ "description": "awa is an Agent Workflow for AIs. It is also a CLI tool to powerfully manage agent workflow files using templates."
13
+ };
14
+
15
+ // src/commands/diff.ts
16
+ import { intro, outro } from "@clack/prompts";
17
+
18
+ // src/core/config.ts
19
+ import { parse } from "smol-toml";
20
+
21
+ // src/types/index.ts
22
+ var DiffError = class extends Error {
23
+ constructor(message) {
24
+ super(message);
25
+ this.name = "DiffError";
26
+ }
27
+ };
28
+ var ConfigError = class extends Error {
29
+ constructor(message, code, filePath) {
30
+ super(message);
31
+ this.code = code;
32
+ this.filePath = filePath;
33
+ this.name = "ConfigError";
34
+ }
35
+ };
36
+ var TemplateError = class extends Error {
37
+ constructor(message, code, source) {
38
+ super(message);
39
+ this.code = code;
40
+ this.source = source;
41
+ this.name = "TemplateError";
42
+ }
43
+ };
44
+ var GenerationError = class extends Error {
45
+ constructor(message, code) {
46
+ super(message);
47
+ this.code = code;
48
+ this.name = "GenerationError";
49
+ }
50
+ };
51
+
52
+ // src/utils/fs.ts
53
+ import { mkdir, readdir, readFile, rm, stat, writeFile } from "fs/promises";
54
+ import { homedir } from "os";
55
+ import { dirname, join } from "path";
56
+ import { fileURLToPath } from "url";
57
+ async function ensureDir(dirPath) {
58
+ await mkdir(dirPath, { recursive: true });
59
+ }
60
+ async function pathExists(path) {
61
+ try {
62
+ await stat(path);
63
+ return true;
64
+ } catch {
65
+ return false;
66
+ }
67
+ }
68
+ async function readTextFile(path) {
69
+ return readFile(path, "utf-8");
70
+ }
71
+ async function readBinaryFile(path) {
72
+ return readFile(path);
73
+ }
74
+ async function writeTextFile(path, content) {
75
+ await ensureDir(dirname(path));
76
+ await writeFile(path, content, "utf-8");
77
+ }
78
+ async function* walkDirectory(dir) {
79
+ const entries = await readdir(dir, { withFileTypes: true });
80
+ for (const entry of entries) {
81
+ const fullPath = join(dir, entry.name);
82
+ if (entry.isDirectory()) {
83
+ if (entry.name.startsWith("_")) {
84
+ continue;
85
+ }
86
+ yield* walkDirectory(fullPath);
87
+ } else if (entry.isFile()) {
88
+ if (entry.name.startsWith("_")) {
89
+ continue;
90
+ }
91
+ yield fullPath;
92
+ }
93
+ }
94
+ }
95
+ function getCacheDir() {
96
+ return join(homedir(), ".cache", "awa", "templates");
97
+ }
98
+ function getTemplateDir() {
99
+ const currentFile = fileURLToPath(import.meta.url);
100
+ const currentDir = dirname(currentFile);
101
+ if (currentDir.includes("/dist")) {
102
+ return join(dirname(currentDir), "templates");
103
+ }
104
+ return join(currentDir, "..", "..", "templates");
105
+ }
106
+ async function rmDir(dirPath) {
107
+ await rm(dirPath, { recursive: true, force: true });
108
+ }
109
+ async function deleteFile(filePath) {
110
+ await rm(filePath, { force: true });
111
+ }
112
+
113
+ // src/utils/logger.ts
114
+ import chalk from "chalk";
115
+ var Logger = class {
116
+ info(message) {
117
+ console.log(chalk.blue("\u2139"), message);
118
+ }
119
+ success(message) {
120
+ console.log(chalk.green("\u2714"), message);
121
+ }
122
+ warn(message) {
123
+ console.warn(chalk.yellow("\u26A0"), message);
124
+ }
125
+ error(message) {
126
+ console.error(chalk.red("\u2716"), message);
127
+ }
128
+ fileAction(action) {
129
+ const { type, outputPath } = action;
130
+ switch (type) {
131
+ case "create":
132
+ console.log(chalk.green(" + "), chalk.dim(outputPath));
133
+ break;
134
+ case "overwrite":
135
+ console.log(chalk.yellow(" ~ "), chalk.dim(outputPath));
136
+ break;
137
+ case "skip-user":
138
+ console.log(chalk.blue(" - "), chalk.dim(outputPath), chalk.dim("(skipped)"));
139
+ break;
140
+ case "skip-empty":
141
+ console.log(chalk.dim(" \xB7 "), chalk.dim(outputPath), chalk.dim("(empty)"));
142
+ break;
143
+ case "skip-equal":
144
+ console.log(chalk.dim(" = "), chalk.dim(outputPath), chalk.dim("(unchanged)"));
145
+ break;
146
+ case "delete":
147
+ console.log(chalk.red(" \u2716 "), chalk.dim(outputPath), chalk.red("(deleted)"));
148
+ break;
149
+ }
150
+ }
151
+ // @awa-impl: GEN-9_AC-1, GEN-9_AC-2, GEN-9_AC-3, GEN-9_AC-4, GEN-9_AC-5, GEN-9_AC-6
152
+ summary(result) {
153
+ console.log("");
154
+ console.log(chalk.bold("Summary:"));
155
+ if (result.created === 0 && result.overwritten === 0 && result.deleted === 0) {
156
+ console.log(chalk.yellow(" \u26A0 No files were created, overwritten, or deleted"));
157
+ }
158
+ if (result.created > 0) {
159
+ console.log(chalk.green(` Created: ${result.created}`));
160
+ }
161
+ if (result.overwritten > 0) {
162
+ console.log(chalk.yellow(` Overwritten: ${result.overwritten}`));
163
+ }
164
+ if (result.deleted > 0) {
165
+ console.log(chalk.red(` Deleted: ${result.deleted}`));
166
+ }
167
+ if (result.skippedEqual > 0) {
168
+ console.log(chalk.dim(` Skipped (equal): ${result.skippedEqual}`));
169
+ }
170
+ if (result.skippedUser > 0) {
171
+ console.log(chalk.blue(` Skipped (user): ${result.skippedUser}`));
172
+ }
173
+ if (result.skippedEmpty > 0) {
174
+ console.log(chalk.dim(` Skipped (empty): ${result.skippedEmpty}`));
175
+ }
176
+ console.log("");
177
+ }
178
+ // @awa-impl: DIFF-4_AC-3
179
+ diffLine(line, type) {
180
+ switch (type) {
181
+ case "add":
182
+ console.log(chalk.green(line));
183
+ break;
184
+ case "remove":
185
+ console.log(chalk.red(line));
186
+ break;
187
+ case "context":
188
+ console.log(chalk.dim(line));
189
+ break;
190
+ }
191
+ }
192
+ // @awa-impl: DIFF-4_AC-4, DIFF-4_AC-5
193
+ diffSummary(result) {
194
+ console.log("");
195
+ const filesCompared = result.identical + result.modified + result.newFiles + result.extraFiles + result.binaryDiffers + result.deleteListed;
196
+ const differences = result.modified + result.newFiles + result.extraFiles + result.binaryDiffers + result.deleteListed;
197
+ console.log(chalk.bold(`${filesCompared} files compared, ${differences} differences`));
198
+ if (!result.hasDifferences) {
199
+ console.log(chalk.green("\u2714 No differences found"));
200
+ }
201
+ console.log(chalk.bold("Summary:"));
202
+ console.log(chalk.dim(` Identical: ${result.identical}`));
203
+ if (result.modified > 0) {
204
+ console.log(chalk.yellow(` Modified: ${result.modified}`));
205
+ }
206
+ if (result.newFiles > 0) {
207
+ console.log(chalk.green(` New: ${result.newFiles}`));
208
+ }
209
+ if (result.extraFiles > 0) {
210
+ console.log(chalk.red(` Extra: ${result.extraFiles}`));
211
+ }
212
+ if (result.binaryDiffers > 0) {
213
+ console.log(chalk.red(` Binary differs: ${result.binaryDiffers}`));
214
+ }
215
+ if (result.deleteListed > 0) {
216
+ console.log(chalk.red(` Delete listed: ${result.deleteListed}`));
217
+ }
218
+ console.log("");
219
+ }
220
+ };
221
+ var logger = new Logger();
222
+
223
+ // src/core/config.ts
224
+ var DEFAULT_CONFIG_PATH = ".awa.toml";
225
+ var ConfigLoader = class {
226
+ // @awa-impl: CFG-1_AC-1, CFG-1_AC-2, CFG-1_AC-3, CFG-1_AC-4
227
+ async load(configPath) {
228
+ const pathToLoad = configPath ?? DEFAULT_CONFIG_PATH;
229
+ const exists = await pathExists(pathToLoad);
230
+ if (configPath && !exists) {
231
+ throw new ConfigError(
232
+ `Configuration file not found: ${configPath}`,
233
+ "FILE_NOT_FOUND",
234
+ configPath
235
+ );
236
+ }
237
+ if (!configPath && !exists) {
238
+ return null;
239
+ }
240
+ try {
241
+ const content = await readTextFile(pathToLoad);
242
+ const parsed = parse(content);
243
+ const config = {};
244
+ if (parsed.output !== void 0) {
245
+ if (typeof parsed.output !== "string") {
246
+ throw new ConfigError(
247
+ `Invalid type for 'output': expected string, got ${typeof parsed.output}`,
248
+ "INVALID_TYPE",
249
+ pathToLoad
250
+ );
251
+ }
252
+ config.output = parsed.output;
253
+ }
254
+ if (parsed.template !== void 0) {
255
+ if (typeof parsed.template !== "string") {
256
+ throw new ConfigError(
257
+ `Invalid type for 'template': expected string, got ${typeof parsed.template}`,
258
+ "INVALID_TYPE",
259
+ pathToLoad
260
+ );
261
+ }
262
+ config.template = parsed.template;
263
+ }
264
+ if (parsed.features !== void 0) {
265
+ if (!Array.isArray(parsed.features) || !parsed.features.every((f) => typeof f === "string")) {
266
+ throw new ConfigError(
267
+ `Invalid type for 'features': expected array of strings`,
268
+ "INVALID_TYPE",
269
+ pathToLoad
270
+ );
271
+ }
272
+ config.features = parsed.features;
273
+ }
274
+ if (parsed.preset !== void 0) {
275
+ if (!Array.isArray(parsed.preset) || !parsed.preset.every((p) => typeof p === "string")) {
276
+ throw new ConfigError(
277
+ `Invalid type for 'preset': expected array of strings`,
278
+ "INVALID_TYPE",
279
+ pathToLoad
280
+ );
281
+ }
282
+ config.preset = parsed.preset;
283
+ }
284
+ if (parsed["remove-features"] !== void 0) {
285
+ if (!Array.isArray(parsed["remove-features"]) || !parsed["remove-features"].every((f) => typeof f === "string")) {
286
+ throw new ConfigError(
287
+ `Invalid type for 'remove-features': expected array of strings`,
288
+ "INVALID_TYPE",
289
+ pathToLoad
290
+ );
291
+ }
292
+ config["remove-features"] = parsed["remove-features"];
293
+ }
294
+ if (parsed.force !== void 0) {
295
+ if (typeof parsed.force !== "boolean") {
296
+ throw new ConfigError(
297
+ `Invalid type for 'force': expected boolean, got ${typeof parsed.force}`,
298
+ "INVALID_TYPE",
299
+ pathToLoad
300
+ );
301
+ }
302
+ config.force = parsed.force;
303
+ }
304
+ if (parsed["dry-run"] !== void 0) {
305
+ if (typeof parsed["dry-run"] !== "boolean") {
306
+ throw new ConfigError(
307
+ `Invalid type for 'dry-run': expected boolean, got ${typeof parsed["dry-run"]}`,
308
+ "INVALID_TYPE",
309
+ pathToLoad
310
+ );
311
+ }
312
+ config["dry-run"] = parsed["dry-run"];
313
+ }
314
+ if (parsed.delete !== void 0) {
315
+ if (typeof parsed.delete !== "boolean") {
316
+ throw new ConfigError(
317
+ `Invalid type for 'delete': expected boolean, got ${typeof parsed.delete}`,
318
+ "INVALID_TYPE",
319
+ pathToLoad
320
+ );
321
+ }
322
+ config.delete = parsed.delete;
323
+ }
324
+ if (parsed.refresh !== void 0) {
325
+ if (typeof parsed.refresh !== "boolean") {
326
+ throw new ConfigError(
327
+ `Invalid type for 'refresh': expected boolean, got ${typeof parsed.refresh}`,
328
+ "INVALID_TYPE",
329
+ pathToLoad
330
+ );
331
+ }
332
+ config.refresh = parsed.refresh;
333
+ }
334
+ if (parsed.presets !== void 0) {
335
+ if (parsed.presets === null || typeof parsed.presets !== "object" || Array.isArray(parsed.presets)) {
336
+ throw new ConfigError(
337
+ `Invalid type for 'presets': expected table of string arrays`,
338
+ "INVALID_PRESET",
339
+ pathToLoad
340
+ );
341
+ }
342
+ const defs = {};
343
+ for (const [presetName, value] of Object.entries(
344
+ parsed.presets
345
+ )) {
346
+ if (!Array.isArray(value) || !value.every((v) => typeof v === "string")) {
347
+ throw new ConfigError(
348
+ `Invalid preset '${presetName}': expected array of strings`,
349
+ "INVALID_PRESET",
350
+ pathToLoad
351
+ );
352
+ }
353
+ defs[presetName] = value;
354
+ }
355
+ config.presets = defs;
356
+ }
357
+ if (parsed["list-unknown"] !== void 0) {
358
+ if (typeof parsed["list-unknown"] !== "boolean") {
359
+ throw new ConfigError(
360
+ `Invalid type for 'list-unknown': expected boolean, got ${typeof parsed["list-unknown"]}`,
361
+ "INVALID_TYPE",
362
+ pathToLoad
363
+ );
364
+ }
365
+ config["list-unknown"] = parsed["list-unknown"];
366
+ }
367
+ const knownKeys = /* @__PURE__ */ new Set([
368
+ "output",
369
+ "template",
370
+ "features",
371
+ "preset",
372
+ "remove-features",
373
+ "presets",
374
+ "force",
375
+ "dry-run",
376
+ "delete",
377
+ "refresh",
378
+ "list-unknown"
379
+ ]);
380
+ for (const key of Object.keys(parsed)) {
381
+ if (!knownKeys.has(key)) {
382
+ logger.warn(`Unknown configuration option: '${key}'`);
383
+ }
384
+ }
385
+ return config;
386
+ } catch (error) {
387
+ if (error instanceof ConfigError) {
388
+ throw error;
389
+ }
390
+ throw new ConfigError(
391
+ `Failed to parse TOML configuration: ${error instanceof Error ? error.message : String(error)}`,
392
+ "PARSE_ERROR",
393
+ pathToLoad
394
+ );
395
+ }
396
+ }
397
+ // @awa-impl: CFG-4_AC-1, CFG-4_AC-2, CFG-4_AC-3, CFG-4_AC-4
398
+ // @awa-impl: CLI-2_AC-2, CLI-2_AC-3, CLI-2_AC-4
399
+ merge(cli, file) {
400
+ const output = cli.output ?? file?.output;
401
+ if (!output) {
402
+ throw new ConfigError(
403
+ "Output directory is required. Provide it as a positional argument or in the config file.",
404
+ "MISSING_OUTPUT",
405
+ null
406
+ );
407
+ }
408
+ const template = cli.template ?? file?.template ?? null;
409
+ const features = cli.features ?? file?.features ?? [];
410
+ const preset = cli.preset ?? file?.preset ?? [];
411
+ const removeFeatures = cli.removeFeatures ?? file?.["remove-features"] ?? [];
412
+ const presets = file?.presets ?? {};
413
+ const force = cli.force ?? file?.force ?? false;
414
+ const dryRun = cli.dryRun ?? file?.["dry-run"] ?? false;
415
+ const enableDelete = cli.delete ?? file?.delete ?? false;
416
+ const refresh = cli.refresh ?? file?.refresh ?? false;
417
+ const listUnknown = cli.listUnknown ?? file?.["list-unknown"] ?? false;
418
+ return {
419
+ output,
420
+ template,
421
+ features,
422
+ preset,
423
+ removeFeatures,
424
+ force,
425
+ dryRun,
426
+ delete: enableDelete,
427
+ refresh,
428
+ presets,
429
+ listUnknown
430
+ };
431
+ }
432
+ };
433
+ var configLoader = new ConfigLoader();
434
+
435
+ // src/core/differ.ts
436
+ import { tmpdir } from "os";
437
+ import { join as join4, relative as relative2 } from "path";
438
+ import { structuredPatch } from "diff";
439
+ import { isBinaryFile as detectBinaryFile } from "isbinaryfile";
440
+
441
+ // src/core/delete-list.ts
442
+ import { join as join2 } from "path";
443
+ var DELETE_LIST_FILENAME = "_delete.txt";
444
+ function parseDeleteList(content) {
445
+ const entries = [];
446
+ let currentFeatures;
447
+ for (const raw of content.split("\n")) {
448
+ const line = raw.trim();
449
+ if (line.length === 0) continue;
450
+ if (line.startsWith("#")) {
451
+ const featureMatch = line.match(/^#\s*@feature\s+(.+)$/);
452
+ if (featureMatch) {
453
+ const featureSection = featureMatch[1];
454
+ currentFeatures = featureSection ? featureSection.trim().split(/\s+/) : void 0;
455
+ } else {
456
+ currentFeatures = void 0;
457
+ }
458
+ continue;
459
+ }
460
+ entries.push({ path: line, features: currentFeatures });
461
+ }
462
+ return entries;
463
+ }
464
+ function resolveDeleteList(entries, activeFeatures) {
465
+ const activeSet = new Set(activeFeatures);
466
+ return entries.filter((e) => e.features === void 0 || !e.features.some((f) => activeSet.has(f))).map((e) => e.path);
467
+ }
468
+ async function loadDeleteList(templatePath) {
469
+ const deleteListPath = join2(templatePath, DELETE_LIST_FILENAME);
470
+ if (!await pathExists(deleteListPath)) {
471
+ return [];
472
+ }
473
+ const content = await readTextFile(deleteListPath);
474
+ return parseDeleteList(content);
475
+ }
476
+
477
+ // src/core/generator.ts
478
+ import { join as join3, relative } from "path";
479
+
480
+ // src/core/resolver.ts
481
+ import { MultiSelectPrompt } from "@clack/core";
482
+ import { isCancel, multiselect } from "@clack/prompts";
483
+ import chalk2 from "chalk";
484
+ var _unicode = process.platform !== "win32";
485
+ var _s = (c, fb) => _unicode ? c : fb;
486
+ var _CHECKED = _s("\u25FC", "[+]");
487
+ var _UNCHECKED_A = _s("\u25FB", "[\xB7]");
488
+ var _UNCHECKED = _s("\u25FB", "[ ]");
489
+ var _BAR = _s("\u2502", "|");
490
+ var _BAR_END = _s("\u2514", "-");
491
+ function _renderDeleteItem(opt, state) {
492
+ const label = opt.label ?? opt.value;
493
+ const hint = opt.hint ? ` ${chalk2.dim(`(${opt.hint})`)}` : "";
494
+ switch (state) {
495
+ case "active":
496
+ return `${chalk2.cyan(_UNCHECKED_A)} ${label}${hint}`;
497
+ case "selected":
498
+ return `${chalk2.red(_CHECKED)} ${chalk2.dim(label)}${hint}`;
499
+ case "active-selected":
500
+ return `${chalk2.red(_CHECKED)} ${label}${hint}`;
501
+ case "cancelled":
502
+ return chalk2.strikethrough(chalk2.dim(label));
503
+ case "submitted":
504
+ return chalk2.dim(label);
505
+ default:
506
+ return `${chalk2.dim(_UNCHECKED)} ${chalk2.dim(label)}`;
507
+ }
508
+ }
509
+ async function deleteMultiselect(opts) {
510
+ const { message, options, initialValues, required = false } = opts;
511
+ return new MultiSelectPrompt({
512
+ options,
513
+ initialValues,
514
+ required,
515
+ render() {
516
+ const self = this;
517
+ const header = `${chalk2.gray(_BAR)}
518
+ ${chalk2.cyan(_BAR)} ${message}
519
+ `;
520
+ const getState = (opt, idx) => {
521
+ const active = idx === self.cursor;
522
+ const sel = self.value.includes(opt.value);
523
+ if (active && sel) return "active-selected";
524
+ if (sel) return "selected";
525
+ if (active) return "active";
526
+ return "inactive";
527
+ };
528
+ switch (self.state) {
529
+ case "submit":
530
+ return `${header}${chalk2.gray(_BAR)} ` + (self.options.filter((o) => self.value.includes(o.value)).map((o) => _renderDeleteItem(o, "submitted")).join(chalk2.dim(", ")) || chalk2.dim("none"));
531
+ case "cancel": {
532
+ const cancelled = self.options.filter((o) => self.value.includes(o.value)).map((o) => _renderDeleteItem(o, "cancelled")).join(chalk2.dim(", "));
533
+ return `${header}${chalk2.gray(_BAR)} ${cancelled.trim() ? `${cancelled}
534
+ ${chalk2.gray(_BAR)}` : chalk2.dim("none")}`;
535
+ }
536
+ default:
537
+ return `${header}${chalk2.cyan(_BAR)} ` + self.options.map((o, i) => _renderDeleteItem(o, getState(o, i))).join(`
538
+ ${chalk2.cyan(_BAR)} `) + `
539
+ ${chalk2.cyan(_BAR_END)}
540
+ `;
541
+ }
542
+ }
543
+ }).prompt();
544
+ }
545
+ var ConflictResolver = class {
546
+ // @awa-impl: GEN-4_AC-1, GEN-4_AC-2, GEN-4_AC-3
547
+ // @awa-impl: GEN-5_AC-1, GEN-5_AC-2, GEN-5_AC-3, GEN-5_AC-4, GEN-5_AC-5, GEN-5_AC-6, GEN-5_AC-7
548
+ // @awa-impl: CLI-5_AC-2, CLI-5_AC-3
549
+ // @awa-impl: GEN-6_AC-3
550
+ async resolveBatch(conflicts, force, dryRun) {
551
+ const identicalPaths = conflicts.filter((c) => c.newContent === c.existingContent).map((c) => c.outputPath);
552
+ const differentFiles = conflicts.filter((c) => c.newContent !== c.existingContent);
553
+ if (dryRun) {
554
+ return {
555
+ overwrite: [],
556
+ skip: differentFiles.map((c) => c.outputPath),
557
+ equal: identicalPaths
558
+ };
559
+ }
560
+ if (force) {
561
+ return {
562
+ overwrite: differentFiles.map((c) => c.outputPath),
563
+ skip: [],
564
+ equal: identicalPaths
565
+ };
566
+ }
567
+ if (differentFiles.length === 0) {
568
+ return {
569
+ overwrite: [],
570
+ skip: [],
571
+ equal: identicalPaths
572
+ };
573
+ }
574
+ const selected = await multiselect({
575
+ message: "The following files already exist. Select files to overwrite:",
576
+ options: differentFiles.map((c) => ({
577
+ value: c.outputPath,
578
+ label: c.outputPath
579
+ })),
580
+ initialValues: differentFiles.map((c) => c.outputPath),
581
+ // All selected by default (AC-5.6)
582
+ required: false
583
+ });
584
+ if (isCancel(selected)) {
585
+ process.exit(1);
586
+ }
587
+ const selectedPaths = selected;
588
+ const allPaths = differentFiles.map((c) => c.outputPath);
589
+ return {
590
+ overwrite: selectedPaths,
591
+ skip: allPaths.filter((p) => !selectedPaths.includes(p)),
592
+ equal: identicalPaths
593
+ };
594
+ }
595
+ };
596
+ var conflictResolver = new ConflictResolver();
597
+ var DeleteResolver = class {
598
+ /**
599
+ * Prompt user to confirm which files to delete.
600
+ * Returns the list of absolute paths confirmed for deletion.
601
+ */
602
+ async resolveDeletes(candidates, force, dryRun) {
603
+ if (candidates.length === 0) {
604
+ return [];
605
+ }
606
+ if (dryRun) {
607
+ return candidates;
608
+ }
609
+ if (force) {
610
+ return candidates;
611
+ }
612
+ const selected = await deleteMultiselect({
613
+ message: "\u26A0 WARNING: The selected files will be PERMANENTLY DELETED from disk.\n Deselect any files you want to keep. Press Enter to confirm deletion:",
614
+ options: candidates.map((p) => ({
615
+ value: p,
616
+ label: p
617
+ })),
618
+ initialValues: candidates,
619
+ required: false
620
+ });
621
+ if (isCancel(selected)) {
622
+ process.exit(1);
623
+ }
624
+ return selected;
625
+ }
626
+ };
627
+ var deleteResolver = new DeleteResolver();
628
+
629
+ // src/core/template.ts
630
+ import { Eta } from "eta";
631
+ var EMPTY_FILE_MARKER = "<!-- AWA:EMPTY_FILE -->";
632
+ var TemplateEngine = class {
633
+ eta = null;
634
+ templateDir = null;
635
+ compiledCache = /* @__PURE__ */ new Map();
636
+ // @awa-impl: TPL-8_AC-1, TPL-8_AC-2, TPL-8_AC-3, TPL-8_AC-4
637
+ configure(templateDir) {
638
+ this.templateDir = templateDir;
639
+ this.compiledCache.clear();
640
+ this.eta = new Eta({
641
+ views: templateDir,
642
+ cache: true,
643
+ // Enable compilation caching
644
+ autoEscape: false,
645
+ // Don't escape HTML by default
646
+ defaultExtension: ""
647
+ // No automatic extension - use exact path as specified (AC-8.2)
648
+ });
649
+ }
650
+ // @awa-impl: TPL-5_AC-1, TPL-5_AC-2, TPL-5_AC-3
651
+ // @awa-impl: TPL-6_AC-1, TPL-6_AC-2
652
+ // @awa-impl: TPL-7_AC-1, TPL-7_AC-2
653
+ // @awa-impl: TPL-11_AC-1, TPL-11_AC-2
654
+ async render(templatePath, context) {
655
+ if (!this.eta || !this.templateDir) {
656
+ throw new TemplateError(
657
+ "Template engine not configured. Call configure() first.",
658
+ "RENDER_ERROR"
659
+ );
660
+ }
661
+ try {
662
+ const templateContent = await readTextFile(templatePath);
663
+ const rendered = await this.eta.renderStringAsync(templateContent, {
664
+ features: context.features
665
+ });
666
+ const trimmed = rendered.trim();
667
+ const isEmpty = trimmed.length === 0;
668
+ const isEmptyFileMarker = trimmed === EMPTY_FILE_MARKER;
669
+ return {
670
+ content: rendered,
671
+ isEmpty,
672
+ isEmptyFileMarker
673
+ };
674
+ } catch (error) {
675
+ throw new TemplateError(
676
+ `Failed to render template ${templatePath}: ${error instanceof Error ? error.message : String(error)}`,
677
+ "RENDER_ERROR",
678
+ templatePath
679
+ );
680
+ }
681
+ }
682
+ };
683
+ var templateEngine = new TemplateEngine();
684
+
685
+ // src/core/generator.ts
686
+ var FileGenerator = class {
687
+ // @awa-impl: GEN-1_AC-1, GEN-1_AC-2, GEN-1_AC-3
688
+ // @awa-impl: GEN-2_AC-1, GEN-2_AC-2, GEN-2_AC-3
689
+ // @awa-impl: GEN-3_AC-1, GEN-3_AC-2, GEN-3_AC-3
690
+ async generate(options) {
691
+ const { templatePath, outputPath, features, force, dryRun } = options;
692
+ const enableDelete = options.delete;
693
+ templateEngine.configure(templatePath);
694
+ const actions = [];
695
+ let created = 0;
696
+ let overwritten = 0;
697
+ let deleted = 0;
698
+ let skippedEmpty = 0;
699
+ let skippedUser = 0;
700
+ let skippedEqual = 0;
701
+ const filesToProcess = [];
702
+ const conflicts = [];
703
+ try {
704
+ for await (const templateFile of this.walkTemplates(templatePath)) {
705
+ const outputFile = this.computeOutputPath(templateFile, templatePath, outputPath);
706
+ const result = await templateEngine.render(templateFile, { features });
707
+ if (result.isEmpty && !result.isEmptyFileMarker) {
708
+ actions.push({
709
+ type: "skip-empty",
710
+ sourcePath: templateFile,
711
+ outputPath: outputFile
712
+ });
713
+ skippedEmpty++;
714
+ continue;
715
+ }
716
+ const content = result.isEmptyFileMarker ? "" : result.content;
717
+ const fileExists = await pathExists(outputFile);
718
+ if (fileExists) {
719
+ const existingContent = await readTextFile(outputFile);
720
+ conflicts.push({
721
+ outputPath: outputFile,
722
+ sourcePath: templateFile,
723
+ newContent: content,
724
+ existingContent
725
+ });
726
+ }
727
+ filesToProcess.push({
728
+ templateFile,
729
+ outputFile,
730
+ content,
731
+ isNew: !fileExists
732
+ });
733
+ }
734
+ let resolution = {
735
+ overwrite: [],
736
+ skip: [],
737
+ equal: []
738
+ };
739
+ if (conflicts.length > 0) {
740
+ resolution = await conflictResolver.resolveBatch(conflicts, force, dryRun);
741
+ }
742
+ for (const file of filesToProcess) {
743
+ if (file.isNew) {
744
+ if (!dryRun) {
745
+ await writeTextFile(file.outputFile, file.content);
746
+ }
747
+ actions.push({
748
+ type: "create",
749
+ sourcePath: file.templateFile,
750
+ outputPath: file.outputFile
751
+ });
752
+ created++;
753
+ logger.fileAction({
754
+ type: "create",
755
+ sourcePath: file.templateFile,
756
+ outputPath: file.outputFile
757
+ });
758
+ } else if (resolution.overwrite.includes(file.outputFile)) {
759
+ if (!dryRun) {
760
+ await writeTextFile(file.outputFile, file.content);
761
+ }
762
+ actions.push({
763
+ type: "overwrite",
764
+ sourcePath: file.templateFile,
765
+ outputPath: file.outputFile
766
+ });
767
+ overwritten++;
768
+ logger.fileAction({
769
+ type: "overwrite",
770
+ sourcePath: file.templateFile,
771
+ outputPath: file.outputFile
772
+ });
773
+ } else if (resolution.equal.includes(file.outputFile)) {
774
+ actions.push({
775
+ type: "skip-equal",
776
+ sourcePath: file.templateFile,
777
+ outputPath: file.outputFile
778
+ });
779
+ skippedEqual++;
780
+ logger.fileAction({
781
+ type: "skip-equal",
782
+ sourcePath: file.templateFile,
783
+ outputPath: file.outputFile
784
+ });
785
+ } else if (resolution.skip.includes(file.outputFile)) {
786
+ actions.push({
787
+ type: "skip-user",
788
+ sourcePath: file.templateFile,
789
+ outputPath: file.outputFile
790
+ });
791
+ skippedUser++;
792
+ logger.fileAction({
793
+ type: "skip-user",
794
+ sourcePath: file.templateFile,
795
+ outputPath: file.outputFile
796
+ });
797
+ }
798
+ }
799
+ const deleteEntries = await loadDeleteList(templatePath);
800
+ if (deleteEntries.length > 0) {
801
+ const deleteList = resolveDeleteList(deleteEntries, features);
802
+ const generatedOutputPaths = new Set(filesToProcess.map((f) => f.outputFile));
803
+ const deleteCandidates = [];
804
+ for (const relPath of deleteList) {
805
+ const absPath = join3(outputPath, relPath);
806
+ if (generatedOutputPaths.has(absPath)) {
807
+ logger.warn(
808
+ `Delete list entry '${relPath}' conflicts with generated file \u2014 skipping deletion`
809
+ );
810
+ continue;
811
+ }
812
+ if (await pathExists(absPath)) {
813
+ deleteCandidates.push(absPath);
814
+ }
815
+ }
816
+ if (deleteCandidates.length > 0) {
817
+ if (!enableDelete) {
818
+ for (const absPath of deleteCandidates) {
819
+ logger.warn(
820
+ `Would delete (pass --delete to enable): ${relative(outputPath, absPath)}`
821
+ );
822
+ }
823
+ } else {
824
+ const confirmed = await deleteResolver.resolveDeletes(deleteCandidates, force, dryRun);
825
+ for (const absPath of confirmed) {
826
+ if (!dryRun) {
827
+ await deleteFile(absPath);
828
+ }
829
+ actions.push({ type: "delete", outputPath: absPath });
830
+ deleted++;
831
+ logger.fileAction({ type: "delete", outputPath: absPath });
832
+ }
833
+ }
834
+ }
835
+ }
836
+ return {
837
+ actions,
838
+ created,
839
+ overwritten,
840
+ deleted,
841
+ skipped: skippedEmpty + skippedUser + skippedEqual,
842
+ skippedEmpty,
843
+ skippedUser,
844
+ skippedEqual
845
+ };
846
+ } catch (error) {
847
+ if (error instanceof Error && "code" in error) {
848
+ const code = error.code;
849
+ if (code === "EACCES" || code === "EPERM") {
850
+ throw new GenerationError(`Permission denied: ${error.message}`, "PERMISSION_DENIED");
851
+ }
852
+ if (code === "ENOSPC") {
853
+ throw new GenerationError(`Disk full: ${error.message}`, "DISK_FULL");
854
+ }
855
+ }
856
+ throw error;
857
+ }
858
+ }
859
+ // @awa-impl: GEN-8_AC-1, GEN-8_AC-2, GEN-8_AC-3
860
+ // @awa-impl: TPL-9_AC-1, TPL-9_AC-2
861
+ async *walkTemplates(dir) {
862
+ yield* walkDirectory(dir);
863
+ }
864
+ // @awa-impl: GEN-1_AC-1, GEN-1_AC-2, GEN-1_AC-3
865
+ computeOutputPath(templatePath, templateRoot, outputRoot) {
866
+ const relativePath = relative(templateRoot, templatePath);
867
+ return join3(outputRoot, relativePath);
868
+ }
869
+ };
870
+ var fileGenerator = new FileGenerator();
871
+
872
+ // src/core/differ.ts
873
+ var DiffEngine = class {
874
+ // @awa-impl: DIFF-1_AC-1, DIFF-1_AC-2, DIFF-1_AC-3
875
+ // @awa-impl: DIFF-2_AC-1, DIFF-2_AC-2, DIFF-2_AC-3, DIFF-2_AC-4, DIFF-2_AC-5
876
+ // @awa-impl: DIFF-3_AC-1, DIFF-3_AC-2, DIFF-3_AC-3
877
+ // @awa-impl: DIFF-4_AC-1, DIFF-4_AC-2
878
+ // @awa-impl: DIFF-5_AC-1, DIFF-5_AC-2, DIFF-5_AC-3
879
+ // @awa-impl: DIFF-6_AC-1, DIFF-6_AC-2, DIFF-6_AC-3
880
+ async diff(options) {
881
+ const { templatePath, targetPath, features, listUnknown } = options;
882
+ const tempPath = await this.createTempDir();
883
+ try {
884
+ const generateOptions = {
885
+ templatePath,
886
+ outputPath: tempPath,
887
+ features,
888
+ force: true,
889
+ dryRun: false,
890
+ delete: false
891
+ };
892
+ await fileGenerator.generate(generateOptions);
893
+ const generatedFiles = /* @__PURE__ */ new Set();
894
+ const targetFiles = /* @__PURE__ */ new Set();
895
+ if (await pathExists(tempPath)) {
896
+ for await (const file of walkDirectory(tempPath)) {
897
+ const relPath = relative2(tempPath, file);
898
+ generatedFiles.add(relPath);
899
+ }
900
+ }
901
+ if (await pathExists(targetPath)) {
902
+ for await (const file of walkDirectory(targetPath)) {
903
+ const relPath = relative2(targetPath, file);
904
+ targetFiles.add(relPath);
905
+ }
906
+ }
907
+ const files = [];
908
+ for (const relPath of generatedFiles) {
909
+ const generatedFilePath = join4(tempPath, relPath);
910
+ const targetFilePath = join4(targetPath, relPath);
911
+ if (targetFiles.has(relPath)) {
912
+ const fileDiff = await this.compareFiles(generatedFilePath, targetFilePath, relPath);
913
+ files.push(fileDiff);
914
+ } else {
915
+ files.push({
916
+ relativePath: relPath,
917
+ status: "new"
918
+ });
919
+ }
920
+ }
921
+ if (listUnknown) {
922
+ for (const relPath of targetFiles) {
923
+ if (generatedFiles.has(relPath)) {
924
+ continue;
925
+ }
926
+ files.push({
927
+ relativePath: relPath,
928
+ status: "extra"
929
+ });
930
+ }
931
+ }
932
+ const deleteEntries = await loadDeleteList(templatePath);
933
+ const deleteList = resolveDeleteList(deleteEntries, features ?? []);
934
+ for (const relPath of deleteList) {
935
+ if (targetFiles.has(relPath) && !generatedFiles.has(relPath)) {
936
+ const existingIdx = files.findIndex(
937
+ (f) => f.relativePath === relPath && f.status === "extra"
938
+ );
939
+ if (existingIdx !== -1) {
940
+ files.splice(existingIdx, 1);
941
+ }
942
+ files.push({
943
+ relativePath: relPath,
944
+ status: "delete-listed"
945
+ });
946
+ }
947
+ }
948
+ const identical = files.filter((f) => f.status === "identical").length;
949
+ const modified = files.filter((f) => f.status === "modified").length;
950
+ const newFiles = files.filter((f) => f.status === "new").length;
951
+ const extraFiles = files.filter((f) => f.status === "extra").length;
952
+ const binaryDiffers = files.filter((f) => f.status === "binary-differs").length;
953
+ const deleteListed = files.filter((f) => f.status === "delete-listed").length;
954
+ const hasDifferences = modified > 0 || newFiles > 0 || extraFiles > 0 || binaryDiffers > 0 || deleteListed > 0;
955
+ return {
956
+ files,
957
+ identical,
958
+ modified,
959
+ newFiles,
960
+ extraFiles,
961
+ binaryDiffers,
962
+ deleteListed,
963
+ hasDifferences
964
+ };
965
+ } finally {
966
+ await this.cleanupTempDir(tempPath);
967
+ }
968
+ }
969
+ // @awa-impl: DIFF-1_AC-1, DIFF-1_AC-2
970
+ async createTempDir() {
971
+ const systemTemp = tmpdir();
972
+ const timestamp = Date.now();
973
+ const random = Math.random().toString(36).substring(2, 8);
974
+ const tempPath = join4(systemTemp, `awa-diff-${timestamp}-${random}`);
975
+ await ensureDir(tempPath);
976
+ return tempPath;
977
+ }
978
+ // @awa-impl: DIFF-6_AC-1, DIFF-6_AC-2, DIFF-6_AC-3
979
+ async cleanupTempDir(tempPath) {
980
+ try {
981
+ if (await pathExists(tempPath)) {
982
+ await rmDir(tempPath);
983
+ }
984
+ } catch (_error) {
985
+ }
986
+ }
987
+ // @awa-impl: DIFF-2_AC-1, DIFF-2_AC-2, DIFF-2_AC-3, DIFF-2_AC-4, DIFF-2_AC-5
988
+ async compareFiles(generatedPath, targetPath, relativePath) {
989
+ const generatedBytes = await readBinaryFile(generatedPath);
990
+ const targetBytes = await readBinaryFile(targetPath);
991
+ if (generatedBytes.equals(targetBytes)) {
992
+ return {
993
+ relativePath,
994
+ status: "identical"
995
+ };
996
+ }
997
+ const isBinaryGenerated = await this.isBinaryFile(generatedPath);
998
+ const isBinaryTarget = await this.isBinaryFile(targetPath);
999
+ if (isBinaryGenerated || isBinaryTarget) {
1000
+ return {
1001
+ relativePath,
1002
+ status: "binary-differs"
1003
+ };
1004
+ }
1005
+ const generatedContent = generatedBytes.toString("utf-8");
1006
+ const targetContent = targetBytes.toString("utf-8");
1007
+ const patch = structuredPatch(
1008
+ `a/${relativePath}`,
1009
+ `b/${relativePath}`,
1010
+ targetContent,
1011
+ generatedContent,
1012
+ "target",
1013
+ "generated",
1014
+ {
1015
+ context: 3
1016
+ }
1017
+ );
1018
+ const headerLines = [
1019
+ `diff --git a/${relativePath} b/${relativePath}`,
1020
+ `--- a/${relativePath}`,
1021
+ `+++ b/${relativePath}`
1022
+ ];
1023
+ const hunkLines = patch.hunks.flatMap((hunk) => {
1024
+ const lines = [`@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`];
1025
+ lines.push(...hunk.lines);
1026
+ return lines;
1027
+ });
1028
+ const unifiedDiff = [...headerLines, ...hunkLines].join("\n");
1029
+ return {
1030
+ relativePath,
1031
+ status: "modified",
1032
+ unifiedDiff
1033
+ };
1034
+ }
1035
+ // @awa-impl: DIFF-2_AC-5
1036
+ async isBinaryFile(filePath) {
1037
+ try {
1038
+ return await detectBinaryFile(filePath);
1039
+ } catch {
1040
+ return false;
1041
+ }
1042
+ }
1043
+ };
1044
+ var diffEngine = new DiffEngine();
1045
+
1046
+ // src/core/feature-resolver.ts
1047
+ var FeatureResolver = class {
1048
+ validatePresets(presetNames, definitions) {
1049
+ for (const name of presetNames) {
1050
+ if (!definitions[name]) {
1051
+ throw new ConfigError(`Unknown preset: ${name}`, "UNKNOWN_PRESET");
1052
+ }
1053
+ }
1054
+ }
1055
+ resolve(input) {
1056
+ const { baseFeatures, presetNames, removeFeatures, presetDefinitions } = input;
1057
+ this.validatePresets(presetNames, presetDefinitions);
1058
+ const finalFeatures = [];
1059
+ const seen = /* @__PURE__ */ new Set();
1060
+ const add = (feature) => {
1061
+ if (seen.has(feature)) return;
1062
+ seen.add(feature);
1063
+ finalFeatures.push(feature);
1064
+ };
1065
+ for (const feature of baseFeatures) add(feature);
1066
+ for (const presetName of presetNames) {
1067
+ for (const feature of presetDefinitions[presetName] ?? []) add(feature);
1068
+ }
1069
+ if (removeFeatures.length === 0) return finalFeatures;
1070
+ const removeSet = new Set(removeFeatures);
1071
+ return finalFeatures.filter((f) => !removeSet.has(f));
1072
+ }
1073
+ };
1074
+ var featureResolver = new FeatureResolver();
1075
+
1076
+ // src/core/template-resolver.ts
1077
+ import { createHash } from "crypto";
1078
+ import { rm as rm2 } from "fs/promises";
1079
+ import { isAbsolute, join as join5, resolve } from "path";
1080
+ import degit from "degit";
1081
+ var TemplateResolver = class {
1082
+ // @awa-impl: CLI-3_AC-2, TPL-10_AC-1
1083
+ async resolve(source, refresh) {
1084
+ if (!source) {
1085
+ const bundledPath = join5(getTemplateDir(), "awa");
1086
+ return {
1087
+ type: "bundled",
1088
+ localPath: bundledPath,
1089
+ source: "bundled"
1090
+ };
1091
+ }
1092
+ const type = this.detectType(source);
1093
+ if (type === "local") {
1094
+ const localPath = isAbsolute(source) ? source : resolve(process.cwd(), source);
1095
+ if (!await pathExists(localPath)) {
1096
+ throw new TemplateError(
1097
+ `Template source not found: ${localPath}`,
1098
+ "SOURCE_NOT_FOUND",
1099
+ source
1100
+ );
1101
+ }
1102
+ return {
1103
+ type: "local",
1104
+ localPath,
1105
+ source
1106
+ };
1107
+ }
1108
+ if (type === "git") {
1109
+ const cachePath = this.getCachePath(source);
1110
+ const cacheExists = await pathExists(cachePath);
1111
+ if (cacheExists && !refresh) {
1112
+ logger.info(`Using cached template: ${source}`);
1113
+ return {
1114
+ type: "git",
1115
+ localPath: cachePath,
1116
+ source
1117
+ };
1118
+ }
1119
+ try {
1120
+ if (cacheExists && refresh) {
1121
+ logger.info(`Refreshing template: ${source}`);
1122
+ await rm2(cachePath, { recursive: true, force: true });
1123
+ } else {
1124
+ logger.info(`Fetching template: ${source}`);
1125
+ }
1126
+ await ensureDir(cachePath);
1127
+ const emitter = degit(source, { cache: false, force: true });
1128
+ await emitter.clone(cachePath);
1129
+ return {
1130
+ type: "git",
1131
+ localPath: cachePath,
1132
+ source
1133
+ };
1134
+ } catch (error) {
1135
+ throw new TemplateError(
1136
+ `Failed to fetch Git template: ${error instanceof Error ? error.message : String(error)}`,
1137
+ "FETCH_FAILED",
1138
+ source
1139
+ );
1140
+ }
1141
+ }
1142
+ throw new TemplateError(
1143
+ `Unable to resolve template source: ${source}`,
1144
+ "SOURCE_NOT_FOUND",
1145
+ source
1146
+ );
1147
+ }
1148
+ // @awa-impl: TPL-2_AC-1 through TPL-2_AC-6
1149
+ detectType(source) {
1150
+ if (source.startsWith(".") || source.startsWith("/") || source.startsWith("~")) {
1151
+ return "local";
1152
+ }
1153
+ if (/^[a-zA-Z]:/.test(source)) {
1154
+ return "local";
1155
+ }
1156
+ return "git";
1157
+ }
1158
+ // @awa-impl: TPL-3_AC-1
1159
+ getCachePath(source) {
1160
+ const hash = createHash("sha256").update(source).digest("hex").substring(0, 16);
1161
+ const cacheDir = getCacheDir();
1162
+ return join5(cacheDir, hash);
1163
+ }
1164
+ };
1165
+ var templateResolver = new TemplateResolver();
1166
+
1167
+ // src/commands/diff.ts
1168
+ async function diffCommand(cliOptions) {
1169
+ try {
1170
+ intro("awa CLI - Template Diff");
1171
+ const fileConfig = await configLoader.load(cliOptions.config ?? null);
1172
+ const options = configLoader.merge(cliOptions, fileConfig);
1173
+ if (!await pathExists(options.output)) {
1174
+ throw new DiffError(`Target directory does not exist: ${options.output}`);
1175
+ }
1176
+ const targetPath = options.output;
1177
+ const template = await templateResolver.resolve(options.template, options.refresh);
1178
+ const features = featureResolver.resolve({
1179
+ baseFeatures: [...options.features],
1180
+ presetNames: [...options.preset],
1181
+ removeFeatures: [...options.removeFeatures],
1182
+ presetDefinitions: options.presets
1183
+ });
1184
+ const result = await diffEngine.diff({
1185
+ templatePath: template.localPath,
1186
+ targetPath,
1187
+ features,
1188
+ listUnknown: options.listUnknown
1189
+ });
1190
+ for (const file of result.files) {
1191
+ switch (file.status) {
1192
+ case "modified":
1193
+ logger.info(`Modified: ${file.relativePath}`);
1194
+ if (file.unifiedDiff) {
1195
+ const lines = file.unifiedDiff.split("\n");
1196
+ for (const line of lines) {
1197
+ if (line.startsWith("diff --git") || line.startsWith("index ") || line.startsWith("--- ") || line.startsWith("+++ ")) {
1198
+ logger.diffLine(line, "context");
1199
+ } else if (line.startsWith("+")) {
1200
+ logger.diffLine(line, "add");
1201
+ } else if (line.startsWith("-")) {
1202
+ logger.diffLine(line, "remove");
1203
+ } else if (line.startsWith("@@")) {
1204
+ logger.diffLine(line, "context");
1205
+ } else {
1206
+ logger.diffLine(line, "context");
1207
+ }
1208
+ }
1209
+ }
1210
+ break;
1211
+ case "new":
1212
+ logger.info(`New file: ${file.relativePath}`);
1213
+ break;
1214
+ case "extra":
1215
+ logger.warn(`Extra file (not in template): ${file.relativePath}`);
1216
+ break;
1217
+ case "binary-differs":
1218
+ logger.warn(`binary files differ: ${file.relativePath}`);
1219
+ break;
1220
+ case "delete-listed":
1221
+ logger.warn(`Delete listed: ${file.relativePath}`);
1222
+ break;
1223
+ case "identical":
1224
+ break;
1225
+ }
1226
+ }
1227
+ logger.diffSummary(result);
1228
+ outro("Diff complete!");
1229
+ return result.hasDifferences ? 1 : 0;
1230
+ } catch (error) {
1231
+ if (error instanceof Error) {
1232
+ logger.error(error.message);
1233
+ } else {
1234
+ logger.error(String(error));
1235
+ }
1236
+ return 2;
1237
+ }
1238
+ }
1239
+
1240
+ // src/commands/generate.ts
1241
+ import { intro as intro2, isCancel as isCancel2, multiselect as multiselect2, outro as outro2 } from "@clack/prompts";
1242
+ var TOOL_FEATURES = [
1243
+ { value: "copilot", label: "GitHub Copilot" },
1244
+ { value: "claude", label: "Claude Code" },
1245
+ { value: "cursor", label: "Cursor" },
1246
+ { value: "windsurf", label: "Windsurf" },
1247
+ { value: "kilocode", label: "Kilocode" },
1248
+ { value: "opencode", label: "OpenCode" },
1249
+ { value: "gemini", label: "Gemini CLI" },
1250
+ { value: "roo", label: "Roo Code" },
1251
+ { value: "qwen", label: "Qwen Code" },
1252
+ { value: "codex", label: "Codex CLI" },
1253
+ { value: "agy", label: "Antigravity (agy)" },
1254
+ { value: "agents-md", label: "AGENTS.md (cross-tool)" }
1255
+ ];
1256
+ var TOOL_FEATURE_VALUES = new Set(TOOL_FEATURES.map((t) => t.value));
1257
+ async function generateCommand(cliOptions) {
1258
+ try {
1259
+ intro2("awa CLI - Template Generator");
1260
+ const fileConfig = await configLoader.load(cliOptions.config ?? null);
1261
+ const options = configLoader.merge(cliOptions, fileConfig);
1262
+ const template = await templateResolver.resolve(options.template, options.refresh);
1263
+ const features = featureResolver.resolve({
1264
+ baseFeatures: [...options.features],
1265
+ presetNames: [...options.preset],
1266
+ removeFeatures: [...options.removeFeatures],
1267
+ presetDefinitions: options.presets
1268
+ });
1269
+ const hasToolFlag = features.some((f) => TOOL_FEATURE_VALUES.has(f));
1270
+ if (!hasToolFlag) {
1271
+ const selected = await multiselect2({
1272
+ message: "Select AI tools to generate for (space to toggle, enter to confirm):",
1273
+ options: TOOL_FEATURES.map((t) => ({ value: t.value, label: t.label })),
1274
+ required: true
1275
+ });
1276
+ if (isCancel2(selected)) {
1277
+ logger.info("Generation cancelled.");
1278
+ process.exit(0);
1279
+ }
1280
+ features.push(...selected);
1281
+ }
1282
+ if (options.dryRun) {
1283
+ logger.info("Running in dry-run mode (no files will be modified)");
1284
+ }
1285
+ if (options.force) {
1286
+ logger.info("Force mode enabled (existing files will be overwritten)");
1287
+ }
1288
+ const result = await fileGenerator.generate({
1289
+ templatePath: template.localPath,
1290
+ outputPath: options.output,
1291
+ features,
1292
+ force: options.force,
1293
+ dryRun: options.dryRun,
1294
+ delete: options.delete
1295
+ });
1296
+ logger.summary(result);
1297
+ outro2("Generation complete!");
1298
+ } catch (error) {
1299
+ if (error instanceof Error) {
1300
+ logger.error(error.message);
1301
+ } else {
1302
+ logger.error(String(error));
1303
+ }
1304
+ process.exit(1);
1305
+ }
1306
+ }
1307
+
1308
+ // src/cli/index.ts
1309
+ var version = PACKAGE_INFO.version;
1310
+ var program = new Command();
1311
+ program.name("awa").description("awa - tool for generating AI coding agent configuration files").version(version, "-v, --version", "Display version number");
1312
+ program.command("generate").description("Generate AI agent configuration files from templates").argument("[output]", "Output directory (optional if specified in config)").option("-t, --template <source>", "Template source (local path or Git repository)").option("-f, --features <flag...>", "Feature flags (can be specified multiple times)").option("--preset <name...>", "Preset names to enable (can be specified multiple times)").option(
1313
+ "--remove-features <flag...>",
1314
+ "Feature flags to remove (can be specified multiple times)"
1315
+ ).option("--force", "Force overwrite existing files without prompting", false).option("--dry-run", "Preview changes without modifying files", false).option(
1316
+ "--delete",
1317
+ "Enable deletion of files listed in the delete list (default: warn only)",
1318
+ false
1319
+ ).option("-c, --config <path>", "Path to configuration file").option("--refresh", "Force refresh of cached Git templates", false).action(async (output, options) => {
1320
+ const cliOptions = {
1321
+ output,
1322
+ template: options.template,
1323
+ features: options.features || [],
1324
+ preset: options.preset || [],
1325
+ removeFeatures: options.removeFeatures || [],
1326
+ force: options.force,
1327
+ dryRun: options.dryRun,
1328
+ delete: options.delete,
1329
+ config: options.config,
1330
+ refresh: options.refresh
1331
+ };
1332
+ await generateCommand(cliOptions);
1333
+ });
1334
+ program.command("diff").description("Compare template output with existing target directory").argument("[target]", "Target directory to compare against (optional if specified in config)").option("-t, --template <source>", "Template source (local path or Git repository)").option("-f, --features <flag...>", "Feature flags (can be specified multiple times)").option("--preset <name...>", "Preset names to enable (can be specified multiple times)").option(
1335
+ "--remove-features <flag...>",
1336
+ "Feature flags to remove (can be specified multiple times)"
1337
+ ).option("-c, --config <path>", "Path to configuration file").option("--refresh", "Force refresh of cached Git templates", false).option("--list-unknown", "Include target-only files in diff results", false).action(async (target, options) => {
1338
+ const cliOptions = {
1339
+ output: target,
1340
+ // Use target as output for consistency
1341
+ template: options.template,
1342
+ features: options.features || [],
1343
+ preset: options.preset || [],
1344
+ removeFeatures: options.removeFeatures || [],
1345
+ config: options.config,
1346
+ refresh: options.refresh,
1347
+ listUnknown: options.listUnknown
1348
+ };
1349
+ const exitCode = await diffCommand(cliOptions);
1350
+ process.exit(exitCode);
1351
+ });
1352
+ program.parse();
1353
+ //# sourceMappingURL=index.js.map