@dtt_siye/atool 1.1.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 (463) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +235 -0
  3. package/VERSION +1 -0
  4. package/agents/code-reviewer.md +29 -0
  5. package/bin/atool.js +235 -0
  6. package/bin/postinstall.js +23 -0
  7. package/hooks/doc-sync-reminder +155 -0
  8. package/hooks/hooks-cursor.json +37 -0
  9. package/hooks/hooks.json +37 -0
  10. package/hooks/prompt-guard +135 -0
  11. package/hooks/session-start +286 -0
  12. package/install.sh +603 -0
  13. package/lib/analyze-source.sh +1265 -0
  14. package/lib/common.sh +1041 -0
  15. package/lib/compute-importance.sh +598 -0
  16. package/lib/detect-stack.sh +354 -0
  17. package/lib/generate-visualization.sh +266 -0
  18. package/lib/install-claude.sh +43 -0
  19. package/lib/install-cursor.sh +281 -0
  20. package/lib/install-hooks.sh +285 -0
  21. package/lib/install-kiro.sh +543 -0
  22. package/lib/install-mcp.sh +99 -0
  23. package/lib/install-skills.sh +129 -0
  24. package/lib/knowledge-graph.sh +1014 -0
  25. package/lib/multi-dimensional-analysis.sh +413 -0
  26. package/lib/pre-scan.sh +1045 -0
  27. package/lib/project-init.sh +552 -0
  28. package/lib/visualization-template.html +545 -0
  29. package/mcp/recommended.json +24 -0
  30. package/package.json +39 -0
  31. package/skills/_superpowers/.claude-plugin/marketplace.json +20 -0
  32. package/skills/_superpowers/.claude-plugin/plugin.json +20 -0
  33. package/skills/_superpowers/.codex/INSTALL.md +67 -0
  34. package/skills/_superpowers/.cursor-plugin/plugin.json +25 -0
  35. package/skills/_superpowers/.gitattributes +18 -0
  36. package/skills/_superpowers/.github/FUNDING.yml +3 -0
  37. package/skills/_superpowers/.github/ISSUE_TEMPLATE/bug_report.md +52 -0
  38. package/skills/_superpowers/.github/ISSUE_TEMPLATE/config.yml +5 -0
  39. package/skills/_superpowers/.github/ISSUE_TEMPLATE/feature_request.md +34 -0
  40. package/skills/_superpowers/.github/ISSUE_TEMPLATE/platform_support.md +23 -0
  41. package/skills/_superpowers/.github/PULL_REQUEST_TEMPLATE.md +87 -0
  42. package/skills/_superpowers/.opencode/INSTALL.md +83 -0
  43. package/skills/_superpowers/.opencode/plugins/superpowers.js +107 -0
  44. package/skills/_superpowers/CHANGELOG.md +13 -0
  45. package/skills/_superpowers/CODE_OF_CONDUCT.md +128 -0
  46. package/skills/_superpowers/GEMINI.md +2 -0
  47. package/skills/_superpowers/LICENSE +21 -0
  48. package/skills/_superpowers/README.md +187 -0
  49. package/skills/_superpowers/RELEASE-NOTES.md +1083 -0
  50. package/skills/_superpowers/agents/code-reviewer.md +48 -0
  51. package/skills/_superpowers/commands/brainstorm.md +5 -0
  52. package/skills/_superpowers/commands/execute-plan.md +5 -0
  53. package/skills/_superpowers/commands/write-plan.md +5 -0
  54. package/skills/_superpowers/docs/README.codex.md +126 -0
  55. package/skills/_superpowers/docs/README.opencode.md +130 -0
  56. package/skills/_superpowers/docs/plans/2025-11-22-opencode-support-design.md +294 -0
  57. package/skills/_superpowers/docs/plans/2025-11-22-opencode-support-implementation.md +1095 -0
  58. package/skills/_superpowers/docs/plans/2025-11-28-skills-improvements-from-user-feedback.md +711 -0
  59. package/skills/_superpowers/docs/plans/2026-01-17-visual-brainstorming.md +571 -0
  60. package/skills/_superpowers/docs/superpowers/plans/2026-01-22-document-review-system.md +301 -0
  61. package/skills/_superpowers/docs/superpowers/plans/2026-02-19-visual-brainstorming-refactor.md +523 -0
  62. package/skills/_superpowers/docs/superpowers/plans/2026-03-11-zero-dep-brainstorm-server.md +479 -0
  63. package/skills/_superpowers/docs/superpowers/plans/2026-03-23-codex-app-compatibility.md +564 -0
  64. package/skills/_superpowers/docs/superpowers/specs/2026-01-22-document-review-system-design.md +136 -0
  65. package/skills/_superpowers/docs/superpowers/specs/2026-02-19-visual-brainstorming-refactor-design.md +162 -0
  66. package/skills/_superpowers/docs/superpowers/specs/2026-03-11-zero-dep-brainstorm-server-design.md +118 -0
  67. package/skills/_superpowers/docs/superpowers/specs/2026-03-23-codex-app-compatibility-design.md +244 -0
  68. package/skills/_superpowers/docs/testing.md +303 -0
  69. package/skills/_superpowers/docs/windows/polyglot-hooks.md +212 -0
  70. package/skills/_superpowers/gemini-extension.json +6 -0
  71. package/skills/_superpowers/hooks/hooks-cursor.json +10 -0
  72. package/skills/_superpowers/hooks/hooks.json +16 -0
  73. package/skills/_superpowers/hooks/run-hook.cmd +46 -0
  74. package/skills/_superpowers/hooks/session-start +57 -0
  75. package/skills/_superpowers/package.json +6 -0
  76. package/skills/_superpowers/skills/brainstorming/SKILL.md +164 -0
  77. package/skills/_superpowers/skills/brainstorming/scripts/frame-template.html +214 -0
  78. package/skills/_superpowers/skills/brainstorming/scripts/helper.js +88 -0
  79. package/skills/_superpowers/skills/brainstorming/scripts/server.cjs +354 -0
  80. package/skills/_superpowers/skills/brainstorming/scripts/start-server.sh +148 -0
  81. package/skills/_superpowers/skills/brainstorming/scripts/stop-server.sh +56 -0
  82. package/skills/_superpowers/skills/brainstorming/spec-document-reviewer-prompt.md +49 -0
  83. package/skills/_superpowers/skills/brainstorming/visual-companion.md +287 -0
  84. package/skills/_superpowers/skills/dispatching-parallel-agents/SKILL.md +182 -0
  85. package/skills/_superpowers/skills/executing-plans/SKILL.md +70 -0
  86. package/skills/_superpowers/skills/finishing-a-development-branch/SKILL.md +200 -0
  87. package/skills/_superpowers/skills/receiving-code-review/SKILL.md +213 -0
  88. package/skills/_superpowers/skills/requesting-code-review/SKILL.md +105 -0
  89. package/skills/_superpowers/skills/requesting-code-review/code-reviewer.md +146 -0
  90. package/skills/_superpowers/skills/subagent-driven-development/SKILL.md +277 -0
  91. package/skills/_superpowers/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
  92. package/skills/_superpowers/skills/subagent-driven-development/implementer-prompt.md +113 -0
  93. package/skills/_superpowers/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
  94. package/skills/_superpowers/skills/systematic-debugging/CREATION-LOG.md +119 -0
  95. package/skills/_superpowers/skills/systematic-debugging/SKILL.md +296 -0
  96. package/skills/_superpowers/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
  97. package/skills/_superpowers/skills/systematic-debugging/condition-based-waiting.md +115 -0
  98. package/skills/_superpowers/skills/systematic-debugging/defense-in-depth.md +122 -0
  99. package/skills/_superpowers/skills/systematic-debugging/find-polluter.sh +63 -0
  100. package/skills/_superpowers/skills/systematic-debugging/root-cause-tracing.md +169 -0
  101. package/skills/_superpowers/skills/systematic-debugging/test-academic.md +14 -0
  102. package/skills/_superpowers/skills/systematic-debugging/test-pressure-1.md +58 -0
  103. package/skills/_superpowers/skills/systematic-debugging/test-pressure-2.md +68 -0
  104. package/skills/_superpowers/skills/systematic-debugging/test-pressure-3.md +69 -0
  105. package/skills/_superpowers/skills/test-driven-development/SKILL.md +371 -0
  106. package/skills/_superpowers/skills/test-driven-development/testing-anti-patterns.md +299 -0
  107. package/skills/_superpowers/skills/using-git-worktrees/SKILL.md +218 -0
  108. package/skills/_superpowers/skills/using-superpowers/SKILL.md +115 -0
  109. package/skills/_superpowers/skills/using-superpowers/references/codex-tools.md +100 -0
  110. package/skills/_superpowers/skills/using-superpowers/references/gemini-tools.md +33 -0
  111. package/skills/_superpowers/skills/verification-before-completion/SKILL.md +139 -0
  112. package/skills/_superpowers/skills/writing-plans/SKILL.md +152 -0
  113. package/skills/_superpowers/skills/writing-plans/plan-document-reviewer-prompt.md +49 -0
  114. package/skills/_superpowers/skills/writing-skills/SKILL.md +655 -0
  115. package/skills/_superpowers/skills/writing-skills/anthropic-best-practices.md +1150 -0
  116. package/skills/_superpowers/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
  117. package/skills/_superpowers/skills/writing-skills/graphviz-conventions.dot +172 -0
  118. package/skills/_superpowers/skills/writing-skills/persuasion-principles.md +187 -0
  119. package/skills/_superpowers/skills/writing-skills/render-graphs.js +168 -0
  120. package/skills/_superpowers/skills/writing-skills/testing-skills-with-subagents.md +384 -0
  121. package/skills/_superpowers/tests/brainstorm-server/package-lock.json +36 -0
  122. package/skills/_superpowers/tests/brainstorm-server/package.json +10 -0
  123. package/skills/_superpowers/tests/brainstorm-server/server.test.js +427 -0
  124. package/skills/_superpowers/tests/brainstorm-server/windows-lifecycle.test.sh +351 -0
  125. package/skills/_superpowers/tests/brainstorm-server/ws-protocol.test.js +392 -0
  126. package/skills/_superpowers/tests/claude-code/README.md +158 -0
  127. package/skills/_superpowers/tests/claude-code/analyze-token-usage.py +168 -0
  128. package/skills/_superpowers/tests/claude-code/run-skill-tests.sh +187 -0
  129. package/skills/_superpowers/tests/claude-code/test-document-review-system.sh +177 -0
  130. package/skills/_superpowers/tests/claude-code/test-helpers.sh +202 -0
  131. package/skills/_superpowers/tests/claude-code/test-subagent-driven-development-integration.sh +314 -0
  132. package/skills/_superpowers/tests/claude-code/test-subagent-driven-development.sh +165 -0
  133. package/skills/_superpowers/tests/explicit-skill-requests/prompts/action-oriented.txt +3 -0
  134. package/skills/_superpowers/tests/explicit-skill-requests/prompts/after-planning-flow.txt +17 -0
  135. package/skills/_superpowers/tests/explicit-skill-requests/prompts/claude-suggested-it.txt +11 -0
  136. package/skills/_superpowers/tests/explicit-skill-requests/prompts/i-know-what-sdd-means.txt +8 -0
  137. package/skills/_superpowers/tests/explicit-skill-requests/prompts/mid-conversation-execute-plan.txt +3 -0
  138. package/skills/_superpowers/tests/explicit-skill-requests/prompts/please-use-brainstorming.txt +1 -0
  139. package/skills/_superpowers/tests/explicit-skill-requests/prompts/skip-formalities.txt +3 -0
  140. package/skills/_superpowers/tests/explicit-skill-requests/prompts/subagent-driven-development-please.txt +1 -0
  141. package/skills/_superpowers/tests/explicit-skill-requests/prompts/use-systematic-debugging.txt +1 -0
  142. package/skills/_superpowers/tests/explicit-skill-requests/run-all.sh +70 -0
  143. package/skills/_superpowers/tests/explicit-skill-requests/run-claude-describes-sdd.sh +100 -0
  144. package/skills/_superpowers/tests/explicit-skill-requests/run-extended-multiturn-test.sh +113 -0
  145. package/skills/_superpowers/tests/explicit-skill-requests/run-haiku-test.sh +144 -0
  146. package/skills/_superpowers/tests/explicit-skill-requests/run-multiturn-test.sh +143 -0
  147. package/skills/_superpowers/tests/explicit-skill-requests/run-test.sh +136 -0
  148. package/skills/_superpowers/tests/opencode/run-tests.sh +163 -0
  149. package/skills/_superpowers/tests/opencode/setup.sh +73 -0
  150. package/skills/_superpowers/tests/opencode/test-plugin-loading.sh +72 -0
  151. package/skills/_superpowers/tests/opencode/test-priority.sh +198 -0
  152. package/skills/_superpowers/tests/opencode/test-tools.sh +104 -0
  153. package/skills/_superpowers/tests/skill-triggering/prompts/dispatching-parallel-agents.txt +8 -0
  154. package/skills/_superpowers/tests/skill-triggering/prompts/executing-plans.txt +1 -0
  155. package/skills/_superpowers/tests/skill-triggering/prompts/requesting-code-review.txt +3 -0
  156. package/skills/_superpowers/tests/skill-triggering/prompts/systematic-debugging.txt +11 -0
  157. package/skills/_superpowers/tests/skill-triggering/prompts/test-driven-development.txt +7 -0
  158. package/skills/_superpowers/tests/skill-triggering/prompts/writing-plans.txt +10 -0
  159. package/skills/_superpowers/tests/skill-triggering/run-all.sh +60 -0
  160. package/skills/_superpowers/tests/skill-triggering/run-test.sh +88 -0
  161. package/skills/_superpowers/tests/subagent-driven-dev/go-fractals/design.md +81 -0
  162. package/skills/_superpowers/tests/subagent-driven-dev/go-fractals/plan.md +172 -0
  163. package/skills/_superpowers/tests/subagent-driven-dev/go-fractals/scaffold.sh +45 -0
  164. package/skills/_superpowers/tests/subagent-driven-dev/run-test.sh +106 -0
  165. package/skills/_superpowers/tests/subagent-driven-dev/svelte-todo/design.md +70 -0
  166. package/skills/_superpowers/tests/subagent-driven-dev/svelte-todo/plan.md +222 -0
  167. package/skills/_superpowers/tests/subagent-driven-dev/svelte-todo/scaffold.sh +46 -0
  168. package/skills/ai-project-architecture/SKILL.md +632 -0
  169. package/skills/ai-project-architecture/reference/structure-rules.md +406 -0
  170. package/skills/ai-project-architecture/templates/compliance-report.md +300 -0
  171. package/skills/ai-project-architecture/templates/migration-plan.md +433 -0
  172. package/skills/ai-project-architecture/templates/verification-checklist.md +408 -0
  173. package/skills/android-conventions/SKILL.md +125 -0
  174. package/skills/atool-init/SKILL.md +141 -0
  175. package/skills/clarify-before-build/SKILL.md +107 -0
  176. package/skills/code-review/SKILL.md +406 -0
  177. package/skills/code-review/rules/architecture.md +285 -0
  178. package/skills/code-review/rules/coupling-cohesion.md +309 -0
  179. package/skills/code-review/rules/dead-code.md +115 -0
  180. package/skills/code-review/rules/deprecation-debt.md +279 -0
  181. package/skills/code-review/rules/duplication.md +104 -0
  182. package/skills/code-review/rules/error-security.md +143 -0
  183. package/skills/code-review/rules/maintainability.md +203 -0
  184. package/skills/code-review/rules/quality.md +158 -0
  185. package/skills/devops-conventions/SKILL.md +205 -0
  186. package/skills/doc-coauthoring/SKILL.md +392 -0
  187. package/skills/doc-standards-enforcer/SKILL.md +290 -0
  188. package/skills/doc-standards-enforcer/examples/valid-document-example.md +67 -0
  189. package/skills/doc-standards-enforcer/references/101-standards-summary.md +318 -0
  190. package/skills/doc-standards-enforcer/scripts/check_references.py +175 -0
  191. package/skills/doc-standards-enforcer/scripts/fix_common_issues.py +303 -0
  192. package/skills/doc-standards-enforcer/scripts/validate_doc_standards.py +332 -0
  193. package/skills/docx/LICENSE.txt +30 -0
  194. package/skills/docx/SKILL.md +200 -0
  195. package/skills/docx/docx-js.md +350 -0
  196. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  197. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  198. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  199. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  200. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  201. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  202. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  203. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  204. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  205. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  206. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  207. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  208. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  209. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  210. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  211. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  212. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  213. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  214. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  215. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  216. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  217. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  218. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  219. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  220. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  221. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  222. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  223. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  224. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  225. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  226. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  227. package/skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
  228. package/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  229. package/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  230. package/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  231. package/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  232. package/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  233. package/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  234. package/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  235. package/skills/docx/ooxml/scripts/pack.py +159 -0
  236. package/skills/docx/ooxml/scripts/unpack.py +29 -0
  237. package/skills/docx/ooxml/scripts/validate.py +69 -0
  238. package/skills/docx/ooxml/scripts/validation/__init__.py +15 -0
  239. package/skills/docx/ooxml/scripts/validation/base.py +951 -0
  240. package/skills/docx/ooxml/scripts/validation/docx.py +274 -0
  241. package/skills/docx/ooxml/scripts/validation/pptx.py +315 -0
  242. package/skills/docx/ooxml/scripts/validation/redlining.py +279 -0
  243. package/skills/docx/ooxml.md +610 -0
  244. package/skills/docx/scripts/__init__.py +1 -0
  245. package/skills/docx/scripts/document.py +1276 -0
  246. package/skills/docx/scripts/templates/comments.xml +3 -0
  247. package/skills/docx/scripts/templates/commentsExtended.xml +3 -0
  248. package/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  249. package/skills/docx/scripts/templates/commentsIds.xml +3 -0
  250. package/skills/docx/scripts/templates/people.xml +3 -0
  251. package/skills/docx/scripts/utilities.py +374 -0
  252. package/skills/flutter-conventions/SKILL.md +70 -0
  253. package/skills/go-conventions/SKILL.md +230 -0
  254. package/skills/harmony-conventions/SKILL.md +156 -0
  255. package/skills/java-conventions/SKILL.md +277 -0
  256. package/skills/pdf/LICENSE.txt +30 -0
  257. package/skills/pdf/SKILL.md +297 -0
  258. package/skills/pdf/forms.md +205 -0
  259. package/skills/pdf/reference.md +612 -0
  260. package/skills/pdf/scripts/check_bounding_boxes.py +70 -0
  261. package/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
  262. package/skills/pdf/scripts/check_fillable_fields.py +12 -0
  263. package/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
  264. package/skills/pdf/scripts/create_validation_image.py +41 -0
  265. package/skills/pdf/scripts/extract_form_field_info.py +152 -0
  266. package/skills/pdf/scripts/fill_fillable_fields.py +114 -0
  267. package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  268. package/skills/pptx/LICENSE.txt +30 -0
  269. package/skills/pptx/SKILL.md +487 -0
  270. package/skills/pptx/html2pptx.md +625 -0
  271. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  272. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  273. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  274. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  275. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  276. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  277. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  278. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  279. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  280. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  281. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  282. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  283. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  284. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  285. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  286. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  287. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  288. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  289. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  290. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  291. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  292. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  293. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  294. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  295. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  296. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  297. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  298. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  299. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  300. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  301. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  302. package/skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
  303. package/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  304. package/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  305. package/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  306. package/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  307. package/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  308. package/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  309. package/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  310. package/skills/pptx/ooxml/scripts/pack.py +159 -0
  311. package/skills/pptx/ooxml/scripts/unpack.py +29 -0
  312. package/skills/pptx/ooxml/scripts/validate.py +69 -0
  313. package/skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
  314. package/skills/pptx/ooxml/scripts/validation/base.py +951 -0
  315. package/skills/pptx/ooxml/scripts/validation/docx.py +274 -0
  316. package/skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
  317. package/skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
  318. package/skills/pptx/ooxml.md +427 -0
  319. package/skills/pptx/scripts/html2pptx.js +979 -0
  320. package/skills/pptx/scripts/inventory.py +1020 -0
  321. package/skills/pptx/scripts/rearrange.py +231 -0
  322. package/skills/pptx/scripts/replace.py +385 -0
  323. package/skills/pptx/scripts/thumbnail.py +450 -0
  324. package/skills/project-analyze/SKILL.md +270 -0
  325. package/skills/project-analyze/phases/phase0-discovery.md +278 -0
  326. package/skills/project-analyze/phases/phase0.5-prescan.md +139 -0
  327. package/skills/project-analyze/phases/phase1-inventory.md +94 -0
  328. package/skills/project-analyze/phases/phase2-deep-analysis.md +249 -0
  329. package/skills/project-analyze/phases/phase2a-l4-analysis.md +94 -0
  330. package/skills/project-analyze/phases/phase2b-l5-analysis.md +97 -0
  331. package/skills/project-analyze/phases/phase3-knowledge-graph.md +120 -0
  332. package/skills/project-analyze/phases/phase3a-multi-dimensional.md +61 -0
  333. package/skills/project-analyze/phases/phase4-code-quality.md +81 -0
  334. package/skills/project-analyze/phases/phase5-synthesis.md +284 -0
  335. package/skills/project-analyze/phases/phase6-validation.md +179 -0
  336. package/skills/project-analyze/prompts/code-review-agent.md +122 -0
  337. package/skills/project-analyze/prompts/deep-analysis-agent.md +107 -0
  338. package/skills/project-analyze/prompts/inventory-agent.md +67 -0
  339. package/skills/project-analyze/prompts/l4-analysis-agent.md +98 -0
  340. package/skills/project-analyze/rules/android.md +282 -0
  341. package/skills/project-analyze/rules/devops.md +443 -0
  342. package/skills/project-analyze/rules/generic.md +243 -0
  343. package/skills/project-analyze/rules/go.md +289 -0
  344. package/skills/project-analyze/rules/harmony.md +257 -0
  345. package/skills/project-analyze/rules/java.md +507 -0
  346. package/skills/project-analyze/rules/mobile-flutter.md +315 -0
  347. package/skills/project-analyze/rules/mobile-react-native.md +283 -0
  348. package/skills/project-analyze/rules/mobile-swift.md +323 -0
  349. package/skills/project-analyze/rules/python.md +317 -0
  350. package/skills/project-analyze/rules/rust-tauri.md +243 -0
  351. package/skills/project-analyze/rules/rust.md +296 -0
  352. package/skills/project-analyze/rules/web-nextjs.md +364 -0
  353. package/skills/project-analyze/rules/web-react.md +298 -0
  354. package/skills/project-analyze/rules/web-vue.md +378 -0
  355. package/skills/project-analyze/rules/web.md +390 -0
  356. package/skills/project-query/SKILL.md +224 -0
  357. package/skills/project-query/rules/query-templates.md +212 -0
  358. package/skills/python-conventions/SKILL.md +169 -0
  359. package/skills/react-native-conventions/SKILL.md +73 -0
  360. package/skills/requirements-writer/README.md +153 -0
  361. package/skills/requirements-writer/SKILL.md +341 -0
  362. package/skills/requirements-writer/examples/prd-outline-example.md +217 -0
  363. package/skills/requirements-writer/templates/module-prd-template.md +362 -0
  364. package/skills/requirements-writer/templates/prd-outline-template.md +185 -0
  365. package/skills/requirements-writer/templates/user-story-template.md +1125 -0
  366. package/skills/rust-conventions/SKILL.md +361 -0
  367. package/skills/smart-dispatch/SKILL.md +296 -0
  368. package/skills/smart-dispatch/implementer-prompt.md +146 -0
  369. package/skills/smart-dispatch/reviewer-prompt.md +199 -0
  370. package/skills/software-architecture/SKILL.md +278 -0
  371. package/skills/swift-conventions/SKILL.md +72 -0
  372. package/skills/ui-ux-pro/SKILL.md +140 -0
  373. package/skills/verification-before-completion/SKILL.md +119 -0
  374. package/skills/web-conventions/SKILL.md +259 -0
  375. package/skills/webapp-testing/LICENSE.txt +202 -0
  376. package/skills/webapp-testing/SKILL.md +97 -0
  377. package/skills/webapp-testing/examples/console_logging.py +35 -0
  378. package/skills/webapp-testing/examples/element_discovery.py +40 -0
  379. package/skills/webapp-testing/examples/static_html_automation.py +33 -0
  380. package/skills/webapp-testing/scripts/with_server.py +106 -0
  381. package/skills/writing-plans/SKILL.md +144 -0
  382. package/skills/xlsx/LICENSE.txt +30 -0
  383. package/skills/xlsx/SKILL.md +292 -0
  384. package/skills/xlsx/recalc.py +178 -0
  385. package/templates/CLAUDE.md.android +57 -0
  386. package/templates/CLAUDE.md.devops +50 -0
  387. package/templates/CLAUDE.md.generic +34 -0
  388. package/templates/CLAUDE.md.go +67 -0
  389. package/templates/CLAUDE.md.harmony +54 -0
  390. package/templates/CLAUDE.md.java +56 -0
  391. package/templates/CLAUDE.md.mobile-flutter +38 -0
  392. package/templates/CLAUDE.md.mobile-react-native +37 -0
  393. package/templates/CLAUDE.md.mobile-swift +40 -0
  394. package/templates/CLAUDE.md.python +65 -0
  395. package/templates/CLAUDE.md.rust +68 -0
  396. package/templates/CLAUDE.md.rust-tauri +120 -0
  397. package/templates/CLAUDE.md.web +63 -0
  398. package/templates/COMPONENT.md.android +58 -0
  399. package/templates/COMPONENT.md.devops +54 -0
  400. package/templates/COMPONENT.md.generic +35 -0
  401. package/templates/COMPONENT.md.go +59 -0
  402. package/templates/COMPONENT.md.harmony +63 -0
  403. package/templates/COMPONENT.md.java +69 -0
  404. package/templates/COMPONENT.md.mobile-flutter +56 -0
  405. package/templates/COMPONENT.md.mobile-react-native +55 -0
  406. package/templates/COMPONENT.md.mobile-swift +56 -0
  407. package/templates/COMPONENT.md.python +67 -0
  408. package/templates/COMPONENT.md.rust +57 -0
  409. package/templates/COMPONENT.md.rust-tauri +66 -0
  410. package/templates/COMPONENT.md.web +39 -0
  411. package/templates/README.md.android +71 -0
  412. package/templates/README.md.devops +68 -0
  413. package/templates/README.md.generic +39 -0
  414. package/templates/README.md.go +70 -0
  415. package/templates/README.md.harmony +72 -0
  416. package/templates/README.md.java +73 -0
  417. package/templates/README.md.mobile-flutter +69 -0
  418. package/templates/README.md.mobile-react-native +65 -0
  419. package/templates/README.md.mobile-swift +69 -0
  420. package/templates/README.md.monorepo +59 -0
  421. package/templates/README.md.python +66 -0
  422. package/templates/README.md.rust +69 -0
  423. package/templates/README.md.rust-tauri +149 -0
  424. package/templates/README.md.web +94 -0
  425. package/templates/UI_STYLE.md.android +74 -0
  426. package/templates/UI_STYLE.md.devops +50 -0
  427. package/templates/UI_STYLE.md.generic +31 -0
  428. package/templates/UI_STYLE.md.go +49 -0
  429. package/templates/UI_STYLE.md.harmony +71 -0
  430. package/templates/UI_STYLE.md.java +61 -0
  431. package/templates/UI_STYLE.md.mobile-flutter +70 -0
  432. package/templates/UI_STYLE.md.mobile-react-native +71 -0
  433. package/templates/UI_STYLE.md.mobile-swift +71 -0
  434. package/templates/UI_STYLE.md.python +58 -0
  435. package/templates/UI_STYLE.md.rust +52 -0
  436. package/templates/UI_STYLE.md.rust-tauri +102 -0
  437. package/templates/UI_STYLE.md.web +92 -0
  438. package/templates/cursor-rules.android.mdc +33 -0
  439. package/templates/cursor-rules.devops.mdc +32 -0
  440. package/templates/cursor-rules.generic.mdc +25 -0
  441. package/templates/cursor-rules.go.mdc +34 -0
  442. package/templates/cursor-rules.harmony.mdc +30 -0
  443. package/templates/cursor-rules.java.mdc +30 -0
  444. package/templates/cursor-rules.mobile-flutter.mdc +42 -0
  445. package/templates/cursor-rules.mobile-react-native.mdc +43 -0
  446. package/templates/cursor-rules.mobile-swift.mdc +42 -0
  447. package/templates/cursor-rules.python.mdc +33 -0
  448. package/templates/cursor-rules.rust-tauri.mdc +67 -0
  449. package/templates/cursor-rules.rust.mdc +30 -0
  450. package/templates/cursor-rules.web.mdc +30 -0
  451. package/templates/kiro-steering.android.md +39 -0
  452. package/templates/kiro-steering.devops.md +32 -0
  453. package/templates/kiro-steering.generic.md +28 -0
  454. package/templates/kiro-steering.go.md +41 -0
  455. package/templates/kiro-steering.harmony.md +36 -0
  456. package/templates/kiro-steering.java.md +37 -0
  457. package/templates/kiro-steering.mobile-flutter.md +73 -0
  458. package/templates/kiro-steering.mobile-react-native.md +71 -0
  459. package/templates/kiro-steering.mobile-swift.md +62 -0
  460. package/templates/kiro-steering.python.md +34 -0
  461. package/templates/kiro-steering.rust-tauri.md +50 -0
  462. package/templates/kiro-steering.rust.md +36 -0
  463. package/templates/kiro-steering.web.md +41 -0
