@thanhvn14/csvibe 0.1.4 → 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 (392) 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 +2 -0
  381. package/dist/config/constants.d.ts.map +1 -1
  382. package/dist/config/constants.js +4 -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/package.json +3 -1
@@ -0,0 +1,596 @@
1
+ /**
2
+ * Dashboard Controls
3
+ * Client-side sorting, filtering, and search for plans dashboard
4
+ */
5
+ (function() {
6
+ 'use strict';
7
+
8
+ // State
9
+ const state = {
10
+ sort: 'date-desc',
11
+ filter: 'all',
12
+ search: '',
13
+ view: 'kanban' // 'kanban' or 'grid'
14
+ };
15
+
16
+ // Status column config
17
+ const STATUS_COLUMNS = [
18
+ { id: 'pending', label: 'Pending', color: 'pending' },
19
+ { id: 'in-progress', label: 'In Progress', color: 'in-progress' },
20
+ { id: 'in-review', label: 'In Review', color: 'in-review' },
21
+ { id: 'completed', label: 'Done', color: 'completed' },
22
+ { id: 'cancelled', label: 'Cancelled', color: 'cancelled' }
23
+ ];
24
+
25
+ // Elements
26
+ let allPlans = [];
27
+ let grid = null;
28
+ let kanbanBoard = null;
29
+ let resultCount = null;
30
+ let emptyState = null;
31
+ let srAnnounce = null;
32
+
33
+ /**
34
+ * Initialize dashboard
35
+ */
36
+ function init() {
37
+ allPlans = window.__plans || [];
38
+ grid = document.querySelector('.plans-grid');
39
+ kanbanBoard = document.querySelector('.kanban-board');
40
+ resultCount = document.querySelector('.result-count');
41
+ emptyState = document.querySelector('.empty-state');
42
+ srAnnounce = document.getElementById('sr-announce');
43
+
44
+ // Mark as loaded
45
+ document.body.classList.add('plans-loaded');
46
+
47
+ // Show empty state if no plans
48
+ if (!allPlans.length) {
49
+ if (emptyState) emptyState.hidden = false;
50
+ return;
51
+ }
52
+
53
+ // Parse URL state
54
+ parseURL();
55
+
56
+ // Bind events
57
+ bindEvents();
58
+
59
+ // Initial render
60
+ applyFiltersAndSort();
61
+
62
+ // Setup keyboard navigation
63
+ setupKeyboardNav();
64
+
65
+ // Setup theme toggle
66
+ setupThemeToggle();
67
+
68
+ // Setup view toggle
69
+ setupViewToggle();
70
+ }
71
+
72
+ /**
73
+ * Bind event listeners
74
+ */
75
+ function bindEvents() {
76
+ // Search input with debounce
77
+ const searchInput = document.getElementById('plan-search');
78
+ if (searchInput) {
79
+ let debounceTimer;
80
+ searchInput.addEventListener('input', (e) => {
81
+ clearTimeout(debounceTimer);
82
+ debounceTimer = setTimeout(() => {
83
+ state.search = e.target.value.toLowerCase().trim();
84
+ applyFiltersAndSort();
85
+ }, 300);
86
+ });
87
+
88
+ // Clear search on Escape
89
+ searchInput.addEventListener('keydown', (e) => {
90
+ if (e.key === 'Escape') {
91
+ searchInput.value = '';
92
+ state.search = '';
93
+ applyFiltersAndSort();
94
+ }
95
+ });
96
+ }
97
+
98
+ // Sort select
99
+ const sortSelect = document.getElementById('sort-select');
100
+ if (sortSelect) {
101
+ sortSelect.addEventListener('change', (e) => {
102
+ state.sort = e.target.value;
103
+ applyFiltersAndSort();
104
+ });
105
+ }
106
+
107
+ // Filter pills
108
+ document.querySelectorAll('.filter-pill').forEach(pill => {
109
+ pill.addEventListener('click', () => {
110
+ // Update active state
111
+ document.querySelectorAll('.filter-pill').forEach(p => {
112
+ p.classList.remove('active');
113
+ p.setAttribute('aria-pressed', 'false');
114
+ });
115
+ pill.classList.add('active');
116
+ pill.setAttribute('aria-pressed', 'true');
117
+
118
+ state.filter = pill.dataset.filter;
119
+ applyFiltersAndSort();
120
+ });
121
+ });
122
+
123
+ // Card click to navigate
124
+ grid?.addEventListener('click', (e) => {
125
+ const card = e.target.closest('.plan-card');
126
+ if (card && !e.target.closest('.view-btn')) {
127
+ const link = card.querySelector('.view-btn');
128
+ if (link) link.click();
129
+ }
130
+ });
131
+ }
132
+
133
+ /**
134
+ * Apply filters and sorting
135
+ */
136
+ function applyFiltersAndSort() {
137
+ let filtered = allPlans.slice();
138
+
139
+ // Filter by status
140
+ if (state.filter !== 'all') {
141
+ filtered = filtered.filter(p => p.status === state.filter);
142
+ }
143
+
144
+ // Filter by search
145
+ if (state.search) {
146
+ filtered = filtered.filter(p =>
147
+ p.name.toLowerCase().includes(state.search) ||
148
+ p.id.toLowerCase().includes(state.search)
149
+ );
150
+ }
151
+
152
+ // Sort
153
+ filtered.sort((a, b) => {
154
+ switch (state.sort) {
155
+ case 'date-desc':
156
+ return new Date(b.lastModified) - new Date(a.lastModified);
157
+ case 'date-asc':
158
+ return new Date(a.lastModified) - new Date(b.lastModified);
159
+ case 'name-asc':
160
+ return a.name.localeCompare(b.name);
161
+ case 'name-desc':
162
+ return b.name.localeCompare(a.name);
163
+ case 'progress-desc':
164
+ return b.progress - a.progress;
165
+ case 'progress-asc':
166
+ return a.progress - b.progress;
167
+ default:
168
+ return 0;
169
+ }
170
+ });
171
+
172
+ renderGrid(filtered);
173
+
174
+ // Also update kanban if in kanban view
175
+ if (state.view === 'kanban') {
176
+ renderKanbanBoard(allPlans); // Kanban uses all plans grouped by status
177
+ }
178
+
179
+ updateURL();
180
+ announce(`Showing ${filtered.length} plan${filtered.length !== 1 ? 's' : ''}`);
181
+ }
182
+
183
+ /**
184
+ * Render grid with filtered plans
185
+ */
186
+ function renderGrid(plans) {
187
+ const visibleIds = new Set(plans.map(p => p.id));
188
+
189
+ // Hide/show cards and set order
190
+ document.querySelectorAll('.plan-card').forEach(card => {
191
+ const id = card.dataset.id;
192
+ const isVisible = visibleIds.has(id);
193
+ card.style.display = isVisible ? '' : 'none';
194
+
195
+ if (isVisible) {
196
+ const index = plans.findIndex(p => p.id === id);
197
+ card.style.order = index;
198
+ }
199
+ });
200
+
201
+ // Update count
202
+ if (resultCount) {
203
+ resultCount.innerHTML = `Showing <strong>${plans.length}</strong> plan${plans.length !== 1 ? 's' : ''}`;
204
+ }
205
+
206
+ // Show/hide empty state
207
+ if (emptyState) {
208
+ emptyState.hidden = plans.length > 0;
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Parse URL parameters
214
+ */
215
+ function parseURL() {
216
+ const params = new URLSearchParams(window.location.search);
217
+
218
+ if (params.has('sort')) {
219
+ state.sort = params.get('sort');
220
+ }
221
+ if (params.has('filter')) {
222
+ state.filter = params.get('filter');
223
+ }
224
+ if (params.has('q')) {
225
+ state.search = params.get('q');
226
+ }
227
+
228
+ // Update controls to match state
229
+ const sortSelect = document.getElementById('sort-select');
230
+ if (sortSelect) sortSelect.value = state.sort;
231
+
232
+ const searchInput = document.getElementById('plan-search');
233
+ if (searchInput) searchInput.value = state.search;
234
+
235
+ document.querySelectorAll('.filter-pill').forEach(p => {
236
+ const isActive = p.dataset.filter === state.filter;
237
+ p.classList.toggle('active', isActive);
238
+ p.setAttribute('aria-pressed', String(isActive));
239
+ });
240
+ }
241
+
242
+ /**
243
+ * Update URL with current state
244
+ */
245
+ function updateURL() {
246
+ const params = new URLSearchParams();
247
+
248
+ if (state.sort !== 'date-desc') params.set('sort', state.sort);
249
+ if (state.filter !== 'all') params.set('filter', state.filter);
250
+ if (state.search) params.set('q', state.search);
251
+
252
+ const url = params.toString()
253
+ ? `${window.location.pathname}?${params}`
254
+ : window.location.pathname;
255
+
256
+ history.replaceState(null, '', url);
257
+ }
258
+
259
+ /**
260
+ * Announce message to screen readers
261
+ */
262
+ function announce(message) {
263
+ if (!srAnnounce) return;
264
+ srAnnounce.textContent = '';
265
+ // Force reflow
266
+ void srAnnounce.offsetHeight;
267
+ srAnnounce.textContent = message;
268
+ }
269
+
270
+ /**
271
+ * Setup keyboard navigation for cards
272
+ */
273
+ function setupKeyboardNav() {
274
+ grid?.addEventListener('keydown', (e) => {
275
+ const cards = [...document.querySelectorAll('.plan-card:not([style*="display: none"])')];
276
+ const current = document.activeElement;
277
+ const index = cards.indexOf(current);
278
+
279
+ if (index === -1) return;
280
+
281
+ let next;
282
+ switch (e.key) {
283
+ case 'ArrowRight':
284
+ case 'ArrowDown':
285
+ e.preventDefault();
286
+ next = cards[index + 1] || cards[0];
287
+ break;
288
+ case 'ArrowLeft':
289
+ case 'ArrowUp':
290
+ e.preventDefault();
291
+ next = cards[index - 1] || cards[cards.length - 1];
292
+ break;
293
+ case 'Enter':
294
+ case ' ':
295
+ e.preventDefault();
296
+ const link = current.querySelector('.view-btn');
297
+ if (link) link.click();
298
+ break;
299
+ case 'Home':
300
+ e.preventDefault();
301
+ next = cards[0];
302
+ break;
303
+ case 'End':
304
+ e.preventDefault();
305
+ next = cards[cards.length - 1];
306
+ break;
307
+ }
308
+
309
+ if (next) next.focus();
310
+ });
311
+ }
312
+
313
+ /**
314
+ * Setup theme toggle
315
+ */
316
+ function setupThemeToggle() {
317
+ const toggle = document.getElementById('theme-toggle');
318
+ if (!toggle) return;
319
+
320
+ // Check saved preference
321
+ const savedTheme = localStorage.getItem('theme');
322
+ const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
323
+ const initialTheme = savedTheme || (prefersDark ? 'dark' : 'light');
324
+
325
+ document.documentElement.setAttribute('data-theme', initialTheme);
326
+
327
+ toggle.addEventListener('click', () => {
328
+ const current = document.documentElement.getAttribute('data-theme');
329
+ const next = current === 'dark' ? 'light' : 'dark';
330
+ document.documentElement.setAttribute('data-theme', next);
331
+ localStorage.setItem('theme', next);
332
+ announce(`Theme changed to ${next} mode`);
333
+ });
334
+ }
335
+
336
+ /**
337
+ * Setup view toggle (Kanban/Grid)
338
+ */
339
+ function setupViewToggle() {
340
+ const toggleBtns = document.querySelectorAll('.view-toggle-btn');
341
+ if (!toggleBtns.length) return;
342
+
343
+ // Restore saved view preference
344
+ const savedView = localStorage.getItem('dashboard-view') || 'kanban';
345
+ state.view = savedView;
346
+ updateViewMode();
347
+
348
+ toggleBtns.forEach(btn => {
349
+ btn.addEventListener('click', () => {
350
+ const view = btn.dataset.view;
351
+ if (view === state.view) return;
352
+
353
+ state.view = view;
354
+ localStorage.setItem('dashboard-view', view);
355
+ updateViewMode();
356
+ announce(`Switched to ${view} view`);
357
+ });
358
+ });
359
+ }
360
+
361
+ /**
362
+ * Update view mode (toggle between kanban and grid)
363
+ */
364
+ function updateViewMode() {
365
+ const body = document.body;
366
+
367
+ // Update toggle buttons
368
+ document.querySelectorAll('.view-toggle-btn').forEach(btn => {
369
+ const isActive = btn.dataset.view === state.view;
370
+ btn.classList.toggle('active', isActive);
371
+ btn.setAttribute('aria-pressed', String(isActive));
372
+ });
373
+
374
+ // Toggle view classes
375
+ if (state.view === 'grid') {
376
+ body.classList.add('view-mode-grid');
377
+ } else {
378
+ body.classList.remove('view-mode-grid');
379
+ }
380
+
381
+ // Re-render kanban when switching to kanban view
382
+ if (state.view === 'kanban') {
383
+ renderKanbanBoard(getFilteredPlans());
384
+ }
385
+ }
386
+
387
+ /**
388
+ * Get filtered and sorted plans
389
+ */
390
+ function getFilteredPlans() {
391
+ let filtered = allPlans.slice();
392
+
393
+ // Filter by status (only for grid view, kanban shows all columns)
394
+ if (state.filter !== 'all' && state.view === 'grid') {
395
+ filtered = filtered.filter(p => p.status === state.filter);
396
+ }
397
+
398
+ // Filter by search
399
+ if (state.search) {
400
+ filtered = filtered.filter(p =>
401
+ p.name.toLowerCase().includes(state.search) ||
402
+ p.id.toLowerCase().includes(state.search)
403
+ );
404
+ }
405
+
406
+ // Sort
407
+ filtered.sort((a, b) => {
408
+ switch (state.sort) {
409
+ case 'date-desc':
410
+ return new Date(b.lastModified) - new Date(a.lastModified);
411
+ case 'date-asc':
412
+ return new Date(a.lastModified) - new Date(b.lastModified);
413
+ case 'name-asc':
414
+ return a.name.localeCompare(b.name);
415
+ case 'name-desc':
416
+ return b.name.localeCompare(a.name);
417
+ case 'progress-desc':
418
+ return b.progress - a.progress;
419
+ case 'progress-asc':
420
+ return a.progress - b.progress;
421
+ default:
422
+ return 0;
423
+ }
424
+ });
425
+
426
+ return filtered;
427
+ }
428
+
429
+ /**
430
+ * Render kanban board with plans grouped by status
431
+ */
432
+ function renderKanbanBoard(plans) {
433
+ if (!kanbanBoard) return;
434
+
435
+ // Group plans by status
436
+ const grouped = {};
437
+ STATUS_COLUMNS.forEach(col => {
438
+ grouped[col.id] = [];
439
+ });
440
+
441
+ // Apply search filter for kanban
442
+ let filteredPlans = plans;
443
+ if (state.search) {
444
+ filteredPlans = plans.filter(p =>
445
+ p.name.toLowerCase().includes(state.search) ||
446
+ p.id.toLowerCase().includes(state.search)
447
+ );
448
+ }
449
+
450
+ filteredPlans.forEach(plan => {
451
+ const status = plan.status || 'pending';
452
+ if (grouped[status]) {
453
+ grouped[status].push(plan);
454
+ } else {
455
+ grouped['pending'].push(plan);
456
+ }
457
+ });
458
+
459
+ // Generate column HTML
460
+ const columnsHtml = STATUS_COLUMNS.map(col => {
461
+ const columnPlans = grouped[col.id];
462
+ const cardsHtml = columnPlans.length > 0
463
+ ? columnPlans.map(plan => renderKanbanCard(plan)).join('')
464
+ : `<div class="kanban-empty">
465
+ <svg class="kanban-empty-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
466
+ <rect x="3" y="3" width="18" height="18" rx="2"/>
467
+ <path d="M9 9h6M9 13h6M9 17h4"/>
468
+ </svg>
469
+ <span>No plans</span>
470
+ </div>`;
471
+
472
+ return `
473
+ <div class="kanban-column" data-status="${col.id}">
474
+ <div class="kanban-column-header">
475
+ <div class="kanban-column-title">
476
+ <span class="kanban-status-dot ${col.color}"></span>
477
+ <span>${col.label}</span>
478
+ </div>
479
+ <span class="kanban-column-count">${columnPlans.length}</span>
480
+ </div>
481
+ <div class="kanban-cards">
482
+ ${cardsHtml}
483
+ </div>
484
+ </div>
485
+ `;
486
+ }).join('');
487
+
488
+ kanbanBoard.innerHTML = columnsHtml;
489
+ }
490
+
491
+ /**
492
+ * Render a single kanban card (enhanced with details)
493
+ */
494
+ function renderKanbanCard(plan) {
495
+ const progressPct = Math.round(plan.progress || 0);
496
+ const dateStr = formatDate(plan.lastModified);
497
+
498
+ // Priority badge
499
+ let priorityHtml = '';
500
+ if (plan.priority) {
501
+ const p = String(plan.priority).toUpperCase();
502
+ let priorityClass = '';
503
+ if (p === 'P1' || p === 'HIGH' || p === 'CRITICAL') priorityClass = 'priority-high';
504
+ else if (p === 'P2' || p === 'MEDIUM' || p === 'NORMAL') priorityClass = 'priority-medium';
505
+ else if (p === 'P3' || p === 'LOW') priorityClass = 'priority-low';
506
+ if (priorityClass) {
507
+ priorityHtml = `<span class="kanban-card-priority ${priorityClass}">${escapeHtml(plan.priority)}</span>`;
508
+ }
509
+ }
510
+
511
+ // Description (truncated)
512
+ let descriptionHtml = '';
513
+ if (plan.description) {
514
+ const desc = plan.description.length > 80 ? plan.description.slice(0, 77) + '...' : plan.description;
515
+ descriptionHtml = `<p class="kanban-card-description">${escapeHtml(desc)}</p>`;
516
+ }
517
+
518
+ // Tags (max 3 visible)
519
+ let tagsHtml = '';
520
+ if (plan.tags && Array.isArray(plan.tags) && plan.tags.length > 0) {
521
+ const visibleTags = plan.tags.slice(0, 3);
522
+ const hiddenCount = plan.tags.length - 3;
523
+ tagsHtml = '<div class="kanban-card-tags">';
524
+ tagsHtml += visibleTags.map(tag => `<span class="kanban-card-tag">${escapeHtml(tag)}</span>`).join('');
525
+ if (hiddenCount > 0) {
526
+ tagsHtml += `<span class="kanban-card-tag tag-more">+${hiddenCount}</span>`;
527
+ }
528
+ tagsHtml += '</div>';
529
+ }
530
+
531
+ // Footer with effort and phases
532
+ let footerHtml = '';
533
+ const effortHtml = plan.totalEffortFormatted
534
+ ? `<span class="kanban-card-effort"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>${escapeHtml(plan.totalEffortFormatted)}</span>`
535
+ : '';
536
+ const phasesHtml = plan.phasesTotal
537
+ ? `<span class="kanban-card-phases">${plan.phasesTotal} phases</span>`
538
+ : '';
539
+ if (effortHtml || phasesHtml) {
540
+ footerHtml = `<div class="kanban-card-footer">${effortHtml}${phasesHtml}</div>`;
541
+ }
542
+
543
+ return `
544
+ <a href="/view?file=${encodeURIComponent(plan.path)}" class="kanban-card" data-id="${plan.id}">
545
+ <div class="kanban-card-header">
546
+ <h4 class="kanban-card-title">${escapeHtml(plan.name)}</h4>
547
+ ${priorityHtml}
548
+ </div>
549
+ ${descriptionHtml}
550
+ <div class="kanban-card-meta">
551
+ <div class="kanban-card-progress">
552
+ <div class="kanban-card-progress-bar">
553
+ <div class="kanban-card-progress-fill" style="width: ${progressPct}%"></div>
554
+ </div>
555
+ <span>${progressPct}%</span>
556
+ </div>
557
+ <span class="kanban-card-date">${dateStr}</span>
558
+ </div>
559
+ ${tagsHtml}
560
+ ${footerHtml}
561
+ </a>
562
+ `;
563
+ }
564
+
565
+ /**
566
+ * Format date for display
567
+ */
568
+ function formatDate(dateStr) {
569
+ if (!dateStr) return '';
570
+ const date = new Date(dateStr);
571
+ const now = new Date();
572
+ const diffDays = Math.floor((now - date) / (1000 * 60 * 60 * 24));
573
+
574
+ if (diffDays === 0) return 'Today';
575
+ if (diffDays === 1) return 'Yesterday';
576
+ if (diffDays < 7) return `${diffDays}d ago`;
577
+
578
+ return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
579
+ }
580
+
581
+ /**
582
+ * Escape HTML to prevent XSS
583
+ */
584
+ function escapeHtml(str) {
585
+ const div = document.createElement('div');
586
+ div.textContent = str;
587
+ return div.innerHTML;
588
+ }
589
+
590
+ // Initialize on DOM ready
591
+ if (document.readyState === 'loading') {
592
+ document.addEventListener('DOMContentLoaded', init);
593
+ } else {
594
+ init();
595
+ }
596
+ })();