@thanhvn14/csvibe 0.1.3 → 0.1.5

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 (395) hide show
  1. package/.github/agents/schemas/base-output.schema.json +88 -0
  2. package/.github/agents/schemas/brainstorm-output.schema.json +88 -0
  3. package/.github/agents/schemas/scout-output.schema.json +60 -0
  4. package/.github/agents/scripts/fetch-copilot-tools.js +245 -0
  5. package/.github/agents/scripts/lib/parse-agent-file.js +275 -0
  6. package/.github/agents/scripts/package-lock.json +78 -0
  7. package/.github/agents/scripts/package.json +22 -0
  8. package/.github/agents/scripts/schemas/agent-frontmatter.schema.json +83 -0
  9. package/.github/agents/scripts/validate-agent-all.js +157 -0
  10. package/.github/agents/scripts/validate-agent-frontmatter.js +96 -0
  11. package/.github/agents/scripts/validate-agent-handoffs.js +169 -0
  12. package/.github/agents/scripts/validate-agent-output.js +157 -0
  13. package/.github/agents/scripts/validate-agent-tools.js +278 -0
  14. package/.github/skills/.env.example +100 -0
  15. package/.github/skills/.install-state.json +23 -0
  16. package/.github/skills/README.md +149 -0
  17. package/.github/skills/ai-multimodal/.env.example +204 -0
  18. package/.github/skills/ai-multimodal/scripts/.coverage +0 -0
  19. package/.github/skills/ai-multimodal/scripts/check_setup.py +305 -0
  20. package/.github/skills/ai-multimodal/scripts/document_converter.py +395 -0
  21. package/.github/skills/ai-multimodal/scripts/gemini_batch_process.py +1184 -0
  22. package/.github/skills/ai-multimodal/scripts/media_optimizer.py +506 -0
  23. package/.github/skills/ai-multimodal/scripts/requirements.txt +26 -0
  24. package/.github/skills/better-auth/scripts/.coverage +0 -0
  25. package/.github/skills/better-auth/scripts/better_auth_init.py +521 -0
  26. package/.github/skills/better-auth/scripts/requirements.txt +15 -0
  27. package/.github/skills/chrome-devtools/scripts/README.md +272 -0
  28. package/.github/skills/chrome-devtools/scripts/__tests__/selector.test.js +210 -0
  29. package/.github/skills/chrome-devtools/scripts/aria-snapshot.js +362 -0
  30. package/.github/skills/chrome-devtools/scripts/click.js +83 -0
  31. package/.github/skills/chrome-devtools/scripts/console.js +79 -0
  32. package/.github/skills/chrome-devtools/scripts/evaluate.js +53 -0
  33. package/.github/skills/chrome-devtools/scripts/fill.js +76 -0
  34. package/.github/skills/chrome-devtools/scripts/inject-auth.js +229 -0
  35. package/.github/skills/chrome-devtools/scripts/install-deps.sh +181 -0
  36. package/.github/skills/chrome-devtools/scripts/install.sh +83 -0
  37. package/.github/skills/chrome-devtools/scripts/lib/browser.js +318 -0
  38. package/.github/skills/chrome-devtools/scripts/lib/selector.js +178 -0
  39. package/.github/skills/chrome-devtools/scripts/navigate.js +54 -0
  40. package/.github/skills/chrome-devtools/scripts/network.js +106 -0
  41. package/.github/skills/chrome-devtools/scripts/package-lock.json +1589 -0
  42. package/.github/skills/chrome-devtools/scripts/package.json +16 -0
  43. package/.github/skills/chrome-devtools/scripts/performance.js +149 -0
  44. package/.github/skills/chrome-devtools/scripts/screenshot.js +198 -0
  45. package/.github/skills/chrome-devtools/scripts/select-ref.js +131 -0
  46. package/.github/skills/chrome-devtools/scripts/snapshot.js +135 -0
  47. package/.github/skills/common/README.md +120 -0
  48. package/.github/skills/common/api_key_helper.py +411 -0
  49. package/.github/skills/common/api_key_rotator.py +248 -0
  50. package/.github/skills/databases/scripts/.coverage +0 -0
  51. package/.github/skills/databases/scripts/db_backup.py +502 -0
  52. package/.github/skills/databases/scripts/db_migrate.py +425 -0
  53. package/.github/skills/databases/scripts/db_performance_check.py +456 -0
  54. package/.github/skills/databases/scripts/requirements.txt +20 -0
  55. package/.github/skills/debugging/scripts/find-polluter.sh +63 -0
  56. package/.github/skills/devops/.env.example +76 -0
  57. package/.github/skills/devops/scripts/cloudflare_deploy.py +269 -0
  58. package/.github/skills/devops/scripts/docker_optimize.py +331 -0
  59. package/.github/skills/devops/scripts/requirements.txt +20 -0
  60. package/.github/skills/docs-seeker/.env.example +15 -0
  61. package/.github/skills/docs-seeker/package.json +25 -0
  62. package/.github/skills/docs-seeker/scripts/analyze-llms-txt.js +211 -0
  63. package/.github/skills/docs-seeker/scripts/detect-topic.js +172 -0
  64. package/.github/skills/docs-seeker/scripts/fetch-docs.js +213 -0
  65. package/.github/skills/docs-seeker/scripts/utils/env-loader.js +94 -0
  66. package/.github/skills/document-skills/docx/LICENSE.txt +30 -0
  67. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  68. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  69. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  70. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  71. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  72. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  73. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  74. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  75. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  76. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  77. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  78. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  79. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  80. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  81. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  82. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  83. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  84. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  85. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  86. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  87. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  88. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  89. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  90. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  91. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  92. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  93. package/.github/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  94. package/.github/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  95. package/.github/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  96. package/.github/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  97. package/.github/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  98. package/.github/skills/document-skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
  99. package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  100. package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  101. package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  102. package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  103. package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  104. package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  105. package/.github/skills/document-skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  106. package/.github/skills/document-skills/docx/ooxml/scripts/pack.py +159 -0
  107. package/.github/skills/document-skills/docx/ooxml/scripts/unpack.py +29 -0
  108. package/.github/skills/document-skills/docx/ooxml/scripts/validate.py +69 -0
  109. package/.github/skills/document-skills/docx/ooxml/scripts/validation/__init__.py +15 -0
  110. package/.github/skills/document-skills/docx/ooxml/scripts/validation/base.py +951 -0
  111. package/.github/skills/document-skills/docx/ooxml/scripts/validation/docx.py +274 -0
  112. package/.github/skills/document-skills/docx/ooxml/scripts/validation/pptx.py +315 -0
  113. package/.github/skills/document-skills/docx/ooxml/scripts/validation/redlining.py +279 -0
  114. package/.github/skills/document-skills/docx/scripts/__init__.py +1 -0
  115. package/.github/skills/document-skills/docx/scripts/document.py +1276 -0
  116. package/.github/skills/document-skills/docx/scripts/templates/comments.xml +3 -0
  117. package/.github/skills/document-skills/docx/scripts/templates/commentsExtended.xml +3 -0
  118. package/.github/skills/document-skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  119. package/.github/skills/document-skills/docx/scripts/templates/commentsIds.xml +3 -0
  120. package/.github/skills/document-skills/docx/scripts/templates/people.xml +3 -0
  121. package/.github/skills/document-skills/docx/scripts/utilities.py +374 -0
  122. package/.github/skills/document-skills/pdf/LICENSE.txt +30 -0
  123. package/.github/skills/document-skills/pdf/scripts/check_bounding_boxes.py +70 -0
  124. package/.github/skills/document-skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
  125. package/.github/skills/document-skills/pdf/scripts/check_fillable_fields.py +12 -0
  126. package/.github/skills/document-skills/pdf/scripts/convert_pdf_to_images.py +35 -0
  127. package/.github/skills/document-skills/pdf/scripts/create_validation_image.py +41 -0
  128. package/.github/skills/document-skills/pdf/scripts/extract_form_field_info.py +152 -0
  129. package/.github/skills/document-skills/pdf/scripts/fill_fillable_fields.py +114 -0
  130. package/.github/skills/document-skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  131. package/.github/skills/document-skills/pptx/LICENSE.txt +30 -0
  132. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  133. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  134. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  135. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  136. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  137. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  138. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  139. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  140. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  141. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  142. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  143. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  144. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  145. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  146. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  147. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  148. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  149. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  150. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  151. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  152. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  153. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  154. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  155. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  156. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  157. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  158. package/.github/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  159. package/.github/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  160. package/.github/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  161. package/.github/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  162. package/.github/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  163. package/.github/skills/document-skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
  164. package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  165. package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  166. package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  167. package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  168. package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  169. package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  170. package/.github/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  171. package/.github/skills/document-skills/pptx/ooxml/scripts/pack.py +159 -0
  172. package/.github/skills/document-skills/pptx/ooxml/scripts/unpack.py +29 -0
  173. package/.github/skills/document-skills/pptx/ooxml/scripts/validate.py +69 -0
  174. package/.github/skills/document-skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
  175. package/.github/skills/document-skills/pptx/ooxml/scripts/validation/base.py +951 -0
  176. package/.github/skills/document-skills/pptx/ooxml/scripts/validation/docx.py +274 -0
  177. package/.github/skills/document-skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
  178. package/.github/skills/document-skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
  179. package/.github/skills/document-skills/pptx/scripts/html2pptx.js +979 -0
  180. package/.github/skills/document-skills/pptx/scripts/inventory.py +1020 -0
  181. package/.github/skills/document-skills/pptx/scripts/rearrange.py +231 -0
  182. package/.github/skills/document-skills/pptx/scripts/replace.py +385 -0
  183. package/.github/skills/document-skills/pptx/scripts/thumbnail.py +450 -0
  184. package/.github/skills/document-skills/xlsx/LICENSE.txt +30 -0
  185. package/.github/skills/document-skills/xlsx/recalc.py +190 -0
  186. package/.github/skills/install.ps1 +1220 -0
  187. package/.github/skills/install.sh +1032 -0
  188. package/.github/skills/markdown-novel-viewer/assets/directory-browser.css +215 -0
  189. package/.github/skills/markdown-novel-viewer/assets/favicon.png +0 -0
  190. package/.github/skills/markdown-novel-viewer/assets/novel-theme.css +818 -0
  191. package/.github/skills/markdown-novel-viewer/assets/reader.js +262 -0
  192. package/.github/skills/markdown-novel-viewer/assets/template.html +80 -0
  193. package/.github/skills/markdown-novel-viewer/package-lock.json +146 -0
  194. package/.github/skills/markdown-novel-viewer/package.json +15 -0
  195. package/.github/skills/markdown-novel-viewer/scripts/lib/http-server.cjs +434 -0
  196. package/.github/skills/markdown-novel-viewer/scripts/lib/markdown-renderer.cjs +272 -0
  197. package/.github/skills/markdown-novel-viewer/scripts/lib/plan-navigator.cjs +509 -0
  198. package/.github/skills/markdown-novel-viewer/scripts/lib/port-finder.cjs +48 -0
  199. package/.github/skills/markdown-novel-viewer/scripts/lib/process-mgr.cjs +150 -0
  200. package/.github/skills/markdown-novel-viewer/scripts/server.cjs +411 -0
  201. package/.github/skills/mcp-builder/LICENSE.txt +202 -0
  202. package/.github/skills/mcp-builder/scripts/connections.py +151 -0
  203. package/.github/skills/mcp-builder/scripts/evaluation.py +373 -0
  204. package/.github/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  205. package/.github/skills/mcp-builder/scripts/requirements.txt +2 -0
  206. package/.github/skills/mcp-management/README.md +219 -0
  207. package/.github/skills/mcp-management/assets/tools.json +3146 -0
  208. package/.github/skills/mcp-management/package-lock.json +6 -0
  209. package/.github/skills/mcp-management/scripts/.env.example +10 -0
  210. package/.github/skills/mcp-management/scripts/cli.ts +195 -0
  211. package/.github/skills/mcp-management/scripts/dist/analyze-tools.js +70 -0
  212. package/.github/skills/mcp-management/scripts/dist/cli.js +160 -0
  213. package/.github/skills/mcp-management/scripts/dist/mcp-client.js +183 -0
  214. package/.github/skills/mcp-management/scripts/mcp-client.ts +230 -0
  215. package/.github/skills/mcp-management/scripts/package.json +20 -0
  216. package/.github/skills/media-processing/scripts/README.md +111 -0
  217. package/.github/skills/media-processing/scripts/batch-remove-background.sh +124 -0
  218. package/.github/skills/media-processing/scripts/batch_resize.py +342 -0
  219. package/.github/skills/media-processing/scripts/media_convert.py +311 -0
  220. package/.github/skills/media-processing/scripts/remove-background.sh +96 -0
  221. package/.github/skills/media-processing/scripts/remove-bg-node.js +158 -0
  222. package/.github/skills/media-processing/scripts/requirements.txt +24 -0
  223. package/.github/skills/media-processing/scripts/video_optimize.py +414 -0
  224. package/.github/skills/payment-integration/README.md +185 -0
  225. package/.github/skills/payment-integration/scripts/.env.example +20 -0
  226. package/.github/skills/payment-integration/scripts/checkout-helper.js +244 -0
  227. package/.github/skills/payment-integration/scripts/package.json +17 -0
  228. package/.github/skills/payment-integration/scripts/polar-webhook-verify.js +202 -0
  229. package/.github/skills/payment-integration/scripts/sepay-webhook-verify.js +193 -0
  230. package/.github/skills/payment-integration/scripts/test-scripts.js +237 -0
  231. package/.github/skills/plans-kanban/assets/dashboard-template.html +119 -0
  232. package/.github/skills/plans-kanban/assets/dashboard.css +1594 -0
  233. package/.github/skills/plans-kanban/assets/dashboard.js +596 -0
  234. package/.github/skills/plans-kanban/assets/favicon.png +0 -0
  235. package/.github/skills/plans-kanban/package-lock.json +123 -0
  236. package/.github/skills/plans-kanban/package.json +13 -0
  237. package/.github/skills/plans-kanban/scripts/lib/dashboard-renderer.cjs +884 -0
  238. package/.github/skills/plans-kanban/scripts/lib/http-server.cjs +310 -0
  239. package/.github/skills/plans-kanban/scripts/lib/plan-metadata-extractor.cjs +489 -0
  240. package/.github/skills/plans-kanban/scripts/lib/plan-parser.cjs +175 -0
  241. package/.github/skills/plans-kanban/scripts/lib/plan-scanner.cjs +272 -0
  242. package/.github/skills/plans-kanban/scripts/lib/port-finder.cjs +48 -0
  243. package/.github/skills/plans-kanban/scripts/lib/process-mgr.cjs +128 -0
  244. package/.github/skills/plans-kanban/scripts/server.cjs +260 -0
  245. package/.github/skills/repomix/scripts/.coverage +0 -0
  246. package/.github/skills/repomix/scripts/README.md +179 -0
  247. package/.github/skills/repomix/scripts/repomix_batch.py +455 -0
  248. package/.github/skills/repomix/scripts/repos.example.json +15 -0
  249. package/.github/skills/repomix/scripts/requirements.txt +15 -0
  250. package/.github/skills/scout-validation/scripts/lib/broad-pattern-detector.cjs +124 -0
  251. package/.github/skills/scout-validation/scripts/lib/path-checker.cjs +66 -0
  252. package/.github/skills/scout-validation/scripts/lib/schema-validator.cjs +45 -0
  253. package/.github/skills/scout-validation/scripts/package.json +11 -0
  254. package/.github/skills/scout-validation/scripts/validate-scout-output.cjs +219 -0
  255. package/.github/skills/scout-validation/test/broad-pattern-output.json +18 -0
  256. package/.github/skills/scout-validation/test/invalid-path-output.json +18 -0
  257. package/.github/skills/scout-validation/test/valid-scout-output.json +26 -0
  258. package/.github/skills/sequential-thinking/.env.example +8 -0
  259. package/.github/skills/sequential-thinking/README.md +183 -0
  260. package/.github/skills/sequential-thinking/package.json +31 -0
  261. package/.github/skills/sequential-thinking/scripts/format-thought.js +159 -0
  262. package/.github/skills/sequential-thinking/scripts/process-thought.js +236 -0
  263. package/.github/skills/shopify/README.md +66 -0
  264. package/.github/skills/shopify/scripts/.coverage +0 -0
  265. package/.github/skills/shopify/scripts/requirements.txt +19 -0
  266. package/.github/skills/shopify/scripts/shopify_init.py +423 -0
  267. package/.github/skills/skill-creator/LICENSE.txt +202 -0
  268. package/.github/skills/skill-creator/scripts/init_skill.py +303 -0
  269. package/.github/skills/skill-creator/scripts/package_skill.py +110 -0
  270. package/.github/skills/skill-creator/scripts/quick_validate.py +65 -0
  271. package/.github/skills/ui-styling/LICENSE.txt +202 -0
  272. package/.github/skills/ui-styling/canvas-fonts/ArsenalSC-OFL.txt +93 -0
  273. package/.github/skills/ui-styling/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
  274. package/.github/skills/ui-styling/canvas-fonts/BigShoulders-Bold.ttf +0 -0
  275. package/.github/skills/ui-styling/canvas-fonts/BigShoulders-OFL.txt +93 -0
  276. package/.github/skills/ui-styling/canvas-fonts/BigShoulders-Regular.ttf +0 -0
  277. package/.github/skills/ui-styling/canvas-fonts/Boldonse-OFL.txt +93 -0
  278. package/.github/skills/ui-styling/canvas-fonts/Boldonse-Regular.ttf +0 -0
  279. package/.github/skills/ui-styling/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  280. package/.github/skills/ui-styling/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
  281. package/.github/skills/ui-styling/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  282. package/.github/skills/ui-styling/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
  283. package/.github/skills/ui-styling/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
  284. package/.github/skills/ui-styling/canvas-fonts/CrimsonPro-OFL.txt +93 -0
  285. package/.github/skills/ui-styling/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
  286. package/.github/skills/ui-styling/canvas-fonts/DMMono-OFL.txt +93 -0
  287. package/.github/skills/ui-styling/canvas-fonts/DMMono-Regular.ttf +0 -0
  288. package/.github/skills/ui-styling/canvas-fonts/EricaOne-OFL.txt +94 -0
  289. package/.github/skills/ui-styling/canvas-fonts/EricaOne-Regular.ttf +0 -0
  290. package/.github/skills/ui-styling/canvas-fonts/GeistMono-Bold.ttf +0 -0
  291. package/.github/skills/ui-styling/canvas-fonts/GeistMono-OFL.txt +93 -0
  292. package/.github/skills/ui-styling/canvas-fonts/GeistMono-Regular.ttf +0 -0
  293. package/.github/skills/ui-styling/canvas-fonts/Gloock-OFL.txt +93 -0
  294. package/.github/skills/ui-styling/canvas-fonts/Gloock-Regular.ttf +0 -0
  295. package/.github/skills/ui-styling/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
  296. package/.github/skills/ui-styling/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
  297. package/.github/skills/ui-styling/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
  298. package/.github/skills/ui-styling/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
  299. package/.github/skills/ui-styling/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
  300. package/.github/skills/ui-styling/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
  301. package/.github/skills/ui-styling/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
  302. package/.github/skills/ui-styling/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  303. package/.github/skills/ui-styling/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  304. package/.github/skills/ui-styling/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  305. package/.github/skills/ui-styling/canvas-fonts/InstrumentSans-OFL.txt +93 -0
  306. package/.github/skills/ui-styling/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  307. package/.github/skills/ui-styling/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  308. package/.github/skills/ui-styling/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  309. package/.github/skills/ui-styling/canvas-fonts/Italiana-OFL.txt +93 -0
  310. package/.github/skills/ui-styling/canvas-fonts/Italiana-Regular.ttf +0 -0
  311. package/.github/skills/ui-styling/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  312. package/.github/skills/ui-styling/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
  313. package/.github/skills/ui-styling/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  314. package/.github/skills/ui-styling/canvas-fonts/Jura-Light.ttf +0 -0
  315. package/.github/skills/ui-styling/canvas-fonts/Jura-Medium.ttf +0 -0
  316. package/.github/skills/ui-styling/canvas-fonts/Jura-OFL.txt +93 -0
  317. package/.github/skills/ui-styling/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
  318. package/.github/skills/ui-styling/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
  319. package/.github/skills/ui-styling/canvas-fonts/Lora-Bold.ttf +0 -0
  320. package/.github/skills/ui-styling/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  321. package/.github/skills/ui-styling/canvas-fonts/Lora-Italic.ttf +0 -0
  322. package/.github/skills/ui-styling/canvas-fonts/Lora-OFL.txt +93 -0
  323. package/.github/skills/ui-styling/canvas-fonts/Lora-Regular.ttf +0 -0
  324. package/.github/skills/ui-styling/canvas-fonts/NationalPark-Bold.ttf +0 -0
  325. package/.github/skills/ui-styling/canvas-fonts/NationalPark-OFL.txt +93 -0
  326. package/.github/skills/ui-styling/canvas-fonts/NationalPark-Regular.ttf +0 -0
  327. package/.github/skills/ui-styling/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
  328. package/.github/skills/ui-styling/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  329. package/.github/skills/ui-styling/canvas-fonts/Outfit-Bold.ttf +0 -0
  330. package/.github/skills/ui-styling/canvas-fonts/Outfit-OFL.txt +93 -0
  331. package/.github/skills/ui-styling/canvas-fonts/Outfit-Regular.ttf +0 -0
  332. package/.github/skills/ui-styling/canvas-fonts/PixelifySans-Medium.ttf +0 -0
  333. package/.github/skills/ui-styling/canvas-fonts/PixelifySans-OFL.txt +93 -0
  334. package/.github/skills/ui-styling/canvas-fonts/PoiretOne-OFL.txt +93 -0
  335. package/.github/skills/ui-styling/canvas-fonts/PoiretOne-Regular.ttf +0 -0
  336. package/.github/skills/ui-styling/canvas-fonts/RedHatMono-Bold.ttf +0 -0
  337. package/.github/skills/ui-styling/canvas-fonts/RedHatMono-OFL.txt +93 -0
  338. package/.github/skills/ui-styling/canvas-fonts/RedHatMono-Regular.ttf +0 -0
  339. package/.github/skills/ui-styling/canvas-fonts/Silkscreen-OFL.txt +93 -0
  340. package/.github/skills/ui-styling/canvas-fonts/Silkscreen-Regular.ttf +0 -0
  341. package/.github/skills/ui-styling/canvas-fonts/SmoochSans-Medium.ttf +0 -0
  342. package/.github/skills/ui-styling/canvas-fonts/SmoochSans-OFL.txt +93 -0
  343. package/.github/skills/ui-styling/canvas-fonts/Tektur-Medium.ttf +0 -0
  344. package/.github/skills/ui-styling/canvas-fonts/Tektur-OFL.txt +93 -0
  345. package/.github/skills/ui-styling/canvas-fonts/Tektur-Regular.ttf +0 -0
  346. package/.github/skills/ui-styling/canvas-fonts/WorkSans-Bold.ttf +0 -0
  347. package/.github/skills/ui-styling/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
  348. package/.github/skills/ui-styling/canvas-fonts/WorkSans-Italic.ttf +0 -0
  349. package/.github/skills/ui-styling/canvas-fonts/WorkSans-OFL.txt +93 -0
  350. package/.github/skills/ui-styling/canvas-fonts/WorkSans-Regular.ttf +0 -0
  351. package/.github/skills/ui-styling/canvas-fonts/YoungSerif-OFL.txt +93 -0
  352. package/.github/skills/ui-styling/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  353. package/.github/skills/ui-styling/scripts/.coverage +0 -0
  354. package/.github/skills/ui-styling/scripts/requirements.txt +17 -0
  355. package/.github/skills/ui-styling/scripts/shadcn_add.py +292 -0
  356. package/.github/skills/ui-styling/scripts/tailwind_config_gen.py +456 -0
  357. package/.github/skills/ui-ux-pro-max/data/charts.csv +26 -0
  358. package/.github/skills/ui-ux-pro-max/data/colors.csv +97 -0
  359. package/.github/skills/ui-ux-pro-max/data/landing.csv +31 -0
  360. package/.github/skills/ui-ux-pro-max/data/products.csv +97 -0
  361. package/.github/skills/ui-ux-pro-max/data/prompts.csv +24 -0
  362. package/.github/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  363. package/.github/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +51 -0
  364. package/.github/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  365. package/.github/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  366. package/.github/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  367. package/.github/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  368. package/.github/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  369. package/.github/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  370. package/.github/skills/ui-ux-pro-max/data/styles.csv +59 -0
  371. package/.github/skills/ui-ux-pro-max/data/typography.csv +58 -0
  372. package/.github/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  373. package/.github/skills/ui-ux-pro-max/scripts/core.py +236 -0
  374. package/.github/skills/ui-ux-pro-max/scripts/search.py +76 -0
  375. package/.github/skills/web-frameworks/scripts/.coverage +0 -0
  376. package/.github/skills/web-frameworks/scripts/__init__.py +0 -0
  377. package/.github/skills/web-frameworks/scripts/nextjs_init.py +547 -0
  378. package/.github/skills/web-frameworks/scripts/requirements.txt +16 -0
  379. package/.github/skills/web-frameworks/scripts/turborepo_migrate.py +394 -0
  380. package/dist/config/constants.d.ts +3 -0
  381. package/dist/config/constants.d.ts.map +1 -1
  382. package/dist/config/constants.js +5 -1
  383. package/dist/config/constants.js.map +1 -1
  384. package/dist/domains/github/github-client.d.ts +5 -0
  385. package/dist/domains/github/github-client.d.ts.map +1 -1
  386. package/dist/domains/github/github-client.js +44 -0
  387. package/dist/domains/github/github-client.js.map +1 -1
  388. package/dist/utils/downloader.d.ts +3 -1
  389. package/dist/utils/downloader.d.ts.map +1 -1
  390. package/dist/utils/downloader.js +48 -11
  391. package/dist/utils/downloader.js.map +1 -1
  392. package/dist/utils/scaffolder.d.ts.map +1 -1
  393. package/dist/utils/scaffolder.js +2 -0
  394. package/dist/utils/scaffolder.js.map +1 -1
  395. package/package.json +3 -1