package/lib/common.sh ADDED
@@ -0,0 +1,1041 @@
1
+ #!/usr/bin/env bash
2
+ # aTool - lib/common.sh
3
+ # Shared functions: logging, JSON merge, path utilities, Superpowers download/cache
4
+
5
+ set -euo pipefail
6
+
7
+ ATOOL_VERSION="${ATOOL_VERSION:-$(cat "$(dirname "${BASH_SOURCE[0]}")/../VERSION" 2>/dev/null || echo "0.1.0")}"
8
+ ATOOL_CACHE_DIR="${ATOOL_CACHE_DIR:-$HOME/.atool/cache}"
9
+ ATOOL_BACKUP_DIR="${ATOOL_BACKUP_DIR:-$HOME/.atool/backups}"
10
+ SUPERPOWERS_VERSION="${SUPERPOWERS_VERSION:-v5.0.6}"
11
+ SUPERPOWERS_REPO="${SUPERPOWERS_REPO:-https://github.com/obra/superpowers.git}"
12
+
13
+ # ── Colors ──────────────────────────────────────────────────────────────────
14
+ RED='\033[0;31m'
15
+ GREEN='\033[0;32m'
16
+ YELLOW='\033[1;33m'
17
+ BLUE='\033[0;34m'
18
+ CYAN='\033[0;36m'
19
+ BOLD='\033[1m'
20
+ DIM='\033[2m'
21
+ NC='\033[0m' # No Color
22
+
23
+ # ── Platform Detection ───────────────────────────────────────────────────────
24
+ ATOOL_PLATFORM="${ATOOL_PLATFORM:-$(uname -s 2>/dev/null || echo "Unknown")}"
25
+ is_windows() { [[ "$ATOOL_PLATFORM" == *"MINGW"* || "$ATOOL_PLATFORM" == *"MSYS"* || "$ATOOL_PLATFORM" == *"CYGWIN"* ]]; }
26
+ is_wsl() { [[ -f /proc/version ]] && grep -qi microsoft /proc/version 2>/dev/null; }
27
+
28
+ # Cross-platform file checksum (md5 -q on macOS, md5sum on Linux, certutil on Windows)
29
+ file_checksum() {
30
+ local file="$1"
31
+ if is_windows; then
32
+ certutil -hashfile "$file" MD5 2>/dev/null | grep -v ':' | tr -d ' \r\n' | tr 'A-F' 'a-f'
33
+ elif command -v md5 &>/dev/null && md5 -q "$file" &>/dev/null; then
34
+ md5 -q "$file"
35
+ else
36
+ md5sum "$file" 2>/dev/null | cut -d' ' -f1
37
+ fi
38
+ }
39
+
40
+ # Cross-platform stat mtime (macOS: stat -f %m, Linux: stat -c %Y, Windows: date)
41
+ file_mtime() {
42
+ local file="$1"
43
+ if [[ "$(uname -s)" == "Darwin" ]]; then
44
+ stat -f "%m" "$file" 2>/dev/null
45
+ elif is_windows; then
46
+ # Use date -r (available in Git Bash / MSYS2) instead of PowerShell
47
+ date -r "$file" +%s 2>/dev/null || stat -c "%Y" "$file" 2>/dev/null
48
+ else
49
+ stat -c "%Y" "$file" 2>/dev/null
50
+ fi
51
+ }
52
+
53
+ # Cross-platform rsync replacement (uses cp -r on Windows)
54
+ sync_dir() {
55
+ local src="$1" dest="$2"
56
+ if is_windows; then
57
+ # Match rsync semantics: trailing slash on src means "copy contents into dest"
58
+ if [[ "$src" == */ ]]; then
59
+ # src ends with / → copy contents of src into dest
60
+ mkdir -p "$dest"
61
+ rm -rf "${dest:?}/"*
62
+ cp -r "${src%/}"/* "${dest%/}/" 2>/dev/null || cp -r "${src%/}/"* "${dest%/}/" 2>/dev/null || true
63
+ else
64
+ # No trailing slash → copy src directory itself into dest's parent
65
+ rm -rf "$dest"
66
+ cp -r "$src" "$dest"
67
+ fi
68
+ else
69
+ rsync -a "$src" "$dest"
70
+ fi
71
+ }
72
+
73
+ # Cross-platform find with -quit equivalent
74
+ find_first() {
75
+ local dir="$1" name_pattern="$2"
76
+ if [[ "$(uname -s)" == "Darwin" ]] || is_windows; then
77
+ find "$dir" -name "$name_pattern" 2>/dev/null | head -1
78
+ else
79
+ find "$dir" -name "$name_pattern" -print -quit 2>/dev/null
80
+ fi
81
+ }
82
+
83
+ # ── Logging ─────────────────────────────────────────────────────────────────
84
+
85
+ log_info() { echo -e "${GREEN}[INFO]${NC} $*"; }
86
+ log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
87
+ log_error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
88
+ log_step() { echo -e "\n${BLUE}${BOLD}▶ $*${NC}"; }
89
+ log_success() { echo -e "${GREEN}${BOLD}✓ $*${NC}"; }
90
+
91
+ # ── Confirmation ────────────────────────────────────────────────────────────
92
+
93
+ confirm() {
94
+ local message="$1"
95
+ local default="${2:-Y}"
96
+ local prompt
97
+
98
+ if [[ "$default" =~ ^[Yy]$ ]]; then
99
+ prompt="$message [Y/n] "
100
+ else
101
+ prompt="$message [y/N] "
102
+ fi
103
+
104
+ if [[ "${ATOOL_YES:-}" == "1" ]]; then
105
+ return 0
106
+ fi
107
+
108
+ while true; do
109
+ printf '%s' "${CYAN}? ${NC}${prompt}"
110
+ read -r answer
111
+ answer="${answer:-$default}"
112
+ case "$answer" in
113
+ [Yy]|[Yy][Ee][Ss]) return 0 ;;
114
+ [Nn]|[Nn][Oo]) return 1 ;;
115
+ *) echo "Please answer yes or no." ;;
116
+ esac
117
+ done
118
+ }
119
+
120
+ # ── Dry Run ─────────────────────────────────────────────────────────────────
121
+
122
+ is_dry_run() { [[ "${ATOOL_DRY_RUN:-0}" == "1" ]]; }
123
+
124
+ run_cmd() {
125
+ if is_dry_run; then
126
+ log_info "[DRY-RUN] $*"
127
+ else
128
+ "$@"
129
+ fi
130
+ }
131
+
132
+ # ── Path Utilities ──────────────────────────────────────────────────────────
133
+
134
+ ensure_dir() {
135
+ local dir="$1"
136
+ # Always create directories - it's idempotent and safe
137
+ mkdir -p "$dir"
138
+ }
139
+
140
+ # ── IDE Config Directory Helpers (cross-platform) ─────────────────────────────
141
+
142
+ get_claude_config_dir() {
143
+ if is_windows && [[ -n "${APPDATA:-}" ]]; then
144
+ cygpath -u "$APPDATA/claude" 2>/dev/null || echo "$HOME/.claude"
145
+ else
146
+ echo "$HOME/.claude"
147
+ fi
148
+ }
149
+
150
+ get_cursor_config_dir() {
151
+ if is_windows && [[ -n "${APPDATA:-}" ]]; then
152
+ cygpath -u "$APPDATA/Cursor" 2>/dev/null || echo "$HOME/.cursor"
153
+ else
154
+ echo "$HOME/.cursor"
155
+ fi
156
+ }
157
+
158
+ get_kiro_config_dir() {
159
+ if is_windows && [[ -n "${APPDATA:-}" ]]; then
160
+ cygpath -u "$APPDATA/Kiro" 2>/dev/null || echo "$HOME/.kiro"
161
+ else
162
+ echo "$HOME/.kiro"
163
+ fi
164
+ }
165
+
166
+ backup_file() {
167
+ local file="$1"
168
+ if [[ ! -f "$file" ]]; then return 0; fi
169
+
170
+ local timestamp
171
+ timestamp=$(date +%Y%m%d_%H%M%S)
172
+ local backup_name="${file}.atool-backup.${timestamp}"
173
+ ensure_dir "$ATOOL_BACKUP_DIR"
174
+
175
+ if is_dry_run; then
176
+ log_info "[DRY-RUN] backup: $file -> $backup_name"
177
+ else
178
+ cp "$file" "$backup_name"
179
+ log_info "Backed up: $file -> $backup_name"
180
+ fi
181
+ }
182
+
183
+ # ── JSON Utilities ──────────────────────────────────────────────────────────
184
+
185
+ # Download a static jq binary from GitHub releases to ~/.atool/bin/
186
+ # Works on macOS, Linux, and Windows (Git Bash/MSYS2/Cygwin)
187
+ _download_jq() {
188
+ local atool_bin="$HOME/.atool/bin"
189
+ local jq_bin="$atool_bin/jq"
190
+ local jq_version="1.7.1"
191
+
192
+ # Already downloaded?
193
+ local jq_check="$jq_bin"
194
+ is_windows && jq_check="${jq_bin}.exe"
195
+ if [[ -x "$jq_check" ]] && "$jq_check" --version &>/dev/null; then
196
+ # Add to PATH if not already there
197
+ case ":${PATH}:" in
198
+ *":$atool_bin:"*) ;;
199
+ *) export PATH="$atool_bin:$PATH" ;;
200
+ esac
201
+ return 0
202
+ fi
203
+
204
+ log_info "jq not found — downloading static binary (v${jq_version})..."
205
+
206
+ # Determine platform and architecture
207
+ local platform arch suffix
208
+ suffix=""
209
+ if is_windows; then
210
+ platform="windows"
211
+ suffix=".exe"
212
+ # Detect architecture
213
+ local msystem="${MSYSTEM:-}"
214
+ if [[ "$msystem" == *"MINGW64"* || "$msystem" == *"UCRT64"* ]]; then
215
+ arch="amd64"
216
+ elif [[ "$msystem" == *"MINGW32"* ]]; then
217
+ arch="i386"
218
+ else
219
+ arch="amd64" # Default to 64-bit
220
+ fi
221
+ elif [[ "$(uname -s)" == "Darwin" ]]; then
222
+ platform="macos"
223
+ if [[ "$(uname -m)" == "arm64" ]]; then
224
+ arch="arm64"
225
+ else
226
+ arch="amd64"
227
+ fi
228
+ else
229
+ platform="linux"
230
+ if [[ "$(uname -m)" == *"aarch64"* || "$(uname -m)" == *"arm64"* ]]; then
231
+ arch="arm64"
232
+ else
233
+ arch="amd64"
234
+ fi
235
+ fi
236
+
237
+ local url="https://github.com/jqlang/jq/releases/download/jq-${jq_version}/jq-${platform}-${arch}${suffix}"
238
+
239
+ ensure_dir "$atool_bin"
240
+
241
+ local tmp_download
242
+ tmp_download=$(mktemp)
243
+
244
+ if command -v curl &>/dev/null; then
245
+ if ! curl -fsSL "$url" -o "$tmp_download" 2>/dev/null; then
246
+ rm -f "$tmp_download"
247
+ log_warn "Failed to download jq from $url"
248
+ return 1
249
+ fi
250
+ elif command -v wget &>/dev/null; then
251
+ if ! wget -q "$url" -O "$tmp_download" 2>/dev/null; then
252
+ rm -f "$tmp_download"
253
+ log_warn "Failed to download jq from $url"
254
+ return 1
255
+ fi
256
+ else
257
+ log_warn "Neither curl nor wget available — cannot auto-download jq"
258
+ return 1
259
+ fi
260
+
261
+ mv "$tmp_download" "$jq_bin${suffix}"
262
+ chmod +x "$jq_bin${suffix}"
263
+
264
+ # Verify the download
265
+ if "$jq_bin${suffix}" --version &>/dev/null; then
266
+ log_success "jq downloaded to $jq_bin${suffix}"
267
+ # Add to PATH for current session
268
+ case ":${PATH}:" in
269
+ *":$atool_bin:"*) ;;
270
+ *) export PATH="$atool_bin:$PATH" ;;
271
+ esac
272
+ # Persist PATH for future sessions
273
+ _persist_jq_path "$atool_bin"
274
+ return 0
275
+ else
276
+ rm -f "$jq_bin${suffix}"
277
+ log_warn "Downloaded jq binary is not executable"
278
+ return 1
279
+ fi
280
+ }
281
+
282
+ # Persist ~/.atool/bin to shell rc file for future sessions
283
+ # Args: ATOOL_BIN_DIR
284
+ _persist_jq_path() {
285
+ local atool_bin="$1"
286
+ local rc_file=""
287
+
288
+ if is_windows; then
289
+ # On Windows (Git Bash), always use ~/.bashrc
290
+ rc_file="$HOME/.bashrc"
291
+ elif [[ -f "$HOME/.bashrc" ]]; then
292
+ rc_file="$HOME/.bashrc"
293
+ elif [[ -f "$HOME/.bash_profile" ]]; then
294
+ rc_file="$HOME/.bash_profile"
295
+ elif [[ -f "$HOME/.zshrc" ]]; then
296
+ rc_file="$HOME/.zshrc"
297
+ fi
298
+
299
+ [[ -z "$rc_file" ]] && return 0
300
+
301
+ # Already persisted?
302
+ if grep -q "$atool_bin" "$rc_file" 2>/dev/null; then
303
+ return 0
304
+ fi
305
+
306
+ printf '\n# Added by aTool - jq binary path\nexport PATH="%s:\$PATH"\n' "$atool_bin" >> "$rc_file"
307
+ log_info "Added $atool_bin to $(basename "$rc_file") for persistent access"
308
+ }
309
+
310
+ check_jq() {
311
+ if command -v jq &>/dev/null; then
312
+ return 0
313
+ fi
314
+
315
+ # Try auto-download first
316
+ if _download_jq; then
317
+ return 0
318
+ fi
319
+
320
+ # Fallback: show manual install instructions
321
+ local install_hint="brew install jq"
322
+ if is_windows; then
323
+ install_hint="choco install jq | scoop install jq | Download from https://jqlang.github.io/jq/"
324
+ fi
325
+ log_error "jq is required but not installed and auto-download failed."
326
+ log_error "Install manually: $install_hint"
327
+ log_error "Or re-run this script after installing jq."
328
+ exit 1
329
+ }
330
+
331
+ # Deep merge two JSON files. source is merged INTO target. Returns merged JSON to stdout.
332
+ json_merge() {
333
+ local target_file="$1"
334
+ local source_file="$2"
335
+
336
+ check_jq
337
+
338
+ if [[ ! -f "$target_file" ]]; then
339
+ # Target doesn't exist, just return source
340
+ cat "$source_file"
341
+ return 0
342
+ fi
343
+
344
+ if [[ ! -f "$source_file" ]]; then
345
+ cat "$target_file"
346
+ return 0
347
+ fi
348
+
349
+ # Deep merge using jq --slurp
350
+ jq -s '.[0] * .[1]' "$target_file" "$source_file"
351
+ }
352
+
353
+ # Get a value from JSON file at a given path
354
+ json_get() {
355
+ local file="$1"
356
+ local path="$2"
357
+ check_jq
358
+ jq -r "$path // empty" "$file" 2>/dev/null
359
+ }
360
+
361
+ # Set a value in a JSON file at a given path
362
+ json_set() {
363
+ local file="$1"
364
+ local path="$2"
365
+ local value="$3"
366
+ check_jq
367
+ local tmp
368
+ tmp=$(mktemp)
369
+ jq "$path = $value" "$file" > "$tmp" && mv "$tmp" "$file"
370
+ }
371
+
372
+ # Check if a key exists in JSON
373
+ json_has_key() {
374
+ local file="$1"
375
+ local path="$2"
376
+ check_jq
377
+ jq -e "$path" "$file" &>/dev/null
378
+ }
379
+
380
+ # ── Superpowers Download/Cache ─────────────────────────────────────────────
381
+
382
+ get_superpowers_dir() {
383
+ echo "$ATOOL_CACHE_DIR/superpowers"
384
+ }
385
+
386
+ download_superpowers() {
387
+ local dest_dir="$1"
388
+ local cached_dir
389
+ cached_dir="$(get_superpowers_dir)"
390
+
391
+ # Check cache first
392
+ if [[ -d "$cached_dir" && -f "$cached_dir/.atool-superpowers-version" ]]; then
393
+ local cached_version
394
+ cached_version=$(cat "$cached_dir/.atool-superpowers-version")
395
+ if [[ "$cached_version" == "$SUPERPOWERS_VERSION" ]]; then
396
+ log_info "Using cached Superpowers ($SUPERPOWERS_VERSION)"
397
+ if [[ "$cached_dir" != "$dest_dir" ]]; then
398
+ ensure_dir "$dest_dir"
399
+ run_cmd sync_dir "$cached_dir/" "$dest_dir/"
400
+ fi
401
+ return 0
402
+ fi
403
+ fi
404
+
405
+ # Download from GitHub
406
+ log_info "Downloading Superpowers $SUPERPOWERS_VERSION..."
407
+ local tmpdir
408
+ tmpdir=$(mktemp -d)
409
+
410
+ if is_dry_run; then
411
+ log_info "[DRY-RUN] git clone --depth 1 --branch $SUPERPOWERS_VERSION $SUPERPOWERS_REPO $tmpdir/superpowers"
412
+ # Create a minimal structure for dry-run
413
+ ensure_dir "$dest_dir"
414
+ return 0
415
+ fi
416
+
417
+ if ! git clone --depth 1 --branch "$SUPERPOWERS_VERSION" \
418
+ "$SUPERPOWERS_REPO" "$tmpdir/superpowers" 2>/dev/null; then
419
+ log_warn "Failed to download Superpowers $SUPERPOWERS_VERSION"
420
+ log_warn "Skills installation will skip Superpowers"
421
+ rm -rf "$tmpdir"
422
+ return 1
423
+ fi
424
+
425
+ # Cache it
426
+ ensure_dir "$(dirname "$cached_dir")"
427
+ sync_dir "$tmpdir/superpowers/" "$cached_dir/"
428
+ echo "$SUPERPOWERS_VERSION" > "$cached_dir/.atool-superpowers-version"
429
+ log_success "Superpowers $SUPERPOWERS_VERSION downloaded and cached"
430
+
431
+ # Copy to destination if different
432
+ if [[ "$cached_dir" != "$dest_dir" ]]; then
433
+ ensure_dir "$dest_dir"
434
+ sync_dir "$cached_dir/" "$dest_dir/"
435
+ fi
436
+
437
+ rm -rf "$tmpdir"
438
+ }
439
+
440
+ # ── Skill Version Detection ─────────────────────────────────────────────────
441
+
442
+ # Get Superpowers version from package.json in a directory
443
+ # Args: SP_DIR (superpowers root directory)
444
+ # Outputs: version string or "unknown"
445
+ get_superpowers_version() {
446
+ local sp_dir="$1"
447
+ local pkg_json="$sp_dir/package.json"
448
+ if [[ -f "$pkg_json" ]]; then
449
+ jq -r '.version // "unknown"' "$pkg_json" 2>/dev/null
450
+ elif [[ -f "$sp_dir/.atool-superpowers-version" ]]; then
451
+ cat "$sp_dir/.atool-superpowers-version"
452
+ else
453
+ echo "unknown"
454
+ fi
455
+ }
456
+
457
+ # Get version of a single Superpowers skill via SKILL.md checksum
458
+ # Args: SKILL_DIR (individual skill directory)
459
+ # Outputs: checksum string or "none"
460
+ get_superpowers_skill_version() {
461
+ local skill_dir="$1"
462
+ local skill_md="$skill_dir/SKILL.md"
463
+ if [[ -f "$skill_md" ]]; then
464
+ file_checksum "$skill_md"
465
+ else
466
+ echo "none"
467
+ fi
468
+ }
469
+
470
+ # Get the installed version of a skill from its target directory
471
+ # Reads .atool-skill-version if present, falls back to checksum
472
+ # Args: SKILL_DIR (installed skill directory)
473
+ # Outputs: version string or "none"
474
+ get_installed_skill_version() {
475
+ local skill_dir="$1"
476
+ local marker="$skill_dir/.atool-skill-version"
477
+ if [[ -f "$marker" ]]; then
478
+ cat "$marker"
479
+ elif [[ -f "$skill_dir/SKILL.md" ]]; then
480
+ file_checksum "$skill_dir/SKILL.md"
481
+ else
482
+ echo "none"
483
+ fi
484
+ }
485
+
486
+ # Get the source version of an aTool skill
487
+ # Priority: VERSION file > frontmatter version: > SKILL.md checksum
488
+ # Args: SKILL_DIR (source skill directory in aTool)
489
+ # Outputs: version string or "none"
490
+ get_atool_skill_version() {
491
+ local skill_dir="$1"
492
+
493
+ # 1. Check VERSION file
494
+ if [[ -f "$skill_dir/VERSION" ]]; then
495
+ cat "$skill_dir/VERSION"
496
+ return 0
497
+ fi
498
+
499
+ # 2. Check frontmatter version:
500
+ local skill_md="$skill_dir/SKILL.md"
501
+ if [[ -f "$skill_md" ]]; then
502
+ local fm_version
503
+ fm_version=$(sed -n '/^---$/,/^---$/p' "$skill_md" | grep -oE '^version:[[:space:]]*[0-9]+\.[0-9]+\.[0-9]+' | head -1 | sed 's/^version:[[:space:]]*//')
504
+ if [[ -n "$fm_version" ]]; then
505
+ echo "$fm_version"
506
+ return 0
507
+ fi
508
+
509
+ # 3. Fallback to checksum
510
+ file_checksum "$skill_md"
511
+ return 0
512
+ fi
513
+
514
+ echo "none"
515
+ }
516
+
517
+ # Determine whether a skill should be installed
518
+ # Args: NAME, INSTALLED_VERSION, SOURCE_VERSION
519
+ # Returns: 0 (install), 1 (skip)
520
+ # Set ATOOL_FORCE=1 to always install
521
+ should_install_skill() {
522
+ local name="$1" installed="$2" source="$3"
523
+
524
+ # Force mode: always install
525
+ if [[ "${ATOOL_FORCE:-0}" == "1" ]]; then
526
+ return 0
527
+ fi
528
+
529
+ # Not installed: install
530
+ if [[ "$installed" == "none" ]]; then
531
+ return 0
532
+ fi
533
+
534
+ # Same version: skip
535
+ if [[ "$installed" == "$source" ]]; then
536
+ return 1
537
+ fi
538
+
539
+ # Different version: install (update)
540
+ return 0
541
+ }
542
+
543
+ # Write a version marker file into an installed skill directory
544
+ # Args: DIR, VERSION
545
+ write_skill_version_marker() {
546
+ local dir="$1" version="$2"
547
+ run_cmd bash -c "echo '$version' > '$dir/.atool-skill-version'"
548
+ }
549
+
550
+ # ── IDE Detection ───────────────────────────────────────────────────────────
551
+
552
+ detect_ides() {
553
+ local ides=()
554
+
555
+ # Claude Code CLI
556
+ if command -v claude &>/dev/null; then
557
+ ides+=("claude")
558
+ fi
559
+
560
+ # Cursor - check binary first, then config dir (cross-platform)
561
+ if command -v cursor &>/dev/null; then
562
+ ides+=("cursor")
563
+ else
564
+ local _cursor_dir
565
+ _cursor_dir=$(get_cursor_config_dir 2>/dev/null)
566
+ if [[ -d "$_cursor_dir" ]]; then
567
+ ides+=("cursor")
568
+ fi
569
+ fi
570
+
571
+ # Kiro - check binary first, then config dir (cross-platform)
572
+ if command -v kiro &>/dev/null; then
573
+ ides+=("kiro")
574
+ else
575
+ local _kiro_dir
576
+ _kiro_dir=$(get_kiro_config_dir 2>/dev/null)
577
+ if [[ -d "$_kiro_dir" ]]; then
578
+ ides+=("kiro")
579
+ fi
580
+ fi
581
+
582
+ echo "${ides[@]}"
583
+ }
584
+
585
+ # ── aTool marker ────────────────────────────────────────────────────────────
586
+
587
+ mark_atool_config() {
588
+ local file="$1"
589
+ local marker='# Added by aTool'
590
+ if ! grep -qF "$marker" "$file" 2>/dev/null; then
591
+ echo "$marker" >> "$file"
592
+ fi
593
+ }
594
+
595
+ # ── Template Substitution ────────────────────────────────────────────────────
596
+
597
+ # Replace {{KEY}} placeholders in a template file with provided values
598
+ # Args: TEMPLATE_FILE OUTPUT_FILE [KEY=VALUE...]
599
+ template_substitute() {
600
+ local template="$1" output="$2"; shift 2
601
+ local content
602
+ content=$(cat "$template")
603
+ for pair in "$@"; do
604
+ local key="${pair%%=*}" value="${pair##*=}"
605
+ content=$(echo "$content" | sed "s|{{${key}}}|${value}|g")
606
+ done
607
+ if ! is_dry_run; then
608
+ echo "$content" > "$output"
609
+ fi
610
+ }
611
+
612
+ # Replace {{#KEY}}...{{/KEY}} block placeholders with content from files
613
+ # Expects metadata pairs where value starts with __BLOCK__:/path/to/file
614
+ # Args: OUTPUT_FILE [KEY=__BLOCK__:/path...]
615
+ template_substitute_blocks() {
616
+ local output="$1"; shift
617
+ [[ ! -f "$output" ]] && return 0
618
+
619
+ for pair in "$@"; do
620
+ local key="${pair%%=*}" value="${pair##*=}"
621
+
622
+ # Only process __BLOCK__ values
623
+ if [[ "$value" != __BLOCK__:* ]]; then
624
+ continue
625
+ fi
626
+
627
+ local block_file="${value#__BLOCK__:}"
628
+ if [[ ! -f "$block_file" ]]; then
629
+ continue
630
+ fi
631
+
632
+ local tmp_result
633
+ tmp_result=$(mktemp)
634
+
635
+ # Use awk with -v repfile to pass the block file path
636
+ # awk reads the replacement file in BEGIN block
637
+ awk -v key="$key" -v repfile="$block_file" '
638
+ BEGIN {
639
+ in_block = 0
640
+ rep = ""
641
+ while ((getline line < repfile) > 0) {
642
+ rep = rep line "\n"
643
+ }
644
+ close(repfile)
645
+ }
646
+ !in_block && index($0, "{{#" key "}}") > 0 {
647
+ in_block = 1
648
+ before = substr($0, 1, index($0, "{{#" key "}}") - 1)
649
+ rest = substr($0, index($0, "{{#" key "}}") + length("{{#" key "}}"))
650
+ if (index(rest, "{{/" key "}}") > 0) {
651
+ after = substr(rest, index(rest, "{{/" key "}}") + length("{{/" key "}}"))
652
+ printf "%s%s%s\n", before, rep, after
653
+ in_block = 0
654
+ } else {
655
+ printf "%s%s", before, rep
656
+ }
657
+ next
658
+ }
659
+ in_block && index($0, "{{/" key "}}") > 0 {
660
+ after = substr($0, index($0, "{{/" key "}}") + length("{{/" key "}}"))
661
+ printf "%s\n", after
662
+ in_block = 0
663
+ next
664
+ }
665
+ !in_block { print }
666
+ ' "$output" > "$tmp_result"
667
+
668
+ if ! is_dry_run; then
669
+ cp "$tmp_result" "$output"
670
+ fi
671
+
672
+ rm -f "$tmp_result"
673
+ done
674
+ }
675
+
676
+ # Remove remaining unresolved block markers ({{#KEY}} and {{/KEY}}) from a file,
677
+ # keeping the content between them intact.
678
+ # This is called after template_substitute_blocks to clean up any block markers
679
+ # that had no replacement data provided (e.g., NEWCOMER_CHECKLIST, RELATED_DOCS).
680
+ # Args: OUTPUT_FILE
681
+ strip_block_markers() {
682
+ local output="$1"
683
+ [[ ! -f "$output" ]] && return 0
684
+
685
+ # Only process if there are block markers
686
+ grep -q '{{#' "$output" 2>/dev/null || return 0
687
+
688
+ local tmp_result
689
+ tmp_result=$(mktemp)
690
+
691
+ # Remove {{#KEY}} and {{/KEY}} lines, keeping everything else
692
+ awk '!/^{{#[A-Z_]+}}$/ && !/^{{\/[A-Z_]+}}$/' "$output" > "$tmp_result"
693
+
694
+ if ! is_dry_run; then
695
+ cp "$tmp_result" "$output"
696
+ fi
697
+
698
+ rm -f "$tmp_result"
699
+ }
700
+
701
+ # ── Project Metadata Extraction ─────────────────────────────────────────────
702
+
703
+ # Extract project metadata from signal files as KEY=VALUE pairs
704
+ # Args: PROJECT_DIR
705
+ # Outputs: key=value lines (PROJECT_NAME, PROJECT_VERSION, PROJECT_DESCRIPTION, STACK_TYPE, STACK_DESCRIPTION)
706
+ extract_project_metadata() {
707
+ local dir="$1"
708
+
709
+ # shellcheck source=lib/detect-stack.sh
710
+ source "${ATOOL_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/lib/detect-stack.sh"
711
+
712
+ local stack description
713
+ stack=$(detect_stack "$dir")
714
+ description=$(get_stack_description "$stack")
715
+
716
+ echo "STACK_TYPE=${stack}"
717
+ echo "STACK_DESCRIPTION=${description}"
718
+
719
+ # Tauri (src-tauri/tauri.conf.json takes priority over plain Cargo.toml)
720
+ if [[ -f "$dir/src-tauri/tauri.conf.json" ]]; then
721
+ echo "PROJECT_NAME=$(jq -r '.productName // empty' "$dir/src-tauri/tauri.conf.json" 2>/dev/null || echo "unknown")"
722
+ echo "PROJECT_VERSION=$(jq -r '.version // empty' "$dir/src-tauri/tauri.conf.json" 2>/dev/null || echo "unknown")"
723
+ echo "PROJECT_DESCRIPTION=Tauri Desktop App"
724
+ return 0
725
+ fi
726
+
727
+ # package.json (Node.js / Web / React Native)
728
+ if [[ -f "$dir/package.json" ]]; then
729
+ echo "PROJECT_NAME=$(jq -r '.name // empty' "$dir/package.json" 2>/dev/null || echo "unknown")"
730
+ echo "PROJECT_VERSION=$(jq -r '.version // empty' "$dir/package.json" 2>/dev/null || echo "unknown")"
731
+ echo "PROJECT_DESCRIPTION=$(jq -r '.description // empty' "$dir/package.json" 2>/dev/null || echo "")"
732
+ return 0
733
+ fi
734
+
735
+ # pom.xml (Java / Maven)
736
+ if [[ -f "$dir/pom.xml" ]]; then
737
+ echo "PROJECT_NAME=$(grep -m1 '<artifactId>' "$dir/pom.xml" 2>/dev/null | sed 's|.*<artifactId>||;s|</artifactId>.*||' || echo "unknown")"
738
+ echo "PROJECT_VERSION=$(grep -m1 '<version>' "$dir/pom.xml" 2>/dev/null | sed 's|.*<version>||;s|</version>.*||' || echo "unknown")"
739
+ echo "PROJECT_DESCRIPTION=$(grep -m1 '<description>' "$dir/pom.xml" 2>/dev/null | sed 's|.*<description>||;s|</description>.*||' || echo "")"
740
+ # Derive package path from groupId (com.example → com/example)
741
+ local _group_id
742
+ _group_id=$(grep -m1 '<groupId>' "$dir/pom.xml" 2>/dev/null | sed 's|.*<groupId>||;s|</groupId>.*||' || echo "")
743
+ [[ -n "$_group_id" ]] && echo "PACKAGE_PATH=${_group_id//.//}"
744
+ return 0
745
+ fi
746
+
747
+ # build.gradle / build.gradle.kts (Java / Android)
748
+ if [[ -f "$dir/build.gradle" || -f "$dir/build.gradle.kts" ]]; then
749
+ local gradle_file="$dir/build.gradle"
750
+ [[ -f "$dir/build.gradle.kts" ]] && gradle_file="$dir/build.gradle.kts"
751
+ echo "PROJECT_NAME=$(grep -m1 'applicationId\|archivesBaseName' "$gradle_file" 2>/dev/null | sed 's|.*"\(.*\)".*|\1|' || echo "unknown")"
752
+ echo "PROJECT_VERSION=$(grep -m1 'versionName\|version' "$gradle_file" 2>/dev/null | grep -oE '"[^"]*"' | head -1 | tr -d '"' || echo "unknown")"
753
+ echo "PROJECT_DESCRIPTION="
754
+ # Derive package path from group or applicationId
755
+ local _gradle_group
756
+ _gradle_group=$(grep -m1 'group\s*=' "$gradle_file" 2>/dev/null | sed 's|.*"\(.*\)".*|\1|' || echo "")
757
+ [[ -z "$_gradle_group" ]] && _gradle_group=$(grep -m1 'applicationId' "$gradle_file" 2>/dev/null | sed 's|.*"\(.*\)".*|\1|' || echo "")
758
+ [[ -n "$_gradle_group" ]] && echo "PACKAGE_PATH=${_gradle_group//.//}"
759
+ return 0
760
+ fi
761
+
762
+ # Cargo.toml (Rust)
763
+ if [[ -f "$dir/Cargo.toml" ]]; then
764
+ echo "PROJECT_NAME=$(grep -m1 '^name' "$dir/Cargo.toml" 2>/dev/null | sed 's|name = "||;s|"$||' || echo "unknown")"
765
+ echo "PROJECT_VERSION=$(grep -m1 '^version' "$dir/Cargo.toml" 2>/dev/null | sed 's|version = "||;s|"$||' || echo "unknown")"
766
+ echo "PROJECT_DESCRIPTION=$(grep -m1 '^description' "$dir/Cargo.toml" 2>/dev/null | sed 's|description = "||;s|"$||' || echo "")"
767
+ return 0
768
+ fi
769
+
770
+ # go.mod (Go)
771
+ if [[ -f "$dir/go.mod" ]]; then
772
+ echo "PROJECT_NAME=$(head -1 "$dir/go.mod" 2>/dev/null | awk '{print $2}' || echo "unknown")"
773
+ echo "PROJECT_VERSION="
774
+ echo "PROJECT_DESCRIPTION="
775
+ return 0
776
+ fi
777
+
778
+ # pyproject.toml (Python)
779
+ if [[ -f "$dir/pyproject.toml" ]]; then
780
+ echo "PROJECT_NAME=$(grep -m1 'name' "$dir/pyproject.toml" 2>/dev/null | head -1 | sed 's|.*name = "||;s|"$||;s|.*name = '"'"'||;s|'"'"'$||' || echo "unknown")"
781
+ echo "PROJECT_VERSION=$(grep -m1 'version' "$dir/pyproject.toml" 2>/dev/null | head -1 | sed 's|.*version = "||;s|"$||;s|.*version = '"'"'||;s|'"'"'$||' || echo "unknown")"
782
+ echo "PROJECT_DESCRIPTION=$(grep -m1 'description' "$dir/pyproject.toml" 2>/dev/null | head -1 | sed 's|.*description = "||;s|"$||' || echo "")"
783
+ return 0
784
+ fi
785
+
786
+ # requirements.txt (Python)
787
+ if [[ -f "$dir/requirements.txt" ]]; then
788
+ echo "PROJECT_NAME=$(basename "$(cd "$dir" && pwd)")"
789
+ echo "PROJECT_VERSION="
790
+ echo "PROJECT_DESCRIPTION="
791
+ return 0
792
+ fi
793
+
794
+ # pubspec.yaml (Flutter)
795
+ if [[ -f "$dir/pubspec.yaml" ]]; then
796
+ echo "PROJECT_NAME=$(grep -m1 '^name:' "$dir/pubspec.yaml" 2>/dev/null | awk '{print $2}' || echo "unknown")"
797
+ echo "PROJECT_VERSION=$(grep -m1 '^version:' "$dir/pubspec.yaml" 2>/dev/null | awk '{print $2}' || echo "unknown")"
798
+ echo "PROJECT_DESCRIPTION=$(grep -m1 '^description:' "$dir/pubspec.yaml" 2>/dev/null | sed 's|^description: *||' || echo "")"
799
+ return 0
800
+ fi
801
+
802
+ # oh-package.json5 (HarmonyOS)
803
+ if [[ -f "$dir/oh-package.json5" ]]; then
804
+ echo "PROJECT_NAME=$(jq -r '.name // empty' "$dir/oh-package.json5" 2>/dev/null || echo "unknown")"
805
+ echo "PROJECT_VERSION=$(jq -r '.version // empty' "$dir/oh-package.json5" 2>/dev/null || echo "unknown")"
806
+ echo "PROJECT_DESCRIPTION=$(jq -r '.description // empty' "$dir/oh-package.json5" 2>/dev/null || echo "")"
807
+ return 0
808
+ fi
809
+
810
+ # Package.swift (Swift/iOS)
811
+ if [[ -f "$dir/Package.swift" ]]; then
812
+ echo "PROJECT_NAME=$(grep -m1 'name:' "$dir/Package.swift" 2>/dev/null | sed 's|.*name: "||;s|".*||' || echo "unknown")"
813
+ echo "PROJECT_VERSION="
814
+ echo "PROJECT_DESCRIPTION="
815
+ return 0
816
+ fi
817
+
818
+ # Fallback: directory name
819
+ echo "PROJECT_NAME=$(basename "$(cd "$dir" && pwd)")"
820
+ echo "PROJECT_VERSION="
821
+ echo "PROJECT_DESCRIPTION="
822
+ }
823
+
824
+ # ── Skill Catalog Scanner ──────────────────────────────────────────────────
825
+
826
+ # Scan installed skills directory and output a structured catalog
827
+ # Reads only the first 10 lines of each SKILL.md for performance
828
+ # Args: SKILLS_DIR (e.g. ~/.claude/skills)
829
+ # Outputs: structured text grouped by category
830
+ scan_skills_catalog() {
831
+ local skills_dir="$1"
832
+ if [[ ! -d "$skills_dir" ]]; then
833
+ return 0
834
+ fi
835
+
836
+ local conventions="" superpowers_list="" office=""
837
+ local arch_design="" quality_review="" documentation="" planning=""
838
+
839
+ for skill_dir in "$skills_dir"/*/; do
840
+ [[ ! -d "$skill_dir" ]] && continue
841
+ local skill_name
842
+ skill_name=$(basename "$skill_dir")
843
+ [[ -L "$skill_dir" ]] && continue
844
+ [[ "$skill_name" == "_superpowers" ]] && continue
845
+
846
+ local skill_md="$skill_dir/SKILL.md"
847
+ [[ ! -f "$skill_md" ]] && continue
848
+
849
+ # Extract description from frontmatter (first 10 lines only)
850
+ local desc=""
851
+ desc=$(head -10 "$skill_md" | sed -n '/^---$/,/^---$/p' | grep '^description:' | head -1 | sed 's/^description:[[:space:]]*//')
852
+ if [[ -z "$desc" ]]; then
853
+ desc=$(head -10 "$skill_md" | grep -i '^#' | head -1 | sed 's/^#*\s*//' || echo "$skill_name")
854
+ fi
855
+
856
+ # Categorize
857
+ case "$skill_name" in
858
+ *-conventions)
859
+ conventions="${conventions}- ${skill_name}: ${desc}
860
+ "
861
+ ;;
862
+ pdf|docx|pptx|xlsx)
863
+ office="${office}- ${skill_name}: ${desc}
864
+ "
865
+ ;;
866
+ # Architecture & Design
867
+ software-architecture|ai-project-architecture|ui-ux-pro)
868
+ arch_design="${arch_design}- ${skill_name}: ${desc}
869
+ "
870
+ ;;
871
+ # Quality & Review
872
+ code-review|project-analyze|project-query|verification-before-completion)
873
+ quality_review="${quality_review}- ${skill_name}: ${desc}
874
+ "
875
+ ;;
876
+ # Documentation
877
+ doc-coauthoring|doc-standards-enforcer|requirements-writer)
878
+ documentation="${documentation}- ${skill_name}: ${desc}
879
+ "
880
+ ;;
881
+ # Planning & Dispatch
882
+ writing-plans|smart-dispatch|brainstorming|clarify-before-build)
883
+ planning="${planning}- ${skill_name}: ${desc}
884
+ "
885
+ ;;
886
+ *)
887
+ planning="${planning}- ${skill_name}: ${desc}
888
+ "
889
+ ;;
890
+ esac
891
+ done
892
+
893
+ # Check for Superpowers skills
894
+ local sp_dir="$skills_dir"
895
+ if [[ -d "$skills_dir/_superpowers/skills" ]]; then
896
+ sp_dir="$skills_dir/_superpowers/skills"
897
+ fi
898
+ for skill_dir in "$sp_dir"/*/; do
899
+ [[ ! -d "$skill_dir" ]] && continue
900
+ local skill_name
901
+ skill_name=$(basename "$skill_dir")
902
+ [[ -L "$skill_dir" ]] && continue
903
+ local sp_md="$skill_dir/SKILL.md"
904
+ [[ ! -f "$sp_md" ]] && continue
905
+ local desc=""
906
+ desc=$(head -10 "$sp_md" | sed -n '/^---$/,/^---$/p' | grep '^description:' | head -1 | sed 's/^description:[[:space:]]*//')
907
+ if [[ -z "$desc" ]]; then
908
+ desc=$(head -10 "$sp_md" | grep -i '^#' | head -1 | sed 's/^#*\s*//' || echo "$skill_name")
909
+ fi
910
+ superpowers_list="${superpowers_list}- ${skill_name}: ${desc}
911
+ "
912
+ done
913
+
914
+ # Output catalog
915
+ if [[ -n "$conventions" ]]; then
916
+ echo "## Conventions Skills (auto-apply when relevant)"
917
+ printf '%s' "$conventions"
918
+ echo ""
919
+ fi
920
+ if [[ -n "$arch_design" ]]; then
921
+ echo "## Architecture & Design"
922
+ printf '%s' "$arch_design"
923
+ echo ""
924
+ fi
925
+ if [[ -n "$quality_review" ]]; then
926
+ echo "## Quality & Review"
927
+ printf '%s' "$quality_review"
928
+ echo ""
929
+ fi
930
+ if [[ -n "$documentation" ]]; then
931
+ echo "## Documentation"
932
+ printf '%s' "$documentation"
933
+ echo ""
934
+ fi
935
+ if [[ -n "$planning" ]]; then
936
+ echo "## Planning & Other"
937
+ printf '%s' "$planning"
938
+ echo ""
939
+ fi
940
+ if [[ -n "$superpowers_list" ]]; then
941
+ echo "## Superpowers Skills"
942
+ printf '%s' "$superpowers_list"
943
+ echo ""
944
+ fi
945
+ if [[ -n "$office" ]]; then
946
+ echo "## Office Skills"
947
+ printf '%s' "$office"
948
+ echo ""
949
+ fi
950
+ }
951
+
952
+ # Map a detected stack to its primary conventions skill name
953
+ # Args: STACK_TYPE (e.g. "java-spring")
954
+ # Outputs: conventions skill name or empty string
955
+ stack_to_conventions_skill() {
956
+ local stack="$1"
957
+ case "$stack" in
958
+ java-spring|java) echo "java-conventions" ;;
959
+ android-kotlin) echo "android-conventions" ;;
960
+ harmony) echo "harmony-conventions" ;;
961
+ web-nextjs|web-react|web-vue|web-svelte) echo "web-conventions" ;;
962
+ mobile-react-native) echo "react-native-conventions" ;;
963
+ mobile-flutter) echo "flutter-conventions" ;;
964
+ mobile-swift) echo "swift-conventions" ;;
965
+ python) echo "python-conventions" ;;
966
+ rust|rust-tauri) echo "rust-conventions" ;;
967
+ go) echo "go-conventions" ;;
968
+ devops|devops-k8s) echo "devops-conventions" ;;
969
+ *) echo "" ;;
970
+ esac
971
+ }
972
+
973
+ # Count source files modified after reference doc file(s)
974
+ # Args: PROJECT_DIR, REF_FILE [REF_FILE2 ...] (relative paths, e.g. "README.md" "UI_STYLE.md")
975
+ # Outputs: count of source files newer than the OLDEST reference file
976
+ # If no reference file exists, outputs 0
977
+ count_stale_docs() {
978
+ local project_dir="$1"
979
+ shift
980
+
981
+ # Find the oldest mtime among all provided reference files
982
+ local oldest_mtime=""
983
+ local found_any=false
984
+ for ref_file in "$@"; do
985
+ local ref_path="$project_dir/$ref_file"
986
+ if [[ -f "$ref_path" ]]; then
987
+ local ref_mtime
988
+ ref_mtime=$(file_mtime "$ref_path")
989
+ if ! $found_any || [[ "$ref_mtime" -lt "$oldest_mtime" ]]; then
990
+ oldest_mtime="$ref_mtime"
991
+ fi
992
+ found_any=true
993
+ fi
994
+ done
995
+
996
+ if ! $found_any; then
997
+ echo "0"
998
+ return 0
999
+ fi
1000
+
1001
+ local count=0
1002
+
1003
+ # Check common source directories for files newer than the oldest reference
1004
+ while IFS= read -r src_file; do
1005
+ [[ -z "$src_file" ]] && continue
1006
+ local src_mtime
1007
+ src_mtime=$(file_mtime "$src_file")
1008
+ if [[ "$src_mtime" -gt "$oldest_mtime" ]]; then
1009
+ count=$((count + 1))
1010
+ fi
1011
+ done < <(find "$project_dir" -type f \
1012
+ \( -name '*.java' -o -name '*.py' -o -name '*.ts' -o -name '*.tsx' \
1013
+ -o -name '*.js' -o -name '*.jsx' -o -name '*.vue' -o -name '*.svelte' \
1014
+ -o -name '*.go' -o -name '*.rs' -o -name '*.kt' -o -name '*.swift' \
1015
+ -o -name '*.dart' -o -name '*.ets' -o -name '*.sh' -o -name '*.html' \
1016
+ \) -not -path '*/node_modules/*' -not -path '*/.git/*' \
1017
+ -not -path '*/.atool-docs/*' -not -path '*/build/*' \
1018
+ -not -path '*/dist/*' -not -path '*/target/*' \
1019
+ 2>/dev/null | head -200)
1020
+
1021
+ echo "$count"
1022
+ }
1023
+
1024
+ # ── Version info ────────────────────────────────────────────────────────────
1025
+
1026
+ show_version() {
1027
+ echo "aTool v${ATOOL_VERSION}"
1028
+ }
1029
+
1030
+ show_banner() {
1031
+ echo -e "${CYAN}${BOLD}"
1032
+ cat <<'EOF'
1033
+ ╔══════════════════════════════════════╗
1034
+ ║ aTool - AI Dev Toolkit ║
1035
+ ║ One-command AI IDE configuration ║
1036
+ ╚══════════════════════════════════════╝
1037
+ EOF
1038
+ echo -e "${NC}"
1039
+ echo -e " Version: ${ATOOL_VERSION}"
1040
+ echo ""
1041
+ }