@@ -0,0 +1,1032 @@
1
+ #!/bin/bash
2
+ # Skills Installation Script for Linux/macOS
3
+ # Installs all dependencies for Claude Code skills
4
+ #
5
+ # Exit codes (rustup model):
6
+ # 0 = Success (full or partial)
7
+ # 1 = Fatal error (no Python, broken venv)
8
+ # 2 = Partial success (some optional deps failed)
9
+
10
+ # set -e removed - we handle errors per-phase
11
+
12
+ # Parse command line arguments
13
+ SKIP_CONFIRM=false
14
+ WITH_SUDO=false
15
+ RESUME_MODE=false
16
+ RETRY_FAILED=false
17
+ while [[ "$#" -gt 0 ]]; do
18
+ case $1 in
19
+ -y|--yes) SKIP_CONFIRM=true ;;
20
+ --with-sudo) WITH_SUDO=true ;;
21
+ --resume) RESUME_MODE=true ;;
22
+ --retry-failed) RETRY_FAILED=true ;;
23
+ *) echo "Unknown parameter: $1"; exit 1 ;;
24
+ esac
25
+ shift
26
+ done
27
+
28
+ # Check for NON_INTERACTIVE environment variable
29
+ if [[ -n "${NON_INTERACTIVE}" ]]; then
30
+ SKIP_CONFIRM=true
31
+ fi
32
+
33
+ # Colors for output
34
+ RED='\033[0;31m'
35
+ GREEN='\033[0;32m'
36
+ YELLOW='\033[1;33m'
37
+ BLUE='\033[0;34m'
38
+ NC='\033[0m' # No Color
39
+
40
+ # Configuration
41
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
42
+ VENV_DIR="$SCRIPT_DIR/.venv"
43
+ STATE_FILE="$SCRIPT_DIR/.install-state.json"
44
+ LOG_DIR="$VENV_DIR/logs"
45
+
46
+ # Installation tracking arrays (Bash 3.2+ compatible - indexed arrays only)
47
+ declare -a INSTALLED_CRITICAL=()
48
+ declare -a INSTALLED_OPTIONAL=()
49
+ declare -a FAILED_OPTIONAL=()
50
+ declare -a SKIPPED_SUDO=()
51
+ FINAL_EXIT_CODE=0
52
+
53
+ # Detect OS
54
+ detect_os() {
55
+ if [[ "$OSTYPE" == "darwin"* ]]; then
56
+ echo "macos"
57
+ elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
58
+ echo "linux"
59
+ else
60
+ echo "unknown"
61
+ fi
62
+ }
63
+
64
+ # Print functions (must be defined before check_bash_version)
65
+ print_header() {
66
+ echo -e "\n${BLUE}===================================================${NC}"
67
+ echo -e "${BLUE}$1${NC}"
68
+ echo -e "${BLUE}===================================================${NC}\n"
69
+ }
70
+
71
+ print_success() {
72
+ echo -e "${GREEN}✓${NC} $1"
73
+ }
74
+
75
+ print_warning() {
76
+ echo -e "${YELLOW}⚠${NC} $1"
77
+ }
78
+
79
+ print_error() {
80
+ echo -e "${RED}✗${NC} $1"
81
+ }
82
+
83
+ print_info() {
84
+ echo -e "${BLUE}ℹ${NC} $1"
85
+ }
86
+
87
+ # Check Bash version (3.2+ required for compatibility)
88
+ check_bash_version() {
89
+ # Get major version number
90
+ bash_major="${BASH_VERSINFO[0]}"
91
+
92
+ if [ "$bash_major" -lt 3 ]; then
93
+ print_error "Bash 3.0+ required (found Bash $BASH_VERSION)"
94
+ print_info "Please upgrade Bash and re-run this script"
95
+ exit 1
96
+ fi
97
+
98
+ if [ "$bash_major" -lt 4 ]; then
99
+ print_warning "Bash 3.x detected (Bash 4+ recommended)"
100
+
101
+ if [[ "$OSTYPE" == "darwin"* ]]; then
102
+ print_info "macOS ships with Bash 3.2 by default"
103
+ print_info "For better compatibility: brew install bash"
104
+ print_info "Then use: /usr/local/bin/bash install.sh"
105
+ fi
106
+
107
+ print_info "Continuing with compatibility mode..."
108
+ fi
109
+ }
110
+
111
+ OS=$(detect_os)
112
+ check_bash_version
113
+
114
+ # Check if command exists
115
+ command_exists() {
116
+ command -v "$1" >/dev/null 2>&1
117
+ }
118
+
119
+ # ============================================================================
120
+ # Installation Tracking Functions
121
+ # ============================================================================
122
+
123
+ track_success() {
124
+ local category="$1" name="$2"
125
+ if [[ "$category" == "critical" ]]; then
126
+ INSTALLED_CRITICAL+=("$name")
127
+ else
128
+ INSTALLED_OPTIONAL+=("$name")
129
+ fi
130
+ }
131
+
132
+ track_failure() {
133
+ local category="$1" name="$2" reason="$3"
134
+ if [[ "$category" == "critical" ]]; then
135
+ FINAL_EXIT_CODE=1
136
+ else
137
+ FAILED_OPTIONAL+=("$name: $reason")
138
+ [[ "$FINAL_EXIT_CODE" == "0" ]] && FINAL_EXIT_CODE=2
139
+ fi
140
+ }
141
+
142
+ track_skipped() {
143
+ local name="$1" reason="$2"
144
+ SKIPPED_SUDO+=("$name: $reason")
145
+ }
146
+
147
+ # ============================================================================
148
+ # State Persistence Functions
149
+ # ============================================================================
150
+
151
+ # Initialize or load state
152
+ init_state() {
153
+ if [[ "$RESUME_MODE" == "true" ]] && [[ -f "$STATE_FILE" ]]; then
154
+ print_info "Resuming from previous installation..."
155
+ return 0
156
+ fi
157
+
158
+ # Create fresh state
159
+ cat > "$STATE_FILE" << EOF
160
+ {
161
+ "version": 1,
162
+ "started_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
163
+ "last_updated": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
164
+ "phases": {
165
+ "system_deps": "pending",
166
+ "node_deps": "pending",
167
+ "python_env": "pending",
168
+ "verify": "pending"
169
+ },
170
+ "packages": {
171
+ "installed": [],
172
+ "failed": [],
173
+ "skipped": []
174
+ }
175
+ }
176
+ EOF
177
+ }
178
+
179
+ # Update phase status
180
+ update_phase() {
181
+ local phase="$1" status="$2"
182
+ if [[ ! -f "$STATE_FILE" ]]; then
183
+ return 0
184
+ fi
185
+ local temp_file="$STATE_FILE.tmp"
186
+
187
+ # Simple sed replacement (jq not required)
188
+ sed "s/\"$phase\": \"[^\"]*\"/\"$phase\": \"$status\"/" "$STATE_FILE" > "$temp_file"
189
+ mv "$temp_file" "$STATE_FILE"
190
+
191
+ # Update timestamp
192
+ sed "s/\"last_updated\": \"[^\"]*\"/\"last_updated\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"/" "$STATE_FILE" > "$temp_file"
193
+ mv "$temp_file" "$STATE_FILE"
194
+ }
195
+
196
+ # Check if phase is already done (for resume)
197
+ phase_done() {
198
+ local phase="$1"
199
+ grep -q "\"$phase\": \"done\"" "$STATE_FILE" 2>/dev/null
200
+ }
201
+
202
+ # Clean state file (on complete success)
203
+ clean_state() {
204
+ if [[ -f "$STATE_FILE" ]]; then
205
+ rm -f "$STATE_FILE"
206
+ print_info "Installation state cleaned (success)"
207
+ fi
208
+ }
209
+
210
+ # ============================================================================
211
+ # Build Tools Detection
212
+ # ============================================================================
213
+
214
+ # Check if system has C build tools for compiling Python packages
215
+ has_build_tools() {
216
+ if command_exists gcc || command_exists clang; then
217
+ if [[ "$OS" == "linux" ]]; then
218
+ # Check for Python dev headers
219
+ if [[ -f /usr/include/python3*/Python.h ]] || \
220
+ python3-config --includes &>/dev/null; then
221
+ return 0
222
+ fi
223
+ elif [[ "$OS" == "macos" ]]; then
224
+ # macOS: Xcode command line tools include headers
225
+ if xcode-select -p &>/dev/null; then
226
+ return 0
227
+ fi
228
+ fi
229
+ fi
230
+ return 1
231
+ }
232
+
233
+ # Try pip install with wheel-first fallback
234
+ # Returns: 0=success, 1=failed
235
+ try_pip_install() {
236
+ local package_spec="$1"
237
+ local log_file="$2"
238
+ local package_name="${package_spec%%[=<>]*}" # Strip version specifier
239
+
240
+ # Phase 1: Try with prefer-binary (wheels first)
241
+ if pip install "$package_spec" --prefer-binary 2>&1 | tee -a "$log_file"; then
242
+ return 0
243
+ fi
244
+
245
+ # Phase 2: Check if we can build from source
246
+ if ! has_build_tools; then
247
+ print_warning "$package_name: No wheel available, no build tools"
248
+ if [[ "$OS" == "linux" ]]; then
249
+ print_info "Install build tools: sudo apt-get install gcc python3-dev"
250
+ elif [[ "$OS" == "macos" ]]; then
251
+ print_info "Install build tools: xcode-select --install"
252
+ fi
253
+ return 1
254
+ fi
255
+
256
+ # Phase 3: Try source build
257
+ print_info "Trying source build for $package_name..."
258
+ if pip install "$package_spec" --no-binary "$package_name" 2>&1 | tee -a "$log_file"; then
259
+ print_success "$package_name installed (source build)"
260
+ return 0
261
+ fi
262
+
263
+ print_error "$package_name: Both wheel and source build failed"
264
+ return 1
265
+ }
266
+
267
+ # Install system package - no prompts, just install or skip
268
+ # CLI controls sudo via --with-sudo flag
269
+ install_system_package() {
270
+ local package_name="$1"
271
+ local display_name="$2"
272
+ local check_commands="$3" # Comma-separated commands to check
273
+
274
+ # Check if already installed (check multiple commands)
275
+ IFS=',' read -ra cmds <<< "$check_commands"
276
+ for cmd in "${cmds[@]}"; do
277
+ if command_exists "$cmd"; then
278
+ print_success "$display_name already installed"
279
+ track_success "optional" "$display_name"
280
+ return 0
281
+ fi
282
+ done
283
+
284
+ # macOS: brew doesn't need sudo
285
+ if [[ "$OS" == "macos" ]]; then
286
+ print_info "Installing $display_name..."
287
+ if brew install "$package_name" 2>/dev/null; then
288
+ print_success "$display_name installed"
289
+ track_success "optional" "$display_name"
290
+ return 0
291
+ else
292
+ print_warning "$display_name: brew install failed"
293
+ track_failure "optional" "$display_name" "brew install failed"
294
+ return 1
295
+ fi
296
+ fi
297
+
298
+ # Linux: only install if --with-sudo was passed
299
+ if [[ "$WITH_SUDO" == "true" ]]; then
300
+ print_info "Installing $display_name (sudo)..."
301
+ if sudo apt-get install -y "$package_name"; then
302
+ print_success "$display_name installed"
303
+ track_success "optional" "$display_name"
304
+ return 0
305
+ else
306
+ print_warning "$display_name: apt-get install failed"
307
+ track_failure "optional" "$display_name" "apt-get install failed"
308
+ return 1
309
+ fi
310
+ else
311
+ # No sudo permission - track as skipped
312
+ print_info "$display_name: skipped (no --with-sudo)"
313
+ track_skipped "$display_name" "requires sudo"
314
+ return 0 # Don't fail, just skip
315
+ fi
316
+ }
317
+
318
+ # Check and install system package manager
319
+ check_package_manager() {
320
+ if [[ "$OS" == "macos" ]]; then
321
+ if ! command_exists brew; then
322
+ print_warning "Homebrew not found. Installing Homebrew..."
323
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
324
+ print_success "Homebrew installed"
325
+ else
326
+ print_success "Homebrew found"
327
+ fi
328
+ elif [[ "$OS" == "linux" ]]; then
329
+ if command_exists apt-get; then
330
+ print_success "apt-get found"
331
+ elif command_exists yum; then
332
+ print_success "yum found"
333
+ else
334
+ print_warning "No supported package manager found (apt-get or yum)"
335
+ print_info "System packages will be skipped"
336
+ # Don't exit - just warn and continue
337
+ fi
338
+ fi
339
+ }
340
+
341
+ # Install system dependencies
342
+ install_system_deps() {
343
+ print_header "Installing System Dependencies"
344
+
345
+ # Update apt cache if we have sudo permission (Linux only)
346
+ if [[ "$OS" == "linux" ]] && [[ "$WITH_SUDO" == "true" ]]; then
347
+ print_info "Updating package lists..."
348
+ sudo apt-get update -qq
349
+ fi
350
+
351
+ # FFmpeg (required for media-processing skill)
352
+ install_system_package "ffmpeg" "FFmpeg" "ffmpeg"
353
+
354
+ # ImageMagick (required for media-processing skill)
355
+ install_system_package "imagemagick" "ImageMagick" "magick,convert"
356
+
357
+ # PostgreSQL client (optional - just check)
358
+ if command_exists psql; then
359
+ print_success "PostgreSQL client already installed"
360
+ fi
361
+
362
+ # Docker (optional - just check)
363
+ if command_exists docker; then
364
+ print_success "Docker already installed ($(docker --version))"
365
+ fi
366
+ }
367
+
368
+ # Install Node.js and npm packages
369
+ install_node_deps() {
370
+ print_header "Installing Node.js Dependencies"
371
+
372
+ # Check Node.js
373
+ if command_exists node; then
374
+ NODE_VERSION=$(node --version)
375
+ print_success "Node.js already installed ($NODE_VERSION)"
376
+ else
377
+ print_info "Installing Node.js..."
378
+ if [[ "$OS" == "macos" ]]; then
379
+ brew install node
380
+ elif [[ "$OS" == "linux" ]]; then
381
+ curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
382
+ sudo apt-get install -y nodejs
383
+ fi
384
+ print_success "Node.js installed"
385
+ fi
386
+
387
+ # Install global npm packages
388
+ print_info "Installing global npm packages..."
389
+
390
+ # Package name to CLI command mapping (some packages have different CLI names)
391
+ # Using indexed array with colon-separated pairs for Bash 3.2+ compatibility
392
+ npm_packages=(
393
+ "rmbg-cli:rmbg"
394
+ "pnpm:pnpm"
395
+ "wrangler:wrangler"
396
+ "repomix:repomix"
397
+ )
398
+
399
+ for package_pair in "${npm_packages[@]}"; do
400
+ # Split "package:command" on colon
401
+ IFS=':' read -r package cmd <<< "$package_pair"
402
+
403
+ # Check CLI command first (handles standalone installs like brew, curl, etc.)
404
+ if command_exists "$cmd"; then
405
+ version=$("$cmd" --version 2>&1 | head -n1 || echo "available")
406
+ print_success "$package already installed ($version)"
407
+ # Fallback: check if installed via npm registry
408
+ elif npm list -g "$package" >/dev/null 2>&1; then
409
+ print_success "$package already installed via npm"
410
+ else
411
+ print_info "Installing $package..."
412
+ npm install -g "$package" 2>/dev/null || {
413
+ print_warning "Failed to install $package globally. Trying with sudo..."
414
+ sudo npm install -g "$package"
415
+ }
416
+ print_success "$package installed"
417
+ fi
418
+ done
419
+
420
+ # Install local npm packages for skills
421
+ print_info "Installing local npm packages for skills..."
422
+
423
+ # chrome-devtools
424
+ if [ -d "$SCRIPT_DIR/chrome-devtools/scripts" ] && [ -f "$SCRIPT_DIR/chrome-devtools/scripts/package.json" ]; then
425
+ print_info "Installing chrome-devtools dependencies..."
426
+ (cd "$SCRIPT_DIR/chrome-devtools/scripts" && npm install --quiet)
427
+ print_success "chrome-devtools dependencies installed"
428
+ fi
429
+
430
+ # sequential-thinking
431
+ if [ -d "$SCRIPT_DIR/sequential-thinking" ] && [ -f "$SCRIPT_DIR/sequential-thinking/package.json" ]; then
432
+ print_info "Installing sequential-thinking dependencies..."
433
+ (cd "$SCRIPT_DIR/sequential-thinking" && npm install --quiet)
434
+ print_success "sequential-thinking dependencies installed"
435
+ fi
436
+
437
+ # mcp-management
438
+ if [ -d "$SCRIPT_DIR/mcp-management/scripts" ] && [ -f "$SCRIPT_DIR/mcp-management/scripts/package.json" ]; then
439
+ print_info "Installing mcp-management dependencies..."
440
+ (cd "$SCRIPT_DIR/mcp-management/scripts" && npm install --quiet)
441
+ print_success "mcp-management dependencies installed"
442
+ fi
443
+
444
+ # markdown-novel-viewer (marked, highlight.js, gray-matter)
445
+ if [ -d "$SCRIPT_DIR/markdown-novel-viewer" ] && [ -f "$SCRIPT_DIR/markdown-novel-viewer/package.json" ]; then
446
+ print_info "Installing markdown-novel-viewer dependencies..."
447
+ (cd "$SCRIPT_DIR/markdown-novel-viewer" && npm install --quiet)
448
+ print_success "markdown-novel-viewer dependencies installed"
449
+ fi
450
+
451
+ # plans-kanban (gray-matter)
452
+ if [ -d "$SCRIPT_DIR/plans-kanban" ] && [ -f "$SCRIPT_DIR/plans-kanban/package.json" ]; then
453
+ print_info "Installing plans-kanban dependencies..."
454
+ (cd "$SCRIPT_DIR/plans-kanban" && npm install --quiet)
455
+ print_success "plans-kanban dependencies installed"
456
+ fi
457
+
458
+ # Optional: Shopify CLI (ask user unless auto-confirming)
459
+ if [ -d "$SCRIPT_DIR/shopify" ]; then
460
+ if [[ "$SKIP_CONFIRM" == "true" ]]; then
461
+ print_info "Skipping Shopify CLI installation (optional, use --yes to install all)"
462
+ else
463
+ read -p "Install Shopify CLI for Shopify skill? (y/N) " -n 1 -r
464
+ echo
465
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
466
+ print_info "Installing Shopify CLI..."
467
+ npm install -g @shopify/cli @shopify/theme 2>/dev/null || {
468
+ print_warning "Failed to install Shopify CLI globally. Trying with sudo..."
469
+ sudo npm install -g @shopify/cli @shopify/theme
470
+ }
471
+ print_success "Shopify CLI installed"
472
+ fi
473
+ fi
474
+ fi
475
+ }
476
+
477
+ # Setup Python virtual environment
478
+ setup_python_env() {
479
+ print_header "Setting Up Python Environment"
480
+
481
+ # Track successful and failed installations
482
+ local successful_skills=()
483
+ local failed_skills=()
484
+
485
+ # Check Python
486
+ if command_exists python3; then
487
+ PYTHON_VERSION=$(python3 --version)
488
+ PYTHON_PATH=$(which python3)
489
+ print_success "Python3 found ($PYTHON_VERSION)"
490
+
491
+ # Check for broken UV Python installation
492
+ if [[ "$PYTHON_PATH" == *"/.local/share/uv/"* ]]; then
493
+ # Verify UV Python works by testing venv creation
494
+ if ! python3 -c "import sys; sys.exit(0 if '/install' not in sys.base_prefix else 1)" 2>/dev/null; then
495
+ print_error "UV Python installation is broken (corrupted sys.base_prefix)"
496
+ print_info "Please reinstall Python using Homebrew:"
497
+ print_info " brew install python@3.12"
498
+ print_info " export PATH=\"/opt/homebrew/bin:\$PATH\""
499
+ print_info "Or fix UV Python:"
500
+ print_info " uv python uninstall 3.12"
501
+ print_info " uv python install 3.12"
502
+ exit 1
503
+ fi
504
+ fi
505
+ else
506
+ print_error "Python3 not found. Please install Python 3.7+"
507
+ exit 1
508
+ fi
509
+
510
+ # Create virtual environment (or recreate if corrupted)
511
+ create_venv() {
512
+ # Try normal venv creation first
513
+ if python3 -m venv "$VENV_DIR" 2>/dev/null; then
514
+ return 0
515
+ fi
516
+
517
+ # If ensurepip fails (common on macOS), create without pip and bootstrap manually
518
+ print_warning "Standard venv creation failed, trying without ensurepip..."
519
+ if python3 -m venv --without-pip "$VENV_DIR"; then
520
+ # Bootstrap pip manually with error handling
521
+ source "$VENV_DIR/bin/activate"
522
+ if ! curl -sS https://bootstrap.pypa.io/get-pip.py | python3; then
523
+ print_error "Failed to bootstrap pip (network issue or get-pip.py failed)"
524
+ deactivate
525
+ rm -rf "$VENV_DIR"
526
+ return 1
527
+ fi
528
+ deactivate
529
+ return 0
530
+ fi
531
+
532
+ return 1
533
+ }
534
+
535
+ if [ -d "$VENV_DIR" ]; then
536
+ # Verify venv is valid by checking for activate script AND python executable
537
+ if [ -f "$VENV_DIR/bin/activate" ] && [ -x "$VENV_DIR/bin/python3" ]; then
538
+ print_success "Virtual environment already exists at $VENV_DIR"
539
+ else
540
+ print_warning "Virtual environment is corrupted (missing activate or python3). Recreating..."
541
+ rm -rf "$VENV_DIR"
542
+ if create_venv; then
543
+ print_success "Virtual environment recreated"
544
+ else
545
+ print_error "Failed to create virtual environment"
546
+ exit 1
547
+ fi
548
+ fi
549
+ else
550
+ print_info "Creating virtual environment at $VENV_DIR..."
551
+ if create_venv; then
552
+ print_success "Virtual environment created"
553
+ else
554
+ print_error "Failed to create virtual environment"
555
+ exit 1
556
+ fi
557
+ fi
558
+
559
+ # Activate and install packages
560
+ print_info "Activating virtual environment..."
561
+ source "$VENV_DIR/bin/activate"
562
+
563
+ # Create log directory
564
+ local LOG_DIR="$VENV_DIR/logs"
565
+ mkdir -p "$LOG_DIR"
566
+
567
+ # Upgrade pip with logging (use --prefer-binary)
568
+ print_info "Upgrading pip..."
569
+ if pip install --upgrade pip --prefer-binary 2>&1 | tee "$LOG_DIR/pip-upgrade.log" | tail -n 3; then
570
+ print_success "pip upgraded successfully"
571
+ else
572
+ print_warning "pip upgrade failed (continuing anyway)"
573
+ print_info "See log: $LOG_DIR/pip-upgrade.log"
574
+ fi
575
+
576
+ # Install dependencies from all skills' requirements.txt files
577
+ print_info "Installing Python dependencies from all skills..."
578
+
579
+ local installed_count=0
580
+ for skill_dir in "$SCRIPT_DIR"/*; do
581
+ if [ -d "$skill_dir" ]; then
582
+ skill_name=$(basename "$skill_dir")
583
+
584
+ # Skip .venv and document-skills
585
+ if [ "$skill_name" == ".venv" ] || [ "$skill_name" == "document-skills" ]; then
586
+ continue
587
+ fi
588
+
589
+ # Install main requirements.txt with wheel-first approach
590
+ if [ -f "$skill_dir/scripts/requirements.txt" ]; then
591
+ local SKILL_LOG="$LOG_DIR/install-${skill_name}.log"
592
+
593
+ print_info "Installing $skill_name dependencies..."
594
+
595
+ # Read requirements and install one-by-one for granular tracking
596
+ local pkg_success=0
597
+ local pkg_fail=0
598
+ while IFS= read -r line || [[ -n "$line" ]]; do
599
+ # Skip comments and empty lines
600
+ [[ "$line" =~ ^#.*$ ]] && continue
601
+ [[ -z "${line// }" ]] && continue
602
+
603
+ # Strip inline comments (e.g., "package>=1.0 # comment" -> "package>=1.0")
604
+ line="${line%%#*}"
605
+ line="${line%"${line##*[![:space:]]}"}" # trim trailing whitespace
606
+ [[ -z "$line" ]] && continue
607
+
608
+ if try_pip_install "$line" "$SKILL_LOG"; then
609
+ pkg_success=$((pkg_success + 1))
610
+ else
611
+ pkg_fail=$((pkg_fail + 1))
612
+ track_failure "optional" "$skill_name:$line" "Package install failed"
613
+ fi
614
+ done < "$skill_dir/scripts/requirements.txt"
615
+
616
+ if [[ $pkg_fail -eq 0 ]]; then
617
+ print_success "$skill_name: all $pkg_success packages installed"
618
+ track_success "optional" "$skill_name"
619
+ successful_skills+=("$skill_name")
620
+ installed_count=$((installed_count + 1))
621
+ else
622
+ print_warning "$skill_name: $pkg_success installed, $pkg_fail failed"
623
+ failed_skills+=("$skill_name")
624
+ fi
625
+ fi
626
+
627
+ # Install test requirements.txt
628
+ if [ -f "$skill_dir/scripts/tests/requirements.txt" ]; then
629
+ local SKILL_TEST_LOG="$LOG_DIR/install-${skill_name}-tests.log"
630
+
631
+ print_info "Installing $skill_name test dependencies..."
632
+
633
+ if pip install -r "$skill_dir/scripts/tests/requirements.txt" --prefer-binary 2>&1 | tee "$SKILL_TEST_LOG"; then
634
+ print_success "$skill_name test dependencies installed successfully"
635
+ else
636
+ print_warning "$skill_name test dependencies failed to install"
637
+ # Don't fail installation if test deps fail (less critical)
638
+ fi
639
+ fi
640
+ fi
641
+ done
642
+
643
+ # Install %USERPROFILE%/.claude/scripts requirements (contains pyyaml for generate_catalogs.py)
644
+ local SCRIPTS_REQ="$SCRIPT_DIR/../scripts/requirements.txt"
645
+ if [ -f "$SCRIPTS_REQ" ]; then
646
+ local SCRIPTS_LOG="$LOG_DIR/install-scripts.log"
647
+ print_info "Installing %USERPROFILE%/.claude/scripts dependencies..."
648
+
649
+ local pkg_success=0
650
+ local pkg_fail=0
651
+ while IFS= read -r line || [[ -n "$line" ]]; do
652
+ [[ "$line" =~ ^#.*$ ]] && continue
653
+ [[ -z "${line// }" ]] && continue
654
+ line="${line%%#*}"
655
+ line="${line%"${line##*[![:space:]]}"}"
656
+ [[ -z "$line" ]] && continue
657
+
658
+ if try_pip_install "$line" "$SCRIPTS_LOG"; then
659
+ pkg_success=$((pkg_success + 1))
660
+ else
661
+ pkg_fail=$((pkg_fail + 1))
662
+ track_failure "optional" "scripts:$line" "Package install failed"
663
+ fi
664
+ done < "$SCRIPTS_REQ"
665
+
666
+ if [[ $pkg_fail -eq 0 ]]; then
667
+ print_success "%USERPROFILE%/.claude/scripts: all $pkg_success packages installed"
668
+ track_success "optional" "scripts"
669
+ else
670
+ print_warning "%USERPROFILE%/.claude/scripts: $pkg_success installed, $pkg_fail failed"
671
+ fi
672
+ fi
673
+
674
+ # Print installation summary (brief - final report comes later)
675
+ print_header "Python Dependencies Installation Summary"
676
+
677
+ if [ ${#successful_skills[@]} -gt 0 ]; then
678
+ print_success "Successfully installed ${#successful_skills[@]} skill(s)"
679
+ fi
680
+
681
+ if [ ${#failed_skills[@]} -gt 0 ]; then
682
+ print_warning "${#failed_skills[@]} skill(s) had package failures (see final report)"
683
+ # Don't exit 1 - track failures instead and continue
684
+ elif [ ${#successful_skills[@]} -eq 0 ]; then
685
+ print_warning "No skill requirements.txt files found"
686
+ else
687
+ print_success "All Python dependencies installed successfully"
688
+ fi
689
+
690
+ deactivate
691
+ }
692
+
693
+ # Verify installations
694
+ verify_installations() {
695
+ print_header "Verifying Installations"
696
+
697
+ # FFmpeg
698
+ if command_exists ffmpeg; then
699
+ print_success "FFmpeg is available"
700
+ else
701
+ print_warning "FFmpeg is not available"
702
+ fi
703
+
704
+ # ImageMagick (check both magick and convert - older versions use convert)
705
+ if command_exists magick || command_exists convert; then
706
+ print_success "ImageMagick is available"
707
+ else
708
+ print_warning "ImageMagick is not available"
709
+ fi
710
+
711
+ # Node.js & npm
712
+ if command_exists node; then
713
+ print_success "Node.js is available"
714
+ else
715
+ print_warning "Node.js is not available"
716
+ fi
717
+
718
+ if command_exists npm; then
719
+ print_success "npm is available"
720
+ else
721
+ print_warning "npm is not available"
722
+ fi
723
+
724
+ declare -a npm_packages=(
725
+ "rmbg"
726
+ "pnpm"
727
+ "wrangler"
728
+ "repomix"
729
+ )
730
+
731
+ for package in "${npm_packages[@]}"; do
732
+ if command_exists "$package"; then
733
+ print_success "$package CLI is available"
734
+ else
735
+ print_warning "$package CLI is not available"
736
+ fi
737
+ done
738
+
739
+ # Check Python packages
740
+ if [ -d "$VENV_DIR" ]; then
741
+ source "$VENV_DIR/bin/activate"
742
+ if python -c "import google.genai" 2>/dev/null; then
743
+ print_success "google-genai Python package is available"
744
+ else
745
+ print_warning "google-genai Python package is not available"
746
+ fi
747
+ deactivate
748
+ fi
749
+ }
750
+
751
+ # ============================================================================
752
+ # Final Report Functions
753
+ # ============================================================================
754
+
755
+ generate_remediation_commands() {
756
+ local has_sudo_skipped=false
757
+ local has_python_failed=false
758
+
759
+ # Check if we have sudo-skipped packages
760
+ if [[ ${#SKIPPED_SUDO[@]} -gt 0 ]]; then
761
+ has_sudo_skipped=true
762
+ fi
763
+
764
+ # Check if we have Python package failures
765
+ if [[ ${#FAILED_OPTIONAL[@]} -gt 0 ]]; then
766
+ has_python_failed=true
767
+ fi
768
+
769
+ if [[ "$has_sudo_skipped" == "false" ]] && [[ "$has_python_failed" == "false" ]]; then
770
+ return 0
771
+ fi
772
+
773
+ echo ""
774
+ echo -e "${BLUE}---------------------------------------------------${NC}"
775
+ echo -e "${BLUE}Manual Installation Commands:${NC}"
776
+ echo -e "${BLUE}---------------------------------------------------${NC}"
777
+ echo ""
778
+
779
+ if [[ "$has_sudo_skipped" == "true" ]]; then
780
+ echo "# System packages (requires sudo):"
781
+ echo "sudo apt-get update"
782
+ for item in "${SKIPPED_SUDO[@]}"; do
783
+ local pkg="${item%%:*}"
784
+ case "$pkg" in
785
+ FFmpeg) echo "sudo apt-get install -y ffmpeg" ;;
786
+ ImageMagick) echo "sudo apt-get install -y imagemagick" ;;
787
+ *) echo "# $pkg: see documentation" ;;
788
+ esac
789
+ done
790
+ echo ""
791
+ fi
792
+
793
+ if [[ "$has_python_failed" == "true" ]]; then
794
+ echo "# Python packages (may require build tools):"
795
+ if [[ "$OS" == "linux" ]]; then
796
+ echo "sudo apt-get install -y gcc python3-dev libjpeg-dev zlib1g-dev"
797
+ elif [[ "$OS" == "macos" ]]; then
798
+ echo "xcode-select --install"
799
+ echo "brew install jpeg libpng"
800
+ fi
801
+ echo "source $VENV_DIR/bin/activate"
802
+
803
+ for item in "${FAILED_OPTIONAL[@]}"; do
804
+ local pkg="${item%%:*}"
805
+ # Extract package name from skill:package format
806
+ if [[ "$pkg" == *":"* ]]; then
807
+ pkg="${pkg#*:}"
808
+ fi
809
+ echo "pip install $pkg"
810
+ done
811
+ echo ""
812
+ fi
813
+ }
814
+
815
+ print_final_report() {
816
+ echo ""
817
+ echo -e "${BLUE}===================================================${NC}"
818
+ echo -e "${BLUE} Installation Report${NC}"
819
+ echo -e "${BLUE}===================================================${NC}"
820
+ echo ""
821
+
822
+ # Installed section
823
+ local installed_count=$((${#INSTALLED_CRITICAL[@]} + ${#INSTALLED_OPTIONAL[@]}))
824
+ if [[ $installed_count -gt 0 ]]; then
825
+ echo -e "${GREEN}Installed ($installed_count):${NC}"
826
+ for item in "${INSTALLED_CRITICAL[@]}"; do
827
+ echo -e " ${GREEN}✓${NC} $item"
828
+ done
829
+ for item in "${INSTALLED_OPTIONAL[@]}"; do
830
+ echo -e " ${GREEN}✓${NC} $item"
831
+ done
832
+ echo ""
833
+ fi
834
+
835
+ # Skipped section
836
+ if [[ ${#SKIPPED_SUDO[@]} -gt 0 ]]; then
837
+ echo -e "${YELLOW}Skipped (${#SKIPPED_SUDO[@]}):${NC}"
838
+ for item in "${SKIPPED_SUDO[@]}"; do
839
+ local name="${item%%:*}"
840
+ local reason="${item#*:}"
841
+ echo -e " ${YELLOW}~${NC} $name (${reason# })"
842
+ done
843
+ echo ""
844
+ fi
845
+
846
+ # Degraded/Failed section
847
+ if [[ ${#FAILED_OPTIONAL[@]} -gt 0 ]]; then
848
+ echo -e "${RED}Degraded (${#FAILED_OPTIONAL[@]}):${NC}"
849
+ for item in "${FAILED_OPTIONAL[@]}"; do
850
+ local name="${item%%:*}"
851
+ local reason="${item#*:}"
852
+ echo -e " ${RED}!${NC} $name (${reason# })"
853
+ done
854
+ echo ""
855
+ fi
856
+
857
+ # Remediation commands
858
+ generate_remediation_commands
859
+
860
+ # Exit status line
861
+ echo -e "${BLUE}===================================================${NC}"
862
+ case $FINAL_EXIT_CODE in
863
+ 0) echo -e " ${GREEN}Exit: 0 (success - all dependencies installed)${NC}" ;;
864
+ 1) echo -e " ${RED}Exit: 1 (failed - critical dependencies missing)${NC}" ;;
865
+ 2) echo -e " ${YELLOW}Exit: 2 (partial - some optional deps failed)${NC}" ;;
866
+ esac
867
+ echo -e "${BLUE}===================================================${NC}"
868
+ echo ""
869
+ }
870
+
871
+ # Escape string for JSON (handle all special chars)
872
+ json_escape() {
873
+ printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g' | tr '\n' ' ' | tr '\r' ' ' | tr '\t' ' '
874
+ }
875
+
876
+ # Write structured error summary for CLI to parse
877
+ write_error_summary() {
878
+ # Only write if there are failures
879
+ if [[ $FINAL_EXIT_CODE -eq 0 ]]; then
880
+ return 0
881
+ fi
882
+
883
+ # Write to a file that CLI can read
884
+ local summary_file="$SCRIPT_DIR/.install-error-summary.json"
885
+
886
+ # Build JSON arrays carefully for bash compatibility
887
+ local critical_json="[]"
888
+ local optional_json="[]"
889
+ local skipped_json="[]"
890
+
891
+ if [[ ${#FAILED_OPTIONAL[@]} -gt 0 ]]; then
892
+ optional_json="["
893
+ local first=true
894
+ for item in "${FAILED_OPTIONAL[@]}"; do
895
+ if [[ "$first" == "true" ]]; then
896
+ first=false
897
+ else
898
+ optional_json+=","
899
+ fi
900
+ optional_json+="\"$(json_escape "$item")\""
901
+ done
902
+ optional_json+="]"
903
+ fi
904
+
905
+ if [[ ${#SKIPPED_SUDO[@]} -gt 0 ]]; then
906
+ skipped_json="["
907
+ local first=true
908
+ for item in "${SKIPPED_SUDO[@]}"; do
909
+ if [[ "$first" == "true" ]]; then
910
+ first=false
911
+ else
912
+ skipped_json+=","
913
+ fi
914
+ skipped_json+="\"$(json_escape "$item")\""
915
+ done
916
+ skipped_json+="]"
917
+ fi
918
+
919
+ cat > "$summary_file" << EOF
920
+ {
921
+ "exit_code": $FINAL_EXIT_CODE,
922
+ "timestamp": "$(date -Iseconds 2>/dev/null || date -u +%Y-%m-%dT%H:%M:%SZ)",
923
+ "critical_failures": $critical_json,
924
+ "optional_failures": $optional_json,
925
+ "skipped": $skipped_json,
926
+ "remediation": {
927
+ "sudo_packages": "sudo apt-get install -y ffmpeg imagemagick",
928
+ "build_tools": "sudo apt-get install -y gcc python3-dev libjpeg-dev zlib1g-dev",
929
+ "pip_retry": "source $VENV_DIR/bin/activate && pip install <package>"
930
+ }
931
+ }
932
+ EOF
933
+
934
+ print_info "Error summary written to: $summary_file"
935
+ }
936
+
937
+ # Print usage instructions (now just brief tips)
938
+ print_usage() {
939
+ echo -e "${GREEN}To use the Python virtual environment:${NC}"
940
+ echo -e " source %USERPROFILE%/.claude/skills/.venv/bin/activate"
941
+ echo ""
942
+ echo -e "${BLUE}For more information, see:${NC}"
943
+ echo -e " %USERPROFILE%/.claude/skills/INSTALLATION.md"
944
+ echo ""
945
+ }
946
+
947
+ # Main installation flow
948
+ main() {
949
+ echo "" # Just add spacing, don't clear terminal
950
+ print_header "Claude Code Skills Installation"
951
+ print_info "OS: $OS"
952
+ print_info "Script directory: $SCRIPT_DIR"
953
+ if [[ "$WITH_SUDO" == "true" ]]; then
954
+ print_info "Mode: with sudo (--with-sudo)"
955
+ else
956
+ print_info "Mode: without sudo (system packages will be skipped)"
957
+ fi
958
+ if [[ "$RESUME_MODE" == "true" ]]; then
959
+ print_info "Mode: resuming previous installation"
960
+ fi
961
+ echo ""
962
+
963
+ if [[ "$OS" == "unknown" ]]; then
964
+ print_error "Unsupported operating system"
965
+ exit 1
966
+ fi
967
+
968
+ # Confirm installation (skip if --yes flag or NON_INTERACTIVE env is set)
969
+ if [[ "$SKIP_CONFIRM" == "false" ]]; then
970
+ read -p "This will install system packages and Node.js dependencies. Continue? (y/N) " -n 1 -r
971
+ echo
972
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
973
+ print_warning "Installation cancelled"
974
+ exit 0
975
+ fi
976
+ else
977
+ print_info "Auto-confirming installation (--yes flag or NON_INTERACTIVE mode)"
978
+ fi
979
+
980
+ # Initialize state tracking
981
+ init_state
982
+
983
+ # Phase 1: System deps
984
+ if phase_done "system_deps"; then
985
+ print_success "System deps: already processed (resume)"
986
+ else
987
+ update_phase "system_deps" "running"
988
+ check_package_manager
989
+ install_system_deps
990
+ update_phase "system_deps" "done"
991
+ fi
992
+
993
+ # Phase 2: Node deps
994
+ if phase_done "node_deps"; then
995
+ print_success "Node deps: already installed (resume)"
996
+ else
997
+ update_phase "node_deps" "running"
998
+ install_node_deps
999
+ update_phase "node_deps" "done"
1000
+ fi
1001
+
1002
+ # Phase 3: Python env
1003
+ if phase_done "python_env"; then
1004
+ print_success "Python env: already set up (resume)"
1005
+ else
1006
+ update_phase "python_env" "running"
1007
+ setup_python_env
1008
+ update_phase "python_env" "done"
1009
+ fi
1010
+
1011
+ # Phase 4: Verify
1012
+ update_phase "verify" "running"
1013
+ verify_installations
1014
+ update_phase "verify" "done"
1015
+
1016
+ # Print final report with all tracking info
1017
+ print_final_report
1018
+ print_usage
1019
+
1020
+ # Write error summary for CLI to parse
1021
+ write_error_summary
1022
+
1023
+ # Clean state on complete success
1024
+ if [[ "$FINAL_EXIT_CODE" -eq 0 ]]; then
1025
+ clean_state
1026
+ fi
1027
+
1028
+ exit $FINAL_EXIT_CODE
1029
+ }
1030
+
1031
+ # Run main function
1032
+ main