thanh-kit 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (862) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +252 -0
  3. package/bin/ak.js +2 -0
  4. package/dist/index.js +3829 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +75 -0
  7. package/templates/AGENTS.md +104 -0
  8. package/templates/README.md +241 -0
  9. package/templates/agents/README.md +172 -0
  10. package/templates/agents/brainstormer.md +108 -0
  11. package/templates/agents/code-reviewer.md +172 -0
  12. package/templates/agents/code-simplifier.md +104 -0
  13. package/templates/agents/copywriter.md +113 -0
  14. package/templates/agents/database-admin.md +97 -0
  15. package/templates/agents/debugger.md +142 -0
  16. package/templates/agents/docs-manager.md +158 -0
  17. package/templates/agents/fullstack-developer.md +95 -0
  18. package/templates/agents/git-manager.md +394 -0
  19. package/templates/agents/journal-writer.md +119 -0
  20. package/templates/agents/mcp-manager.md +93 -0
  21. package/templates/agents/planner.md +113 -0
  22. package/templates/agents/project-manager.md +129 -0
  23. package/templates/agents/researcher.md +43 -0
  24. package/templates/agents/scout-external.md +146 -0
  25. package/templates/agents/scout.md +260 -0
  26. package/templates/agents/tester.md +110 -0
  27. package/templates/agents/ui-ux-designer.md +238 -0
  28. package/templates/commands/README.md +251 -0
  29. package/templates/commands/ask.md +56 -0
  30. package/templates/commands/bootstrap/auto/fast.md +111 -0
  31. package/templates/commands/bootstrap/auto/parallel.md +66 -0
  32. package/templates/commands/bootstrap/auto.md +115 -0
  33. package/templates/commands/bootstrap.md +137 -0
  34. package/templates/commands/brainstorm.md +74 -0
  35. package/templates/commands/build.md +39 -0
  36. package/templates/commands/checkpoint.md +156 -0
  37. package/templates/commands/ck-help.md +113 -0
  38. package/templates/commands/code/auto.md +170 -0
  39. package/templates/commands/code/no-test.md +158 -0
  40. package/templates/commands/code/parallel.md +55 -0
  41. package/templates/commands/code-simplifier.md +71 -0
  42. package/templates/commands/code.md +176 -0
  43. package/templates/commands/coding-level.md +48 -0
  44. package/templates/commands/compact.md +57 -0
  45. package/templates/commands/content/cro.md +43 -0
  46. package/templates/commands/content/enhance.md +14 -0
  47. package/templates/commands/content/fast.md +13 -0
  48. package/templates/commands/content/good.md +16 -0
  49. package/templates/commands/context.md +48 -0
  50. package/templates/commands/cook/auto/fast.md +26 -0
  51. package/templates/commands/cook/auto/parallel.md +49 -0
  52. package/templates/commands/cook/auto.md +15 -0
  53. package/templates/commands/cook/fast.md +47 -0
  54. package/templates/commands/cook/hard.md +80 -0
  55. package/templates/commands/cook/parallel.md +90 -0
  56. package/templates/commands/cook.md +105 -0
  57. package/templates/commands/create-feature.md +48 -0
  58. package/templates/commands/db-migrate.md +52 -0
  59. package/templates/commands/debug.md +13 -0
  60. package/templates/commands/design/3d.md +83 -0
  61. package/templates/commands/design/describe.md +23 -0
  62. package/templates/commands/design/fast.md +31 -0
  63. package/templates/commands/design/good.md +35 -0
  64. package/templates/commands/design/screenshot.md +34 -0
  65. package/templates/commands/design/video.md +34 -0
  66. package/templates/commands/docs/init.md +39 -0
  67. package/templates/commands/docs/summarize.md +31 -0
  68. package/templates/commands/docs/update.md +57 -0
  69. package/templates/commands/feature.md +62 -0
  70. package/templates/commands/fix/ci.md +17 -0
  71. package/templates/commands/fix/fast.md +19 -0
  72. package/templates/commands/fix/hard.md +39 -0
  73. package/templates/commands/fix/logs.md +26 -0
  74. package/templates/commands/fix/parallel.md +54 -0
  75. package/templates/commands/fix/test.md +20 -0
  76. package/templates/commands/fix/types.md +9 -0
  77. package/templates/commands/fix/ui.md +48 -0
  78. package/templates/commands/fix-issue.md +177 -0
  79. package/templates/commands/fix.md +43 -0
  80. package/templates/commands/generate-dto.md +67 -0
  81. package/templates/commands/git/cm.md +5 -0
  82. package/templates/commands/git/cp.md +4 -0
  83. package/templates/commands/git/merge.md +40 -0
  84. package/templates/commands/git/pr.md +48 -0
  85. package/templates/commands/integrate/polar.md +28 -0
  86. package/templates/commands/integrate/sepay.md +28 -0
  87. package/templates/commands/investigate.md +324 -0
  88. package/templates/commands/journal.md +7 -0
  89. package/templates/commands/kanban.md +101 -0
  90. package/templates/commands/lint.md +47 -0
  91. package/templates/commands/migration.md +111 -0
  92. package/templates/commands/performance.md +110 -0
  93. package/templates/commands/plan/archive.md +57 -0
  94. package/templates/commands/plan/ci.md +33 -0
  95. package/templates/commands/plan/cro.md +69 -0
  96. package/templates/commands/plan/fast.md +86 -0
  97. package/templates/commands/plan/hard.md +103 -0
  98. package/templates/commands/plan/parallel.md +152 -0
  99. package/templates/commands/plan/preview.md +40 -0
  100. package/templates/commands/plan/two.md +52 -0
  101. package/templates/commands/plan/validate.md +132 -0
  102. package/templates/commands/plan.md +36 -0
  103. package/templates/commands/pr.md +49 -0
  104. package/templates/commands/preview.md +87 -0
  105. package/templates/commands/release-notes.md +144 -0
  106. package/templates/commands/review/codebase.md +49 -0
  107. package/templates/commands/review/post-task.md +157 -0
  108. package/templates/commands/review-changes.md +46 -0
  109. package/templates/commands/review.md +56 -0
  110. package/templates/commands/scout/ext.md +35 -0
  111. package/templates/commands/scout.md +283 -0
  112. package/templates/commands/security.md +119 -0
  113. package/templates/commands/skill/add.md +36 -0
  114. package/templates/commands/skill/create.md +29 -0
  115. package/templates/commands/skill/fix-logs.md +22 -0
  116. package/templates/commands/skill/optimize/auto.md +25 -0
  117. package/templates/commands/skill/optimize.md +34 -0
  118. package/templates/commands/skill/plan.md +45 -0
  119. package/templates/commands/test/ui.md +92 -0
  120. package/templates/commands/test.md +8 -0
  121. package/templates/commands/use-mcp.md +34 -0
  122. package/templates/commands/watzup.md +8 -0
  123. package/templates/commands/worktree.md +126 -0
  124. package/templates/discord/README.md +274 -0
  125. package/templates/discord/config.json5 +87 -0
  126. package/templates/discord/skills/auto-intent-router/SKILL.md +195 -0
  127. package/templates/discord/skills/train-prompt/SKILL.md +306 -0
  128. package/templates/discord/start-bot.sh +47 -0
  129. package/templates/gemini/settings.json +12 -0
  130. package/templates/hooks/.python-cache.json +1 -0
  131. package/templates/hooks/README.md +246 -0
  132. package/templates/hooks/backend-csharp-context.cjs +223 -0
  133. package/templates/hooks/design-system-context.cjs +185 -0
  134. package/templates/hooks/dev-rules-reminder.cjs +249 -0
  135. package/templates/hooks/docs/README.md +179 -0
  136. package/templates/hooks/frontend-typescript-context.cjs +233 -0
  137. package/templates/hooks/lib/__tests__/ck-config-utils.test.cjs +169 -0
  138. package/templates/hooks/lib/ck-config-utils.cjs +706 -0
  139. package/templates/hooks/lib/ck-paths.cjs +110 -0
  140. package/templates/hooks/lib/context-tracker.cjs +335 -0
  141. package/templates/hooks/notifications/.env.example +21 -0
  142. package/templates/hooks/notifications/discord_notify.sh +221 -0
  143. package/templates/hooks/notifications/docs/discord-hook-setup.md +445 -0
  144. package/templates/hooks/notifications/docs/slack-hook-setup.md +118 -0
  145. package/templates/hooks/notifications/docs/telegram-hook-setup.md +795 -0
  146. package/templates/hooks/notifications/lib/env-loader.cjs +105 -0
  147. package/templates/hooks/notifications/lib/sender.cjs +128 -0
  148. package/templates/hooks/notifications/notify.cjs +156 -0
  149. package/templates/hooks/notifications/providers/discord.cjs +197 -0
  150. package/templates/hooks/notifications/providers/slack.cjs +111 -0
  151. package/templates/hooks/notifications/providers/telegram.cjs +109 -0
  152. package/templates/hooks/notifications/send-discord.sh +75 -0
  153. package/templates/hooks/notifications/telegram_notify.sh +124 -0
  154. package/templates/hooks/notify-waiting.js +117 -0
  155. package/templates/hooks/post-edit-prettier.cjs +189 -0
  156. package/templates/hooks/post-task-review.cjs +142 -0
  157. package/templates/hooks/privacy-block.cjs +257 -0
  158. package/templates/hooks/scout-block/broad-pattern-detector.cjs +266 -0
  159. package/templates/hooks/scout-block/error-formatter.cjs +156 -0
  160. package/templates/hooks/scout-block/path-extractor.cjs +238 -0
  161. package/templates/hooks/scout-block/pattern-matcher.cjs +184 -0
  162. package/templates/hooks/scout-block/tests/test-broad-pattern-detector.js +225 -0
  163. package/templates/hooks/scout-block/tests/test-build-command-allowlist.js +137 -0
  164. package/templates/hooks/scout-block/tests/test-error-formatter.js +109 -0
  165. package/templates/hooks/scout-block/tests/test-full-flow-edge-cases.js +75 -0
  166. package/templates/hooks/scout-block/tests/test-monorepo-scenarios.js +225 -0
  167. package/templates/hooks/scout-block/tests/test-path-extractor.js +138 -0
  168. package/templates/hooks/scout-block/tests/test-pattern-matcher.js +64 -0
  169. package/templates/hooks/scout-block/vendor/ignore.js +627 -0
  170. package/templates/hooks/scout-block.cjs +134 -0
  171. package/templates/hooks/scss-styling-context.cjs +213 -0
  172. package/templates/hooks/session-end.cjs +35 -0
  173. package/templates/hooks/session-init.cjs +493 -0
  174. package/templates/hooks/subagent-init.cjs +150 -0
  175. package/templates/hooks/tests/test-ckignore.js +194 -0
  176. package/templates/hooks/tests/test-context-tracker.cjs +454 -0
  177. package/templates/hooks/tests/test-modularization-hook.js +126 -0
  178. package/templates/hooks/tests/test-privacy-block.js +298 -0
  179. package/templates/hooks/tests/test-scout-block.js +163 -0
  180. package/templates/hooks/workflow-router.cjs +326 -0
  181. package/templates/hooks/write-compact-marker.cjs +159 -0
  182. package/templates/memory/session-log.md +186 -0
  183. package/templates/output-styles/coding-level-0-eli5.md +103 -0
  184. package/templates/output-styles/coding-level-1-junior.md +124 -0
  185. package/templates/output-styles/coding-level-2-mid.md +146 -0
  186. package/templates/output-styles/coding-level-3-senior.md +148 -0
  187. package/templates/output-styles/coding-level-4-lead.md +159 -0
  188. package/templates/output-styles/coding-level-5-god.md +91 -0
  189. package/templates/router/README.md +294 -0
  190. package/templates/router/agents-guide.md +38 -0
  191. package/templates/router/commands-guide.md +122 -0
  192. package/templates/router/decision-flow.md +92 -0
  193. package/templates/router/skills-guide.md +127 -0
  194. package/templates/router/workflows-guide.md +68 -0
  195. package/templates/scripts/README.md +254 -0
  196. package/templates/scripts/__pycache__/win_compat.cpython-312.pyc +0 -0
  197. package/templates/scripts/ck-help.py +869 -0
  198. package/templates/scripts/commands_data.yaml +621 -0
  199. package/templates/scripts/generate_catalogs.py +168 -0
  200. package/templates/scripts/plan-preview.cjs +921 -0
  201. package/templates/scripts/requirements.txt +1 -0
  202. package/templates/scripts/resolve_env.py +329 -0
  203. package/templates/scripts/scan_commands.py +107 -0
  204. package/templates/scripts/scan_skills.py +197 -0
  205. package/templates/scripts/set-active-plan.cjs +45 -0
  206. package/templates/scripts/skills_data.yaml +596 -0
  207. package/templates/scripts/win_compat.py +57 -0
  208. package/templates/scripts/worktree.cjs +657 -0
  209. package/templates/scripts/worktree.test.cjs +334 -0
  210. package/templates/settings.json +242 -0
  211. package/templates/skills/.env.example +100 -0
  212. package/templates/skills/INSTALLATION.md +360 -0
  213. package/templates/skills/README.md +309 -0
  214. package/templates/skills/agent_skills_spec.md +55 -0
  215. package/templates/skills/ai-artist/SKILL.md +75 -0
  216. package/templates/skills/ai-artist/references/advanced-techniques.md +184 -0
  217. package/templates/skills/ai-artist/references/domain-code.md +66 -0
  218. package/templates/skills/ai-artist/references/domain-data.md +72 -0
  219. package/templates/skills/ai-artist/references/domain-marketing.md +66 -0
  220. package/templates/skills/ai-artist/references/domain-patterns.md +33 -0
  221. package/templates/skills/ai-artist/references/domain-writing.md +68 -0
  222. package/templates/skills/ai-artist/references/image-prompting.md +141 -0
  223. package/templates/skills/ai-artist/references/llm-prompting.md +165 -0
  224. package/templates/skills/ai-artist/references/nano-banana.md +59 -0
  225. package/templates/skills/ai-artist/references/reasoning-techniques.md +201 -0
  226. package/templates/skills/ai-multimodal/.env.example +204 -0
  227. package/templates/skills/ai-multimodal/SKILL.md +109 -0
  228. package/templates/skills/ai-multimodal/references/audio-processing.md +387 -0
  229. package/templates/skills/ai-multimodal/references/image-generation.md +939 -0
  230. package/templates/skills/ai-multimodal/references/music-generation.md +311 -0
  231. package/templates/skills/ai-multimodal/references/video-analysis.md +515 -0
  232. package/templates/skills/ai-multimodal/references/video-generation.md +457 -0
  233. package/templates/skills/ai-multimodal/references/vision-understanding.md +492 -0
  234. package/templates/skills/ai-multimodal/scripts/.coverage +0 -0
  235. package/templates/skills/ai-multimodal/scripts/check_setup.py +305 -0
  236. package/templates/skills/ai-multimodal/scripts/document_converter.py +395 -0
  237. package/templates/skills/ai-multimodal/scripts/gemini_batch_process.py +1184 -0
  238. package/templates/skills/ai-multimodal/scripts/media_optimizer.py +506 -0
  239. package/templates/skills/ai-multimodal/scripts/requirements.txt +26 -0
  240. package/templates/skills/ai-multimodal/scripts/tests/.coverage +0 -0
  241. package/templates/skills/ai-multimodal/scripts/tests/requirements.txt +20 -0
  242. package/templates/skills/ai-multimodal/scripts/tests/test_document_converter.py +74 -0
  243. package/templates/skills/ai-multimodal/scripts/tests/test_gemini_batch_process.py +362 -0
  244. package/templates/skills/ai-multimodal/scripts/tests/test_media_optimizer.py +373 -0
  245. package/templates/skills/arch-cross-service-integration/SKILL.md +48 -0
  246. package/templates/skills/arch-performance-optimization/SKILL.md +306 -0
  247. package/templates/skills/arch-security-review/SKILL.md +344 -0
  248. package/templates/skills/backend-development/SKILL.md +95 -0
  249. package/templates/skills/backend-development/references/backend-api-design.md +495 -0
  250. package/templates/skills/backend-development/references/backend-architecture.md +454 -0
  251. package/templates/skills/backend-development/references/backend-authentication.md +338 -0
  252. package/templates/skills/backend-development/references/backend-code-quality.md +659 -0
  253. package/templates/skills/backend-development/references/backend-debugging.md +904 -0
  254. package/templates/skills/backend-development/references/backend-devops.md +494 -0
  255. package/templates/skills/backend-development/references/backend-mindset.md +387 -0
  256. package/templates/skills/backend-development/references/backend-performance.md +397 -0
  257. package/templates/skills/backend-development/references/backend-security.md +290 -0
  258. package/templates/skills/backend-development/references/backend-technologies.md +256 -0
  259. package/templates/skills/backend-development/references/backend-testing.md +429 -0
  260. package/templates/skills/better-auth/SKILL.md +204 -0
  261. package/templates/skills/better-auth/references/advanced-features.md +553 -0
  262. package/templates/skills/better-auth/references/database-integration.md +577 -0
  263. package/templates/skills/better-auth/references/email-password-auth.md +416 -0
  264. package/templates/skills/better-auth/references/oauth-providers.md +430 -0
  265. package/templates/skills/better-auth/scripts/.coverage +0 -0
  266. package/templates/skills/better-auth/scripts/better_auth_init.py +521 -0
  267. package/templates/skills/better-auth/scripts/requirements.txt +15 -0
  268. package/templates/skills/better-auth/scripts/tests/.coverage +0 -0
  269. package/templates/skills/better-auth/scripts/tests/test_better_auth_init.py +421 -0
  270. package/templates/skills/branch-comparison/SKILL.md +150 -0
  271. package/templates/skills/bug-diagnosis/SKILL.md +309 -0
  272. package/templates/skills/chrome-devtools/SKILL.md +472 -0
  273. package/templates/skills/chrome-devtools/references/cdp-domains.md +694 -0
  274. package/templates/skills/chrome-devtools/references/performance-guide.md +940 -0
  275. package/templates/skills/chrome-devtools/references/puppeteer-reference.md +953 -0
  276. package/templates/skills/chrome-devtools/scripts/README.md +272 -0
  277. package/templates/skills/chrome-devtools/scripts/__tests__/selector.test.js +210 -0
  278. package/templates/skills/chrome-devtools/scripts/aria-snapshot.js +362 -0
  279. package/templates/skills/chrome-devtools/scripts/click.js +83 -0
  280. package/templates/skills/chrome-devtools/scripts/console.js +79 -0
  281. package/templates/skills/chrome-devtools/scripts/evaluate.js +53 -0
  282. package/templates/skills/chrome-devtools/scripts/fill.js +76 -0
  283. package/templates/skills/chrome-devtools/scripts/inject-auth.js +229 -0
  284. package/templates/skills/chrome-devtools/scripts/install-deps.sh +181 -0
  285. package/templates/skills/chrome-devtools/scripts/install.sh +83 -0
  286. package/templates/skills/chrome-devtools/scripts/lib/browser.js +318 -0
  287. package/templates/skills/chrome-devtools/scripts/lib/selector.js +178 -0
  288. package/templates/skills/chrome-devtools/scripts/navigate.js +54 -0
  289. package/templates/skills/chrome-devtools/scripts/network.js +106 -0
  290. package/templates/skills/chrome-devtools/scripts/package.json +16 -0
  291. package/templates/skills/chrome-devtools/scripts/performance.js +149 -0
  292. package/templates/skills/chrome-devtools/scripts/screenshot.js +198 -0
  293. package/templates/skills/chrome-devtools/scripts/select-ref.js +131 -0
  294. package/templates/skills/chrome-devtools/scripts/snapshot.js +135 -0
  295. package/templates/skills/claude-code/references/advanced-features.md +399 -0
  296. package/templates/skills/claude-code/references/agent-skills.md +399 -0
  297. package/templates/skills/claude-code/references/api-reference.md +498 -0
  298. package/templates/skills/claude-code/references/best-practices.md +447 -0
  299. package/templates/skills/claude-code/references/cicd-integration.md +428 -0
  300. package/templates/skills/claude-code/references/common-workflows.md +119 -0
  301. package/templates/skills/claude-code/references/configuration.md +480 -0
  302. package/templates/skills/claude-code/references/enterprise-features.md +472 -0
  303. package/templates/skills/claude-code/references/getting-started.md +252 -0
  304. package/templates/skills/claude-code/references/hooks-and-plugins.md +444 -0
  305. package/templates/skills/claude-code/references/hooks-comprehensive.md +622 -0
  306. package/templates/skills/claude-code/references/ide-integration.md +316 -0
  307. package/templates/skills/claude-code/references/mcp-integration.md +386 -0
  308. package/templates/skills/claude-code/references/slash-commands.md +489 -0
  309. package/templates/skills/claude-code/references/troubleshooting.md +456 -0
  310. package/templates/skills/claude-code/skill.md +60 -0
  311. package/templates/skills/code-review/SKILL.md +143 -0
  312. package/templates/skills/code-review/references/code-review-reception.md +209 -0
  313. package/templates/skills/code-review/references/requesting-code-review.md +105 -0
  314. package/templates/skills/code-review/references/verification-before-completion.md +139 -0
  315. package/templates/skills/databases/SKILL.md +232 -0
  316. package/templates/skills/databases/references/mongodb-aggregation.md +447 -0
  317. package/templates/skills/databases/references/mongodb-atlas.md +465 -0
  318. package/templates/skills/databases/references/mongodb-crud.md +408 -0
  319. package/templates/skills/databases/references/mongodb-indexing.md +442 -0
  320. package/templates/skills/databases/references/postgresql-administration.md +594 -0
  321. package/templates/skills/databases/references/postgresql-performance.md +527 -0
  322. package/templates/skills/databases/references/postgresql-psql-cli.md +467 -0
  323. package/templates/skills/databases/references/postgresql-queries.md +475 -0
  324. package/templates/skills/databases/scripts/.coverage +0 -0
  325. package/templates/skills/databases/scripts/db_backup.py +502 -0
  326. package/templates/skills/databases/scripts/db_migrate.py +425 -0
  327. package/templates/skills/databases/scripts/db_performance_check.py +456 -0
  328. package/templates/skills/databases/scripts/requirements.txt +20 -0
  329. package/templates/skills/databases/scripts/tests/coverage-db.json +1 -0
  330. package/templates/skills/databases/scripts/tests/requirements.txt +4 -0
  331. package/templates/skills/databases/scripts/tests/test_db_backup.py +340 -0
  332. package/templates/skills/databases/scripts/tests/test_db_migrate.py +277 -0
  333. package/templates/skills/databases/scripts/tests/test_db_performance_check.py +370 -0
  334. package/templates/skills/debugging/SKILL.md +84 -0
  335. package/templates/skills/debugging/references/defense-in-depth.md +124 -0
  336. package/templates/skills/debugging/references/root-cause-tracing.md +122 -0
  337. package/templates/skills/debugging/references/systematic-debugging.md +102 -0
  338. package/templates/skills/debugging/references/verification.md +123 -0
  339. package/templates/skills/debugging/scripts/find-polluter.sh +63 -0
  340. package/templates/skills/debugging/scripts/find-polluter.test.md +102 -0
  341. package/templates/skills/developer-growth-analysis/SKILL.md +322 -0
  342. package/templates/skills/devops/.env.example +76 -0
  343. package/templates/skills/devops/SKILL.md +285 -0
  344. package/templates/skills/devops/references/browser-rendering.md +305 -0
  345. package/templates/skills/devops/references/cloudflare-d1-kv.md +123 -0
  346. package/templates/skills/devops/references/cloudflare-platform.md +271 -0
  347. package/templates/skills/devops/references/cloudflare-r2-storage.md +280 -0
  348. package/templates/skills/devops/references/cloudflare-workers-advanced.md +312 -0
  349. package/templates/skills/devops/references/cloudflare-workers-apis.md +309 -0
  350. package/templates/skills/devops/references/cloudflare-workers-basics.md +418 -0
  351. package/templates/skills/devops/references/docker-basics.md +297 -0
  352. package/templates/skills/devops/references/docker-compose.md +292 -0
  353. package/templates/skills/devops/references/gcloud-platform.md +297 -0
  354. package/templates/skills/devops/references/gcloud-services.md +304 -0
  355. package/templates/skills/devops/scripts/cloudflare_deploy.py +269 -0
  356. package/templates/skills/devops/scripts/docker_optimize.py +331 -0
  357. package/templates/skills/devops/scripts/requirements.txt +20 -0
  358. package/templates/skills/devops/scripts/tests/requirements.txt +3 -0
  359. package/templates/skills/devops/scripts/tests/test_cloudflare_deploy.py +285 -0
  360. package/templates/skills/devops/scripts/tests/test_docker_optimize.py +436 -0
  361. package/templates/skills/docs-seeker/.env.example +15 -0
  362. package/templates/skills/docs-seeker/SKILL.md +97 -0
  363. package/templates/skills/docs-seeker/package.json +25 -0
  364. package/templates/skills/docs-seeker/references/advanced.md +79 -0
  365. package/templates/skills/docs-seeker/references/context7-patterns.md +68 -0
  366. package/templates/skills/docs-seeker/references/errors.md +68 -0
  367. package/templates/skills/docs-seeker/scripts/analyze-llms-txt.js +211 -0
  368. package/templates/skills/docs-seeker/scripts/detect-topic.js +172 -0
  369. package/templates/skills/docs-seeker/scripts/fetch-docs.js +213 -0
  370. package/templates/skills/docs-seeker/scripts/tests/run-tests.js +72 -0
  371. package/templates/skills/docs-seeker/scripts/tests/test-analyze-llms.js +119 -0
  372. package/templates/skills/docs-seeker/scripts/tests/test-detect-topic.js +112 -0
  373. package/templates/skills/docs-seeker/scripts/tests/test-fetch-docs.js +84 -0
  374. package/templates/skills/docs-seeker/scripts/utils/env-loader.js +94 -0
  375. package/templates/skills/docs-seeker/workflows/library-search.md +87 -0
  376. package/templates/skills/docs-seeker/workflows/repo-analysis.md +91 -0
  377. package/templates/skills/docs-seeker/workflows/topic-search.md +77 -0
  378. package/templates/skills/document-skills/docx/LICENSE.txt +30 -0
  379. package/templates/skills/document-skills/docx/SKILL.md +197 -0
  380. package/templates/skills/document-skills/docx/docx-js.md +350 -0
  381. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  382. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  383. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  384. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  385. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  386. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  387. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  388. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  389. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  390. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  391. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  392. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  393. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  394. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  395. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  396. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  397. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  398. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  399. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  400. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  401. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  402. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  403. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  404. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  405. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  406. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  407. package/templates/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  408. package/templates/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  409. package/templates/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  410. package/templates/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  411. package/templates/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  412. package/templates/skills/document-skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
  413. package/templates/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  414. package/templates/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  415. package/templates/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  416. package/templates/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  417. package/templates/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  418. package/templates/skills/document-skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  419. package/templates/skills/document-skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  420. package/templates/skills/document-skills/docx/ooxml/scripts/pack.py +159 -0
  421. package/templates/skills/document-skills/docx/ooxml/scripts/unpack.py +29 -0
  422. package/templates/skills/document-skills/docx/ooxml/scripts/validate.py +69 -0
  423. package/templates/skills/document-skills/docx/ooxml/scripts/validation/__init__.py +15 -0
  424. package/templates/skills/document-skills/docx/ooxml/scripts/validation/base.py +951 -0
  425. package/templates/skills/document-skills/docx/ooxml/scripts/validation/docx.py +274 -0
  426. package/templates/skills/document-skills/docx/ooxml/scripts/validation/pptx.py +315 -0
  427. package/templates/skills/document-skills/docx/ooxml/scripts/validation/redlining.py +279 -0
  428. package/templates/skills/document-skills/docx/ooxml.md +610 -0
  429. package/templates/skills/document-skills/docx/scripts/__init__.py +1 -0
  430. package/templates/skills/document-skills/docx/scripts/document.py +1276 -0
  431. package/templates/skills/document-skills/docx/scripts/templates/comments.xml +3 -0
  432. package/templates/skills/document-skills/docx/scripts/templates/commentsExtended.xml +3 -0
  433. package/templates/skills/document-skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  434. package/templates/skills/document-skills/docx/scripts/templates/commentsIds.xml +3 -0
  435. package/templates/skills/document-skills/docx/scripts/templates/people.xml +3 -0
  436. package/templates/skills/document-skills/docx/scripts/utilities.py +374 -0
  437. package/templates/skills/document-skills/pdf/LICENSE.txt +30 -0
  438. package/templates/skills/document-skills/pdf/SKILL.md +294 -0
  439. package/templates/skills/document-skills/pdf/forms.md +205 -0
  440. package/templates/skills/document-skills/pdf/reference.md +612 -0
  441. package/templates/skills/document-skills/pdf/scripts/check_bounding_boxes.py +70 -0
  442. package/templates/skills/document-skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
  443. package/templates/skills/document-skills/pdf/scripts/check_fillable_fields.py +12 -0
  444. package/templates/skills/document-skills/pdf/scripts/convert_pdf_to_images.py +35 -0
  445. package/templates/skills/document-skills/pdf/scripts/create_validation_image.py +41 -0
  446. package/templates/skills/document-skills/pdf/scripts/extract_form_field_info.py +152 -0
  447. package/templates/skills/document-skills/pdf/scripts/fill_fillable_fields.py +114 -0
  448. package/templates/skills/document-skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  449. package/templates/skills/document-skills/pptx/LICENSE.txt +30 -0
  450. package/templates/skills/document-skills/pptx/SKILL.md +484 -0
  451. package/templates/skills/document-skills/pptx/html2pptx.md +625 -0
  452. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  453. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  454. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  455. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  456. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  457. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  458. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  459. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  460. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  461. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  462. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  463. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  464. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  465. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  466. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  467. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  468. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  469. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  470. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  471. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  472. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  473. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  474. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  475. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  476. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  477. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  478. package/templates/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  479. package/templates/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  480. package/templates/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  481. package/templates/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  482. package/templates/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  483. package/templates/skills/document-skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
  484. package/templates/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  485. package/templates/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  486. package/templates/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  487. package/templates/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  488. package/templates/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  489. package/templates/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  490. package/templates/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  491. package/templates/skills/document-skills/pptx/ooxml/scripts/pack.py +159 -0
  492. package/templates/skills/document-skills/pptx/ooxml/scripts/unpack.py +29 -0
  493. package/templates/skills/document-skills/pptx/ooxml/scripts/validate.py +69 -0
  494. package/templates/skills/document-skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
  495. package/templates/skills/document-skills/pptx/ooxml/scripts/validation/base.py +951 -0
  496. package/templates/skills/document-skills/pptx/ooxml/scripts/validation/docx.py +274 -0
  497. package/templates/skills/document-skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
  498. package/templates/skills/document-skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
  499. package/templates/skills/document-skills/pptx/ooxml.md +427 -0
  500. package/templates/skills/document-skills/pptx/scripts/html2pptx.js +979 -0
  501. package/templates/skills/document-skills/pptx/scripts/inventory.py +1020 -0
  502. package/templates/skills/document-skills/pptx/scripts/rearrange.py +231 -0
  503. package/templates/skills/document-skills/pptx/scripts/replace.py +385 -0
  504. package/templates/skills/document-skills/pptx/scripts/thumbnail.py +450 -0
  505. package/templates/skills/document-skills/xlsx/LICENSE.txt +30 -0
  506. package/templates/skills/document-skills/xlsx/SKILL.md +289 -0
  507. package/templates/skills/document-skills/xlsx/recalc.py +190 -0
  508. package/templates/skills/documentation/SKILL.md +134 -0
  509. package/templates/skills/domain-name-brainstormer/SKILL.md +212 -0
  510. package/templates/skills/dual-pass-review/SKILL.md +249 -0
  511. package/templates/skills/feature-docs/SKILL.md +294 -0
  512. package/templates/skills/feature-implementation/SKILL.md +262 -0
  513. package/templates/skills/feature-investigation/SKILL.md +346 -0
  514. package/templates/skills/frontend-design/SKILL.md +91 -0
  515. package/templates/skills/frontend-design/references/ai-multimodal-overview.md +165 -0
  516. package/templates/skills/frontend-design/references/analysis-best-practices.md +80 -0
  517. package/templates/skills/frontend-design/references/analysis-prompts.md +141 -0
  518. package/templates/skills/frontend-design/references/analysis-techniques.md +118 -0
  519. package/templates/skills/frontend-design/references/animejs.md +396 -0
  520. package/templates/skills/frontend-design/references/asset-generation.md +337 -0
  521. package/templates/skills/frontend-design/references/design-extraction-overview.md +71 -0
  522. package/templates/skills/frontend-design/references/extraction-best-practices.md +141 -0
  523. package/templates/skills/frontend-design/references/extraction-output-templates.md +162 -0
  524. package/templates/skills/frontend-design/references/extraction-prompts.md +127 -0
  525. package/templates/skills/frontend-design/references/technical-accessibility.md +119 -0
  526. package/templates/skills/frontend-design/references/technical-best-practices.md +97 -0
  527. package/templates/skills/frontend-design/references/technical-optimization.md +44 -0
  528. package/templates/skills/frontend-design/references/technical-overview.md +90 -0
  529. package/templates/skills/frontend-design/references/technical-workflows.md +150 -0
  530. package/templates/skills/frontend-design/references/visual-analysis-overview.md +95 -0
  531. package/templates/skills/frontend-design-pro/SKILL.md +58 -0
  532. package/templates/skills/frontend-development/SKILL.md +399 -0
  533. package/templates/skills/frontend-development/resources/common-patterns.md +331 -0
  534. package/templates/skills/frontend-development/resources/complete-examples.md +872 -0
  535. package/templates/skills/frontend-development/resources/component-patterns.md +502 -0
  536. package/templates/skills/frontend-development/resources/data-fetching.md +767 -0
  537. package/templates/skills/frontend-development/resources/file-organization.md +502 -0
  538. package/templates/skills/frontend-development/resources/loading-and-error-states.md +501 -0
  539. package/templates/skills/frontend-development/resources/performance.md +406 -0
  540. package/templates/skills/frontend-development/resources/routing-guide.md +364 -0
  541. package/templates/skills/frontend-development/resources/styling-guide.md +428 -0
  542. package/templates/skills/frontend-development/resources/typescript-standards.md +418 -0
  543. package/templates/skills/google-adk-python/SKILL.md +237 -0
  544. package/templates/skills/install.ps1 +1220 -0
  545. package/templates/skills/install.sh +1032 -0
  546. package/templates/skills/mcp-builder/LICENSE.txt +202 -0
  547. package/templates/skills/mcp-builder/SKILL.md +328 -0
  548. package/templates/skills/mcp-builder/reference/evaluation.md +602 -0
  549. package/templates/skills/mcp-builder/reference/mcp_best_practices.md +915 -0
  550. package/templates/skills/mcp-builder/reference/node_mcp_server.md +916 -0
  551. package/templates/skills/mcp-builder/reference/python_mcp_server.md +752 -0
  552. package/templates/skills/mcp-builder/scripts/connections.py +151 -0
  553. package/templates/skills/mcp-builder/scripts/evaluation.py +373 -0
  554. package/templates/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  555. package/templates/skills/mcp-builder/scripts/requirements.txt +2 -0
  556. package/templates/skills/mcp-management/README.md +219 -0
  557. package/templates/skills/mcp-management/SKILL.md +209 -0
  558. package/templates/skills/mcp-management/assets/tools.json +3146 -0
  559. package/templates/skills/mcp-management/references/configuration.md +114 -0
  560. package/templates/skills/mcp-management/references/gemini-cli-integration.md +215 -0
  561. package/templates/skills/mcp-management/references/mcp-protocol.md +116 -0
  562. package/templates/skills/mcp-management/scripts/.env.example +10 -0
  563. package/templates/skills/mcp-management/scripts/cli.ts +195 -0
  564. package/templates/skills/mcp-management/scripts/dist/analyze-tools.js +70 -0
  565. package/templates/skills/mcp-management/scripts/dist/cli.js +160 -0
  566. package/templates/skills/mcp-management/scripts/dist/mcp-client.js +183 -0
  567. package/templates/skills/mcp-management/scripts/mcp-client.ts +230 -0
  568. package/templates/skills/mcp-management/scripts/package.json +20 -0
  569. package/templates/skills/mcp-management/scripts/tsconfig.json +15 -0
  570. package/templates/skills/media-processing/SKILL.md +91 -0
  571. package/templates/skills/media-processing/references/common-workflows.md +132 -0
  572. package/templates/skills/media-processing/references/ffmpeg-encoding.md +358 -0
  573. package/templates/skills/media-processing/references/ffmpeg-filters.md +503 -0
  574. package/templates/skills/media-processing/references/ffmpeg-streaming.md +403 -0
  575. package/templates/skills/media-processing/references/format-compatibility.md +375 -0
  576. package/templates/skills/media-processing/references/imagemagick-batch.md +612 -0
  577. package/templates/skills/media-processing/references/imagemagick-editing.md +623 -0
  578. package/templates/skills/media-processing/references/rmbg-background-removal.md +66 -0
  579. package/templates/skills/media-processing/references/troubleshooting.md +109 -0
  580. package/templates/skills/media-processing/scripts/README.md +111 -0
  581. package/templates/skills/media-processing/scripts/batch-remove-background.sh +124 -0
  582. package/templates/skills/media-processing/scripts/batch_resize.py +342 -0
  583. package/templates/skills/media-processing/scripts/media_convert.py +311 -0
  584. package/templates/skills/media-processing/scripts/remove-background.sh +96 -0
  585. package/templates/skills/media-processing/scripts/remove-bg-node.js +158 -0
  586. package/templates/skills/media-processing/scripts/requirements.txt +24 -0
  587. package/templates/skills/media-processing/scripts/tests/.coverage +0 -0
  588. package/templates/skills/media-processing/scripts/tests/requirements.txt +2 -0
  589. package/templates/skills/media-processing/scripts/tests/test_batch_resize.py +372 -0
  590. package/templates/skills/media-processing/scripts/tests/test_media_convert.py +259 -0
  591. package/templates/skills/media-processing/scripts/tests/test_video_optimize.py +397 -0
  592. package/templates/skills/media-processing/scripts/video_optimize.py +414 -0
  593. package/templates/skills/mobile-development/SKILL.md +212 -0
  594. package/templates/skills/mobile-development/references/mobile-android.md +604 -0
  595. package/templates/skills/mobile-development/references/mobile-best-practices.md +545 -0
  596. package/templates/skills/mobile-development/references/mobile-debugging.md +1089 -0
  597. package/templates/skills/mobile-development/references/mobile-frameworks.md +465 -0
  598. package/templates/skills/mobile-development/references/mobile-ios.md +496 -0
  599. package/templates/skills/mobile-development/references/mobile-mindset.md +544 -0
  600. package/templates/skills/package-upgrade/SKILL.md +189 -0
  601. package/templates/skills/payment-integration/README.md +185 -0
  602. package/templates/skills/payment-integration/SKILL.md +118 -0
  603. package/templates/skills/payment-integration/references/polar/benefits.md +396 -0
  604. package/templates/skills/payment-integration/references/polar/best-practices.md +482 -0
  605. package/templates/skills/payment-integration/references/polar/checkouts.md +266 -0
  606. package/templates/skills/payment-integration/references/polar/overview.md +184 -0
  607. package/templates/skills/payment-integration/references/polar/products.md +244 -0
  608. package/templates/skills/payment-integration/references/polar/sdk.md +436 -0
  609. package/templates/skills/payment-integration/references/polar/subscriptions.md +340 -0
  610. package/templates/skills/payment-integration/references/polar/webhooks.md +405 -0
  611. package/templates/skills/payment-integration/references/sepay/api.md +140 -0
  612. package/templates/skills/payment-integration/references/sepay/best-practices.md +337 -0
  613. package/templates/skills/payment-integration/references/sepay/overview.md +138 -0
  614. package/templates/skills/payment-integration/references/sepay/qr-codes.md +228 -0
  615. package/templates/skills/payment-integration/references/sepay/sdk.md +213 -0
  616. package/templates/skills/payment-integration/references/sepay/webhooks.md +208 -0
  617. package/templates/skills/payment-integration/scripts/.env.example +20 -0
  618. package/templates/skills/payment-integration/scripts/checkout-helper.js +244 -0
  619. package/templates/skills/payment-integration/scripts/package.json +17 -0
  620. package/templates/skills/payment-integration/scripts/polar-webhook-verify.js +202 -0
  621. package/templates/skills/payment-integration/scripts/sepay-webhook-verify.js +193 -0
  622. package/templates/skills/payment-integration/scripts/test-scripts.js +237 -0
  623. package/templates/skills/plan-analysis/SKILL.md +191 -0
  624. package/templates/skills/planning/SKILL.md +115 -0
  625. package/templates/skills/planning/references/codebase-understanding.md +62 -0
  626. package/templates/skills/planning/references/output-standards.md +127 -0
  627. package/templates/skills/planning/references/plan-organization.md +150 -0
  628. package/templates/skills/planning/references/research-phase.md +49 -0
  629. package/templates/skills/planning/references/solution-design.md +63 -0
  630. package/templates/skills/planning-with-files/SKILL.md +160 -0
  631. package/templates/skills/planning-with-files/examples.md +202 -0
  632. package/templates/skills/planning-with-files/reference.md +110 -0
  633. package/templates/skills/problem-solving/SKILL.md +96 -0
  634. package/templates/skills/problem-solving/references/attribution.md +69 -0
  635. package/templates/skills/problem-solving/references/collision-zone-thinking.md +79 -0
  636. package/templates/skills/problem-solving/references/inversion-exercise.md +91 -0
  637. package/templates/skills/problem-solving/references/meta-pattern-recognition.md +87 -0
  638. package/templates/skills/problem-solving/references/scale-game.md +95 -0
  639. package/templates/skills/problem-solving/references/simplification-cascades.md +80 -0
  640. package/templates/skills/problem-solving/references/when-stuck.md +72 -0
  641. package/templates/skills/project-index/SKILL.md +97 -0
  642. package/templates/skills/project-index/scripts/scan-structure.js +417 -0
  643. package/templates/skills/project-index/scripts/scan_structure.py +450 -0
  644. package/templates/skills/readme-improvement/SKILL.md +177 -0
  645. package/templates/skills/repomix/SKILL.md +247 -0
  646. package/templates/skills/repomix/references/configuration.md +211 -0
  647. package/templates/skills/repomix/references/usage-patterns.md +232 -0
  648. package/templates/skills/repomix/scripts/.coverage +0 -0
  649. package/templates/skills/repomix/scripts/README.md +179 -0
  650. package/templates/skills/repomix/scripts/repomix_batch.py +455 -0
  651. package/templates/skills/repomix/scripts/repos.example.json +15 -0
  652. package/templates/skills/repomix/scripts/requirements.txt +15 -0
  653. package/templates/skills/repomix/scripts/tests/test_repomix_batch.py +531 -0
  654. package/templates/skills/research/SKILL.md +168 -0
  655. package/templates/skills/sequential-thinking/.env.example +8 -0
  656. package/templates/skills/sequential-thinking/README.md +183 -0
  657. package/templates/skills/sequential-thinking/SKILL.md +94 -0
  658. package/templates/skills/sequential-thinking/package.json +31 -0
  659. package/templates/skills/sequential-thinking/references/advanced-strategies.md +79 -0
  660. package/templates/skills/sequential-thinking/references/advanced-techniques.md +76 -0
  661. package/templates/skills/sequential-thinking/references/core-patterns.md +95 -0
  662. package/templates/skills/sequential-thinking/references/examples-api.md +88 -0
  663. package/templates/skills/sequential-thinking/references/examples-architecture.md +94 -0
  664. package/templates/skills/sequential-thinking/references/examples-debug.md +90 -0
  665. package/templates/skills/sequential-thinking/scripts/format-thought.js +159 -0
  666. package/templates/skills/sequential-thinking/scripts/process-thought.js +236 -0
  667. package/templates/skills/sequential-thinking/tests/format-thought.test.js +133 -0
  668. package/templates/skills/sequential-thinking/tests/process-thought.test.js +215 -0
  669. package/templates/skills/shopify/README.md +66 -0
  670. package/templates/skills/shopify/SKILL.md +319 -0
  671. package/templates/skills/shopify/references/app-development.md +470 -0
  672. package/templates/skills/shopify/references/extensions.md +493 -0
  673. package/templates/skills/shopify/references/themes.md +498 -0
  674. package/templates/skills/shopify/scripts/.coverage +0 -0
  675. package/templates/skills/shopify/scripts/requirements.txt +19 -0
  676. package/templates/skills/shopify/scripts/shopify_init.py +423 -0
  677. package/templates/skills/shopify/scripts/tests/.coverage +0 -0
  678. package/templates/skills/shopify/scripts/tests/test_shopify_init.py +385 -0
  679. package/templates/skills/skill-creator/LICENSE.txt +202 -0
  680. package/templates/skills/skill-creator/SKILL.md +266 -0
  681. package/templates/skills/skill-creator/scripts/init_skill.py +303 -0
  682. package/templates/skills/skill-creator/scripts/package_skill.py +110 -0
  683. package/templates/skills/skill-creator/scripts/quick_validate.py +65 -0
  684. package/templates/skills/skill-share/SKILL.md +80 -0
  685. package/templates/skills/tasks-code-review/SKILL.md +298 -0
  686. package/templates/skills/tasks-documentation/SKILL.md +328 -0
  687. package/templates/skills/tasks-spec-update/SKILL.md +318 -0
  688. package/templates/skills/tasks-test-generation/SKILL.md +433 -0
  689. package/templates/skills/template-skill/SKILL.md +6 -0
  690. package/templates/skills/test-generation/SKILL.md +203 -0
  691. package/templates/skills/threejs/SKILL.md +89 -0
  692. package/templates/skills/threejs/references/01-getting-started.md +177 -0
  693. package/templates/skills/threejs/references/02-loaders.md +169 -0
  694. package/templates/skills/threejs/references/03-textures.md +170 -0
  695. package/templates/skills/threejs/references/04-cameras.md +195 -0
  696. package/templates/skills/threejs/references/05-lights.md +183 -0
  697. package/templates/skills/threejs/references/06-animations.md +214 -0
  698. package/templates/skills/threejs/references/07-math.md +260 -0
  699. package/templates/skills/threejs/references/08-interaction.md +267 -0
  700. package/templates/skills/threejs/references/09-postprocessing.md +240 -0
  701. package/templates/skills/threejs/references/10-controls.md +259 -0
  702. package/templates/skills/threejs/references/11-materials-advanced.md +270 -0
  703. package/templates/skills/threejs/references/12-performance.md +269 -0
  704. package/templates/skills/threejs/references/13-node-materials.md +298 -0
  705. package/templates/skills/threejs/references/14-physics-vr.md +304 -0
  706. package/templates/skills/threejs/references/15-specialized-loaders.md +333 -0
  707. package/templates/skills/threejs/references/16-webgpu.md +302 -0
  708. package/templates/skills/ui-styling/LICENSE.txt +202 -0
  709. package/templates/skills/ui-styling/SKILL.md +321 -0
  710. package/templates/skills/ui-styling/canvas-fonts/ArsenalSC-OFL.txt +93 -0
  711. package/templates/skills/ui-styling/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
  712. package/templates/skills/ui-styling/canvas-fonts/BigShoulders-Bold.ttf +0 -0
  713. package/templates/skills/ui-styling/canvas-fonts/BigShoulders-OFL.txt +93 -0
  714. package/templates/skills/ui-styling/canvas-fonts/BigShoulders-Regular.ttf +0 -0
  715. package/templates/skills/ui-styling/canvas-fonts/Boldonse-OFL.txt +93 -0
  716. package/templates/skills/ui-styling/canvas-fonts/Boldonse-Regular.ttf +0 -0
  717. package/templates/skills/ui-styling/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  718. package/templates/skills/ui-styling/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
  719. package/templates/skills/ui-styling/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  720. package/templates/skills/ui-styling/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
  721. package/templates/skills/ui-styling/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
  722. package/templates/skills/ui-styling/canvas-fonts/CrimsonPro-OFL.txt +93 -0
  723. package/templates/skills/ui-styling/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
  724. package/templates/skills/ui-styling/canvas-fonts/DMMono-OFL.txt +93 -0
  725. package/templates/skills/ui-styling/canvas-fonts/DMMono-Regular.ttf +0 -0
  726. package/templates/skills/ui-styling/canvas-fonts/EricaOne-OFL.txt +94 -0
  727. package/templates/skills/ui-styling/canvas-fonts/EricaOne-Regular.ttf +0 -0
  728. package/templates/skills/ui-styling/canvas-fonts/GeistMono-Bold.ttf +0 -0
  729. package/templates/skills/ui-styling/canvas-fonts/GeistMono-OFL.txt +93 -0
  730. package/templates/skills/ui-styling/canvas-fonts/GeistMono-Regular.ttf +0 -0
  731. package/templates/skills/ui-styling/canvas-fonts/Gloock-OFL.txt +93 -0
  732. package/templates/skills/ui-styling/canvas-fonts/Gloock-Regular.ttf +0 -0
  733. package/templates/skills/ui-styling/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
  734. package/templates/skills/ui-styling/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
  735. package/templates/skills/ui-styling/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
  736. package/templates/skills/ui-styling/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
  737. package/templates/skills/ui-styling/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
  738. package/templates/skills/ui-styling/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
  739. package/templates/skills/ui-styling/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
  740. package/templates/skills/ui-styling/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  741. package/templates/skills/ui-styling/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  742. package/templates/skills/ui-styling/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  743. package/templates/skills/ui-styling/canvas-fonts/InstrumentSans-OFL.txt +93 -0
  744. package/templates/skills/ui-styling/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  745. package/templates/skills/ui-styling/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  746. package/templates/skills/ui-styling/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  747. package/templates/skills/ui-styling/canvas-fonts/Italiana-OFL.txt +93 -0
  748. package/templates/skills/ui-styling/canvas-fonts/Italiana-Regular.ttf +0 -0
  749. package/templates/skills/ui-styling/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  750. package/templates/skills/ui-styling/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
  751. package/templates/skills/ui-styling/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  752. package/templates/skills/ui-styling/canvas-fonts/Jura-Light.ttf +0 -0
  753. package/templates/skills/ui-styling/canvas-fonts/Jura-Medium.ttf +0 -0
  754. package/templates/skills/ui-styling/canvas-fonts/Jura-OFL.txt +93 -0
  755. package/templates/skills/ui-styling/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
  756. package/templates/skills/ui-styling/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
  757. package/templates/skills/ui-styling/canvas-fonts/Lora-Bold.ttf +0 -0
  758. package/templates/skills/ui-styling/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  759. package/templates/skills/ui-styling/canvas-fonts/Lora-Italic.ttf +0 -0
  760. package/templates/skills/ui-styling/canvas-fonts/Lora-OFL.txt +93 -0
  761. package/templates/skills/ui-styling/canvas-fonts/Lora-Regular.ttf +0 -0
  762. package/templates/skills/ui-styling/canvas-fonts/NationalPark-Bold.ttf +0 -0
  763. package/templates/skills/ui-styling/canvas-fonts/NationalPark-OFL.txt +93 -0
  764. package/templates/skills/ui-styling/canvas-fonts/NationalPark-Regular.ttf +0 -0
  765. package/templates/skills/ui-styling/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
  766. package/templates/skills/ui-styling/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  767. package/templates/skills/ui-styling/canvas-fonts/Outfit-Bold.ttf +0 -0
  768. package/templates/skills/ui-styling/canvas-fonts/Outfit-OFL.txt +93 -0
  769. package/templates/skills/ui-styling/canvas-fonts/Outfit-Regular.ttf +0 -0
  770. package/templates/skills/ui-styling/canvas-fonts/PixelifySans-Medium.ttf +0 -0
  771. package/templates/skills/ui-styling/canvas-fonts/PixelifySans-OFL.txt +93 -0
  772. package/templates/skills/ui-styling/canvas-fonts/PoiretOne-OFL.txt +93 -0
  773. package/templates/skills/ui-styling/canvas-fonts/PoiretOne-Regular.ttf +0 -0
  774. package/templates/skills/ui-styling/canvas-fonts/RedHatMono-Bold.ttf +0 -0
  775. package/templates/skills/ui-styling/canvas-fonts/RedHatMono-OFL.txt +93 -0
  776. package/templates/skills/ui-styling/canvas-fonts/RedHatMono-Regular.ttf +0 -0
  777. package/templates/skills/ui-styling/canvas-fonts/Silkscreen-OFL.txt +93 -0
  778. package/templates/skills/ui-styling/canvas-fonts/Silkscreen-Regular.ttf +0 -0
  779. package/templates/skills/ui-styling/canvas-fonts/SmoochSans-Medium.ttf +0 -0
  780. package/templates/skills/ui-styling/canvas-fonts/SmoochSans-OFL.txt +93 -0
  781. package/templates/skills/ui-styling/canvas-fonts/Tektur-Medium.ttf +0 -0
  782. package/templates/skills/ui-styling/canvas-fonts/Tektur-OFL.txt +93 -0
  783. package/templates/skills/ui-styling/canvas-fonts/Tektur-Regular.ttf +0 -0
  784. package/templates/skills/ui-styling/canvas-fonts/WorkSans-Bold.ttf +0 -0
  785. package/templates/skills/ui-styling/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
  786. package/templates/skills/ui-styling/canvas-fonts/WorkSans-Italic.ttf +0 -0
  787. package/templates/skills/ui-styling/canvas-fonts/WorkSans-OFL.txt +93 -0
  788. package/templates/skills/ui-styling/canvas-fonts/WorkSans-Regular.ttf +0 -0
  789. package/templates/skills/ui-styling/canvas-fonts/YoungSerif-OFL.txt +93 -0
  790. package/templates/skills/ui-styling/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  791. package/templates/skills/ui-styling/references/canvas-design-system.md +320 -0
  792. package/templates/skills/ui-styling/references/shadcn-accessibility.md +471 -0
  793. package/templates/skills/ui-styling/references/shadcn-components.md +424 -0
  794. package/templates/skills/ui-styling/references/shadcn-theming.md +373 -0
  795. package/templates/skills/ui-styling/references/tailwind-customization.md +483 -0
  796. package/templates/skills/ui-styling/references/tailwind-responsive.md +382 -0
  797. package/templates/skills/ui-styling/references/tailwind-utilities.md +455 -0
  798. package/templates/skills/ui-styling/scripts/.coverage +0 -0
  799. package/templates/skills/ui-styling/scripts/requirements.txt +17 -0
  800. package/templates/skills/ui-styling/scripts/shadcn_add.py +292 -0
  801. package/templates/skills/ui-styling/scripts/tailwind_config_gen.py +456 -0
  802. package/templates/skills/ui-styling/scripts/tests/coverage-ui.json +1 -0
  803. package/templates/skills/ui-styling/scripts/tests/requirements.txt +3 -0
  804. package/templates/skills/ui-styling/scripts/tests/test_shadcn_add.py +266 -0
  805. package/templates/skills/ui-styling/scripts/tests/test_tailwind_config_gen.py +336 -0
  806. package/templates/skills/ui-ux-pro-max/SKILL.md +315 -0
  807. package/templates/skills/ui-ux-pro-max/data/charts.csv +26 -0
  808. package/templates/skills/ui-ux-pro-max/data/colors.csv +97 -0
  809. package/templates/skills/ui-ux-pro-max/data/icons.csv +101 -0
  810. package/templates/skills/ui-ux-pro-max/data/landing.csv +31 -0
  811. package/templates/skills/ui-ux-pro-max/data/products.csv +97 -0
  812. package/templates/skills/ui-ux-pro-max/data/prompts.csv +24 -0
  813. package/templates/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  814. package/templates/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  815. package/templates/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  816. package/templates/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  817. package/templates/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  818. package/templates/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  819. package/templates/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  820. package/templates/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  821. package/templates/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  822. package/templates/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  823. package/templates/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  824. package/templates/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  825. package/templates/skills/ui-ux-pro-max/data/styles.csv +59 -0
  826. package/templates/skills/ui-ux-pro-max/data/typography.csv +58 -0
  827. package/templates/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  828. package/templates/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  829. package/templates/skills/ui-ux-pro-max/scripts/core.py +257 -0
  830. package/templates/skills/ui-ux-pro-max/scripts/search.py +61 -0
  831. package/templates/skills/web-frameworks/SKILL.md +324 -0
  832. package/templates/skills/web-frameworks/references/nextjs-app-router.md +465 -0
  833. package/templates/skills/web-frameworks/references/nextjs-data-fetching.md +459 -0
  834. package/templates/skills/web-frameworks/references/nextjs-optimization.md +511 -0
  835. package/templates/skills/web-frameworks/references/nextjs-server-components.md +495 -0
  836. package/templates/skills/web-frameworks/references/remix-icon-integration.md +603 -0
  837. package/templates/skills/web-frameworks/references/turborepo-caching.md +551 -0
  838. package/templates/skills/web-frameworks/references/turborepo-pipelines.md +517 -0
  839. package/templates/skills/web-frameworks/references/turborepo-setup.md +542 -0
  840. package/templates/skills/web-frameworks/scripts/.coverage +0 -0
  841. package/templates/skills/web-frameworks/scripts/__init__.py +0 -0
  842. package/templates/skills/web-frameworks/scripts/nextjs_init.py +547 -0
  843. package/templates/skills/web-frameworks/scripts/requirements.txt +16 -0
  844. package/templates/skills/web-frameworks/scripts/tests/coverage-web.json +1 -0
  845. package/templates/skills/web-frameworks/scripts/tests/requirements.txt +3 -0
  846. package/templates/skills/web-frameworks/scripts/tests/test_nextjs_init.py +319 -0
  847. package/templates/skills/web-frameworks/scripts/tests/test_turborepo_migrate.py +374 -0
  848. package/templates/skills/web-frameworks/scripts/turborepo_migrate.py +394 -0
  849. package/templates/skills/webapp-testing/LICENSE.txt +202 -0
  850. package/templates/skills/webapp-testing/SKILL.md +96 -0
  851. package/templates/skills/webapp-testing/examples/console_logging.py +35 -0
  852. package/templates/skills/webapp-testing/examples/element_discovery.py +40 -0
  853. package/templates/skills/webapp-testing/examples/static_html_automation.py +33 -0
  854. package/templates/skills/webapp-testing/scripts/with_server.py +106 -0
  855. package/templates/statusline.cjs +306 -0
  856. package/templates/statusline.ps1 +308 -0
  857. package/templates/statusline.sh +238 -0
  858. package/templates/workflows/README.md +241 -0
  859. package/templates/workflows/development-rules.md +93 -0
  860. package/templates/workflows/documentation-management.md +121 -0
  861. package/templates/workflows/orchestration-protocol.md +16 -0
  862. package/templates/workflows/primary-workflow.md +45 -0
package/dist/index.js ADDED
@@ -0,0 +1,3829 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'module'; const require = createRequire(import.meta.url);
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
6
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
7
+ }) : x)(function(x) {
8
+ if (typeof require !== "undefined") return require.apply(this, arguments);
9
+ throw Error('Dynamic require of "' + x + '" is not supported');
10
+ });
11
+ var __esm = (fn, res) => function __init() {
12
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
13
+ };
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+
19
+ // src/kits/index.ts
20
+ var KITS, getKit, getKitList;
21
+ var init_kits = __esm({
22
+ "src/kits/index.ts"() {
23
+ "use strict";
24
+ KITS = {
25
+ engineer: {
26
+ name: "engineer",
27
+ description: "Full-stack development kit for building applications",
28
+ emoji: "\u{1F6E0}\uFE0F",
29
+ color: "blue",
30
+ agents: [
31
+ "planner",
32
+ "debugger",
33
+ "fullstack-developer",
34
+ "tester",
35
+ "code-reviewer",
36
+ "git-manager",
37
+ "database-admin"
38
+ ],
39
+ commands: [
40
+ "plan",
41
+ "plan/parallel",
42
+ "plan/fast",
43
+ "plan/hard",
44
+ "code",
45
+ "code/auto",
46
+ "code/parallel",
47
+ "fix",
48
+ "fix/test",
49
+ "fix/types",
50
+ "fix/fast",
51
+ "fix/ci",
52
+ "test",
53
+ "test/ui",
54
+ "review",
55
+ "review/codebase",
56
+ "scout",
57
+ "build",
58
+ "lint"
59
+ ],
60
+ skills: [
61
+ "frontend-development",
62
+ "backend-development",
63
+ "databases",
64
+ "debugging",
65
+ "code-review",
66
+ "planning",
67
+ "problem-solving"
68
+ ],
69
+ workflows: ["feature-development", "bug-fixing"],
70
+ includeRouter: true,
71
+ includeHooks: true
72
+ },
73
+ researcher: {
74
+ name: "researcher",
75
+ description: "Research and analysis kit for exploring codebases",
76
+ emoji: "\u{1F52C}",
77
+ color: "green",
78
+ agents: [
79
+ "researcher",
80
+ "scout",
81
+ "scout-external",
82
+ "brainstormer",
83
+ "docs-manager",
84
+ "planner"
85
+ ],
86
+ commands: [
87
+ "scout",
88
+ "scout/ext",
89
+ "investigate",
90
+ "brainstorm",
91
+ "docs",
92
+ "docs/init",
93
+ "docs/update",
94
+ "docs/summarize",
95
+ "plan",
96
+ "ask",
97
+ "context"
98
+ ],
99
+ skills: [
100
+ "research",
101
+ "planning-with-files",
102
+ "documentation",
103
+ "project-index"
104
+ ],
105
+ workflows: [],
106
+ includeRouter: true,
107
+ includeHooks: false
108
+ },
109
+ designer: {
110
+ name: "designer",
111
+ description: "UI/UX design and frontend development kit",
112
+ emoji: "\u{1F3A8}",
113
+ color: "magenta",
114
+ agents: [
115
+ "ui-ux-designer",
116
+ "fullstack-developer",
117
+ "code-reviewer"
118
+ ],
119
+ commands: [
120
+ "code",
121
+ "fix",
122
+ "fix/ui",
123
+ "test/ui",
124
+ "review"
125
+ ],
126
+ skills: [
127
+ "ui-ux-pro-max",
128
+ "frontend-development",
129
+ "frontend-design"
130
+ ],
131
+ workflows: [],
132
+ includeRouter: false,
133
+ includeHooks: true
134
+ },
135
+ minimal: {
136
+ name: "minimal",
137
+ description: "Lightweight kit with essential agents only",
138
+ emoji: "\u{1F4E6}",
139
+ color: "yellow",
140
+ agents: ["planner", "debugger"],
141
+ commands: ["plan", "fix", "code"],
142
+ skills: ["planning", "debugging"],
143
+ workflows: [],
144
+ includeRouter: false,
145
+ includeHooks: false
146
+ },
147
+ full: {
148
+ name: "full",
149
+ description: "Complete kit with ALL agents, commands, and skills",
150
+ emoji: "\u{1F680}",
151
+ color: "cyan",
152
+ agents: "all",
153
+ commands: "all",
154
+ skills: "all",
155
+ workflows: "all",
156
+ includeRouter: true,
157
+ includeHooks: true
158
+ }
159
+ };
160
+ getKit = (name) => KITS[name] || null;
161
+ getKitList = () => Object.values(KITS);
162
+ }
163
+ });
164
+
165
+ // src/utils/paths.ts
166
+ var paths_exports = {};
167
+ __export(paths_exports, {
168
+ CLI_ROOT: () => CLI_ROOT,
169
+ TARGETS: () => TARGETS,
170
+ TEMPLATES_DIR: () => TEMPLATES_DIR,
171
+ getCkInternalSource: () => getCkInternalSource,
172
+ getEmbeddedTemplates: () => getEmbeddedTemplates,
173
+ getGlobalInstallPath: () => getGlobalInstallPath,
174
+ getTargetDir: () => getTargetDir,
175
+ isAkProject: () => isAkProject,
176
+ resolveSource: () => resolveSource
177
+ });
178
+ import { fileURLToPath } from "url";
179
+ import { dirname, join, resolve } from "path";
180
+ import { existsSync } from "fs";
181
+ import { homedir } from "os";
182
+ function getCkInternalSource() {
183
+ for (const basePath of CK_INTERNAL_PATHS) {
184
+ const claudeDir = join(basePath, ".claude");
185
+ if (existsSync(claudeDir) && existsSync(join(claudeDir, "skills"))) {
186
+ const agentsMd = join(basePath, "AGENTS.md");
187
+ return {
188
+ path: basePath,
189
+ type: "ck-internal",
190
+ claudeDir,
191
+ agentsMd: existsSync(agentsMd) ? agentsMd : null
192
+ };
193
+ }
194
+ }
195
+ return null;
196
+ }
197
+ function getEmbeddedTemplates() {
198
+ if (existsSync(TEMPLATES_DIR)) {
199
+ const agentsMd = join(TEMPLATES_DIR, "AGENTS.md");
200
+ return {
201
+ path: TEMPLATES_DIR,
202
+ type: "embedded",
203
+ claudeDir: TEMPLATES_DIR,
204
+ agentsMd: existsSync(agentsMd) ? agentsMd : null
205
+ };
206
+ }
207
+ return null;
208
+ }
209
+ function getGlobalInstallPath() {
210
+ if (process.platform === "win32") {
211
+ return join(process.env.APPDATA || join(homedir(), "AppData", "Roaming"), "claude");
212
+ }
213
+ return join(homedir(), ".claude");
214
+ }
215
+ function isAkProject(dir = process.cwd()) {
216
+ const akConfig = join(dir, ".ak", "state.json");
217
+ const claudeDir = join(dir, ".claude");
218
+ const geminiDir = join(dir, ".gemini");
219
+ const opencodeDir = join(dir, ".opencode");
220
+ const agentDir = join(dir, ".agent");
221
+ return existsSync(akConfig) || existsSync(claudeDir) || existsSync(geminiDir) || existsSync(opencodeDir) || existsSync(agentDir);
222
+ }
223
+ function getTargetDir(projectDir, target = "claude") {
224
+ const folder = TARGETS[target] || TARGETS.claude;
225
+ return join(projectDir, folder);
226
+ }
227
+ function resolveSource(sourceFlag) {
228
+ if (sourceFlag) {
229
+ const resolved = resolve(sourceFlag);
230
+ if (!existsSync(resolved)) {
231
+ return { error: `Source path not found: ${sourceFlag}` };
232
+ }
233
+ const claudeDir = join(resolved, ".claude");
234
+ const opencodeDir = join(resolved, ".opencode");
235
+ if (existsSync(claudeDir)) {
236
+ return {
237
+ path: resolved,
238
+ type: "custom",
239
+ claudeDir,
240
+ agentsMd: existsSync(join(resolved, "AGENTS.md")) ? join(resolved, "AGENTS.md") : null
241
+ };
242
+ }
243
+ if (existsSync(opencodeDir)) {
244
+ return {
245
+ path: resolved,
246
+ type: "custom",
247
+ claudeDir: opencodeDir,
248
+ agentsMd: existsSync(join(resolved, "AGENTS.md")) ? join(resolved, "AGENTS.md") : null
249
+ };
250
+ }
251
+ if (existsSync(join(resolved, "agents")) || existsSync(join(resolved, "commands"))) {
252
+ return {
253
+ path: resolved,
254
+ type: "custom",
255
+ claudeDir: resolved,
256
+ agentsMd: existsSync(join(resolved, "AGENTS.md")) ? join(resolved, "AGENTS.md") : null
257
+ };
258
+ }
259
+ return { error: `No templates found in: ${sourceFlag}` };
260
+ }
261
+ const ckInternal = getCkInternalSource();
262
+ if (ckInternal) {
263
+ return ckInternal;
264
+ }
265
+ const embedded = getEmbeddedTemplates();
266
+ if (embedded) {
267
+ return embedded;
268
+ }
269
+ return {
270
+ error: "No templates found. Reinstall: npm install -g thanh-kit"
271
+ };
272
+ }
273
+ var __filename, __dirname, CLI_ROOT, TEMPLATES_DIR, CK_INTERNAL_PATHS, TARGETS;
274
+ var init_paths = __esm({
275
+ "src/utils/paths.ts"() {
276
+ "use strict";
277
+ __filename = fileURLToPath(import.meta.url);
278
+ __dirname = dirname(__filename);
279
+ CLI_ROOT = __dirname.endsWith("dist") ? resolve(__dirname, "..") : resolve(__dirname, "../..");
280
+ TEMPLATES_DIR = join(CLI_ROOT, "templates");
281
+ CK_INTERNAL_PATHS = [
282
+ "/Users/nguyenthanh/AndroidStudioProjects/CK-Internal",
283
+ join(homedir(), "AndroidStudioProjects/CK-Internal"),
284
+ join(homedir(), "CK-Internal")
285
+ ];
286
+ TARGETS = {
287
+ claude: ".claude",
288
+ gemini: ".gemini",
289
+ discord: ".discord",
290
+ opencode: ".opencode",
291
+ generic: ".agent"
292
+ };
293
+ }
294
+ });
295
+
296
+ // src/targets/base-adapter.ts
297
+ import fs from "fs-extra";
298
+ import { join as join2, dirname as dirname2 } from "path";
299
+ var BaseTargetAdapter;
300
+ var init_base_adapter = __esm({
301
+ "src/targets/base-adapter.ts"() {
302
+ "use strict";
303
+ BaseTargetAdapter = class {
304
+ supports(feature) {
305
+ return this.config.features[feature];
306
+ }
307
+ getSupportedFeatures() {
308
+ return Object.entries(this.config.features).filter(([_, supported]) => supported).map(([feature]) => feature);
309
+ }
310
+ filterInstallItems(items) {
311
+ return {
312
+ agents: this.supports("agents") ? items.agents : [],
313
+ skills: this.supports("skills") ? items.skills : [],
314
+ commands: this.supports("commands") ? items.commands : [],
315
+ workflows: this.supports("workflows") ? items.workflows : [],
316
+ includeRouter: this.supports("router") && items.includeRouter,
317
+ includeHooks: this.supports("hooks") && items.includeHooks
318
+ };
319
+ }
320
+ /**
321
+ * Default: not supported - override in subclass if needed
322
+ */
323
+ async copyWorkflows(_items, _sourceDir, _targetDir, _mergeMode) {
324
+ return { copied: [], skipped: [], errors: [] };
325
+ }
326
+ async copyRouter(_sourceDir, _targetDir, _mergeMode) {
327
+ return { success: false, error: "Router not supported by this target" };
328
+ }
329
+ async copyHooks(_sourceDir, _targetDir, _mergeMode) {
330
+ return { success: false, error: "Hooks not supported by this target" };
331
+ }
332
+ async copyExtras(_sourceDir, _targetDir, _mergeMode) {
333
+ return [];
334
+ }
335
+ // Helper methods for common operations
336
+ async copyDirectory(dirName, sourceDir, destDir, mergeMode) {
337
+ const srcPath = join2(sourceDir, dirName);
338
+ if (!fs.existsSync(srcPath)) {
339
+ return { success: false, error: `${dirName} directory not found` };
340
+ }
341
+ try {
342
+ await fs.copy(srcPath, join2(destDir, dirName), { overwrite: !mergeMode });
343
+ return { success: true };
344
+ } catch (err) {
345
+ return { success: false, error: err.message };
346
+ }
347
+ }
348
+ async copyFile(srcPath, destPath, mergeMode) {
349
+ if (mergeMode && fs.existsSync(destPath)) {
350
+ return false;
351
+ }
352
+ if (fs.existsSync(srcPath)) {
353
+ await fs.ensureDir(dirname2(destPath));
354
+ await fs.copy(srcPath, destPath, { overwrite: !mergeMode });
355
+ return true;
356
+ }
357
+ return false;
358
+ }
359
+ async listItems(typeDir, extension) {
360
+ if (!fs.existsSync(typeDir)) {
361
+ return [];
362
+ }
363
+ const entries = fs.readdirSync(typeDir);
364
+ return entries.filter((e) => {
365
+ if (extension) {
366
+ return e.endsWith(extension) && e !== "README.md";
367
+ }
368
+ return e !== "README.md";
369
+ }).map((e) => extension ? e.replace(extension, "") : e);
370
+ }
371
+ getItemList(items, typeDir, extension) {
372
+ if (items === "all") {
373
+ return this.listItemsSync(typeDir, extension);
374
+ }
375
+ return items;
376
+ }
377
+ listItemsSync(typeDir, extension) {
378
+ if (!fs.existsSync(typeDir)) {
379
+ return [];
380
+ }
381
+ const entries = fs.readdirSync(typeDir);
382
+ let result = entries.filter((e) => e !== "README.md");
383
+ if (extension) {
384
+ result = result.filter((e) => e.endsWith(extension)).map((e) => e.replace(extension, ""));
385
+ }
386
+ return [...new Set(result.map((e) => e.replace(/\.md$/, "")))];
387
+ }
388
+ };
389
+ }
390
+ });
391
+
392
+ // src/targets/claude-adapter.ts
393
+ import fs2 from "fs-extra";
394
+ import { join as join3 } from "path";
395
+ var ClaudeAdapter;
396
+ var init_claude_adapter = __esm({
397
+ "src/targets/claude-adapter.ts"() {
398
+ "use strict";
399
+ init_base_adapter();
400
+ ClaudeAdapter = class extends BaseTargetAdapter {
401
+ config = {
402
+ name: "claude",
403
+ displayName: "Claude Code",
404
+ directory: ".claude",
405
+ features: {
406
+ agents: true,
407
+ skills: true,
408
+ commands: true,
409
+ workflows: true,
410
+ router: true,
411
+ hooks: true,
412
+ memory: true,
413
+ scripts: true,
414
+ "output-styles": true
415
+ }
416
+ };
417
+ async copyAgents(items, sourceDir, targetDir, mergeMode) {
418
+ const typeDir = join3(sourceDir, "agents");
419
+ const destTypeDir = join3(targetDir, "agents");
420
+ if (!fs2.existsSync(typeDir)) {
421
+ return { copied: [], skipped: [], errors: [] };
422
+ }
423
+ await fs2.ensureDir(destTypeDir);
424
+ if (items === "all") {
425
+ await fs2.copy(typeDir, destTypeDir, { overwrite: !mergeMode });
426
+ const entries = fs2.readdirSync(typeDir).filter((e) => e.endsWith(".md") && e !== "README.md");
427
+ return { copied: entries.map((e) => e.replace(".md", "")), skipped: [], errors: [] };
428
+ }
429
+ const copied = [];
430
+ const skipped = [];
431
+ const errors = [];
432
+ for (const agent of items) {
433
+ try {
434
+ const srcPath = join3(typeDir, agent + ".md");
435
+ if (!fs2.existsSync(srcPath)) {
436
+ skipped.push(agent);
437
+ continue;
438
+ }
439
+ const destPath = join3(destTypeDir, agent + ".md");
440
+ if (mergeMode && fs2.existsSync(destPath)) {
441
+ skipped.push(agent);
442
+ continue;
443
+ }
444
+ await fs2.copy(srcPath, destPath, { overwrite: !mergeMode });
445
+ copied.push(agent);
446
+ } catch (err) {
447
+ errors.push({ item: agent, error: err.message });
448
+ }
449
+ }
450
+ return { copied, skipped, errors };
451
+ }
452
+ async copySkills(items, sourceDir, targetDir, mergeMode) {
453
+ const typeDir = join3(sourceDir, "skills");
454
+ const destTypeDir = join3(targetDir, "skills");
455
+ if (!fs2.existsSync(typeDir)) {
456
+ return { copied: [], skipped: [], errors: [] };
457
+ }
458
+ await fs2.ensureDir(destTypeDir);
459
+ if (items === "all") {
460
+ await fs2.copy(typeDir, destTypeDir, { overwrite: !mergeMode });
461
+ const entries = fs2.readdirSync(typeDir).filter((e) => {
462
+ const fullPath = join3(typeDir, e);
463
+ return fs2.statSync(fullPath).isDirectory() && fs2.existsSync(join3(fullPath, "SKILL.md"));
464
+ });
465
+ return { copied: entries, skipped: [], errors: [] };
466
+ }
467
+ const copied = [];
468
+ const skipped = [];
469
+ const errors = [];
470
+ for (const skill of items) {
471
+ try {
472
+ const srcPath = join3(typeDir, skill);
473
+ if (!fs2.existsSync(srcPath) || !fs2.statSync(srcPath).isDirectory()) {
474
+ skipped.push(skill);
475
+ continue;
476
+ }
477
+ if (!fs2.existsSync(join3(srcPath, "SKILL.md"))) {
478
+ skipped.push(skill);
479
+ continue;
480
+ }
481
+ const destPath = join3(destTypeDir, skill);
482
+ if (mergeMode && fs2.existsSync(destPath)) {
483
+ skipped.push(skill);
484
+ continue;
485
+ }
486
+ await fs2.copy(srcPath, destPath, { overwrite: !mergeMode });
487
+ copied.push(skill);
488
+ } catch (err) {
489
+ errors.push({ item: skill, error: err.message });
490
+ }
491
+ }
492
+ return { copied, skipped, errors };
493
+ }
494
+ async copyCommands(items, sourceDir, targetDir, mergeMode) {
495
+ const typeDir = join3(sourceDir, "commands");
496
+ const destTypeDir = join3(targetDir, "commands");
497
+ if (!fs2.existsSync(typeDir)) {
498
+ return { copied: [], skipped: [], errors: [] };
499
+ }
500
+ await fs2.ensureDir(destTypeDir);
501
+ if (items === "all") {
502
+ await fs2.copy(typeDir, destTypeDir, { overwrite: !mergeMode });
503
+ const entries = fs2.readdirSync(typeDir);
504
+ return { copied: [...new Set(entries.map((e) => e.replace(".md", "")))], skipped: [], errors: [] };
505
+ }
506
+ const copied = [];
507
+ const skipped = [];
508
+ const errors = [];
509
+ for (const item of items) {
510
+ try {
511
+ const itemPath = join3(typeDir, item);
512
+ const itemPathMd = itemPath + ".md";
513
+ let srcPath = null;
514
+ if (fs2.existsSync(itemPath)) {
515
+ srcPath = itemPath;
516
+ } else if (fs2.existsSync(itemPathMd)) {
517
+ srcPath = itemPathMd;
518
+ }
519
+ if (!srcPath) {
520
+ skipped.push(item);
521
+ continue;
522
+ }
523
+ const stat = fs2.statSync(srcPath);
524
+ const destPath = stat.isDirectory() ? join3(destTypeDir, item) : join3(destTypeDir, item + ".md");
525
+ if (mergeMode && fs2.existsSync(destPath)) {
526
+ skipped.push(item);
527
+ continue;
528
+ }
529
+ await fs2.copy(srcPath, destPath, { overwrite: !mergeMode });
530
+ copied.push(item);
531
+ } catch (err) {
532
+ errors.push({ item, error: err.message });
533
+ }
534
+ }
535
+ return { copied, skipped, errors };
536
+ }
537
+ async copyWorkflows(items, sourceDir, targetDir, mergeMode) {
538
+ const typeDir = join3(sourceDir, "workflows");
539
+ const destTypeDir = join3(targetDir, "workflows");
540
+ if (!fs2.existsSync(typeDir)) {
541
+ return { copied: [], skipped: [], errors: [] };
542
+ }
543
+ await fs2.ensureDir(destTypeDir);
544
+ if (items === "all") {
545
+ await fs2.copy(typeDir, destTypeDir, { overwrite: !mergeMode });
546
+ const entries = fs2.readdirSync(typeDir);
547
+ return { copied: entries.map((e) => e.replace(".md", "")), skipped: [], errors: [] };
548
+ }
549
+ const copied = [];
550
+ const skipped = [];
551
+ const errors = [];
552
+ for (const item of items) {
553
+ try {
554
+ const srcPath = join3(typeDir, item + ".md");
555
+ if (!fs2.existsSync(srcPath)) {
556
+ skipped.push(item);
557
+ continue;
558
+ }
559
+ const destPath = join3(destTypeDir, item + ".md");
560
+ if (mergeMode && fs2.existsSync(destPath)) {
561
+ skipped.push(item);
562
+ continue;
563
+ }
564
+ await fs2.copy(srcPath, destPath, { overwrite: !mergeMode });
565
+ copied.push(item);
566
+ } catch (err) {
567
+ errors.push({ item, error: err.message });
568
+ }
569
+ }
570
+ return { copied, skipped, errors };
571
+ }
572
+ async copyRouter(sourceDir, targetDir, mergeMode) {
573
+ return this.copyDirectory("router", sourceDir, targetDir, mergeMode);
574
+ }
575
+ async copyHooks(sourceDir, targetDir, mergeMode) {
576
+ return this.copyDirectory("hooks", sourceDir, targetDir, mergeMode);
577
+ }
578
+ async copyExtras(sourceDir, targetDir, mergeMode) {
579
+ const extras = ["memory", "output-styles", "scripts"];
580
+ const copied = [];
581
+ for (const extra of extras) {
582
+ const result = await this.copyDirectory(extra, sourceDir, targetDir, mergeMode);
583
+ if (result.success) {
584
+ copied.push(extra);
585
+ }
586
+ }
587
+ return copied;
588
+ }
589
+ async copyBaseFiles(targetDir, mergeMode) {
590
+ const { CLI_ROOT: CLI_ROOT2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
591
+ const sourceDir = join3(CLI_ROOT2, "templates");
592
+ const baseFiles = ["README.md", "settings.json", ".env.example", "statusline.cjs", "statusline.ps1", "statusline.sh"];
593
+ const copied = [];
594
+ for (const file of baseFiles) {
595
+ const srcPath = join3(sourceDir, file);
596
+ const destPath = join3(targetDir, file);
597
+ if (await this.copyFile(srcPath, destPath, mergeMode)) {
598
+ copied.push(file);
599
+ }
600
+ }
601
+ return copied;
602
+ }
603
+ };
604
+ }
605
+ });
606
+
607
+ // src/targets/gemini-adapter.ts
608
+ import fs3 from "fs-extra";
609
+ import { join as join4, dirname as dirname3 } from "path";
610
+ function parseFrontmatter(content) {
611
+ const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
612
+ if (!match) {
613
+ return { frontmatter: "", body: content };
614
+ }
615
+ return { frontmatter: match[1], body: match[2] };
616
+ }
617
+ function escapeTomlString(str) {
618
+ return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\t/g, "\\t");
619
+ }
620
+ function convertAgentToGemini(mdContent) {
621
+ const { frontmatter, body } = parseFrontmatter(mdContent);
622
+ if (!frontmatter) return mdContent;
623
+ let converted = frontmatter;
624
+ for (const [claudeModel, geminiModel] of Object.entries(MODEL_MAP)) {
625
+ const regex = new RegExp(`^model:\\s*${claudeModel}\\s*$`, "m");
626
+ if (geminiModel) {
627
+ converted = converted.replace(regex, `model: ${geminiModel}`);
628
+ } else {
629
+ converted = converted.replace(regex, "");
630
+ }
631
+ }
632
+ converted = converted.replace(/^tools:\s*.+$/m, "");
633
+ if (!converted.includes("kind:")) {
634
+ converted = converted.trim() + "\nkind: local";
635
+ }
636
+ return `---
637
+ ${converted.trim()}
638
+ ---
639
+ ${body}`;
640
+ }
641
+ function convertCommandToToml(mdContent) {
642
+ const { frontmatter, body } = parseFrontmatter(mdContent);
643
+ const descMatch = frontmatter.match(/description:\s*(.+)/);
644
+ const description = descMatch ? descMatch[1].trim() : "";
645
+ const prompt = body.trim().replace(/\$ARGUMENTS/g, "{{args}}");
646
+ const lines = [];
647
+ if (description) {
648
+ lines.push(`description = "${escapeTomlString(description)}"`);
649
+ }
650
+ lines.push(`prompt = '''
651
+ ${prompt}
652
+ '''`);
653
+ return lines.join("\n");
654
+ }
655
+ var MODEL_MAP, GeminiAdapter;
656
+ var init_gemini_adapter = __esm({
657
+ "src/targets/gemini-adapter.ts"() {
658
+ "use strict";
659
+ init_base_adapter();
660
+ MODEL_MAP = {
661
+ "opus": "gemini-2.5-pro",
662
+ "sonnet": "gemini-2.5-flash",
663
+ "haiku": "gemini-2.0-flash-lite",
664
+ "inherit": ""
665
+ // Remove inherit, let Gemini use default
666
+ };
667
+ GeminiAdapter = class extends BaseTargetAdapter {
668
+ config = {
669
+ name: "gemini",
670
+ displayName: "Gemini CLI",
671
+ directory: ".gemini",
672
+ features: {
673
+ agents: true,
674
+ skills: true,
675
+ commands: true,
676
+ workflows: false,
677
+ router: false,
678
+ hooks: false,
679
+ memory: false,
680
+ scripts: false,
681
+ "output-styles": false
682
+ }
683
+ };
684
+ async copyAgents(items, sourceDir, targetDir, mergeMode) {
685
+ const typeDir = join4(sourceDir, "agents");
686
+ const destTypeDir = join4(targetDir, "agents");
687
+ if (!fs3.existsSync(typeDir)) {
688
+ return { copied: [], skipped: [], errors: [] };
689
+ }
690
+ await fs3.ensureDir(destTypeDir);
691
+ let agentList;
692
+ if (items === "all") {
693
+ const entries = fs3.readdirSync(typeDir);
694
+ agentList = entries.filter((e) => e.endsWith(".md") && e !== "README.md").map((e) => e.replace(".md", ""));
695
+ } else {
696
+ agentList = items;
697
+ }
698
+ const copied = [];
699
+ const skipped = [];
700
+ const errors = [];
701
+ for (const agent of agentList) {
702
+ try {
703
+ const srcPath = join4(typeDir, agent + ".md");
704
+ if (!fs3.existsSync(srcPath)) {
705
+ skipped.push(agent);
706
+ continue;
707
+ }
708
+ const destPath = join4(destTypeDir, agent + ".md");
709
+ if (mergeMode && fs3.existsSync(destPath)) {
710
+ skipped.push(agent);
711
+ continue;
712
+ }
713
+ const mdContent = fs3.readFileSync(srcPath, "utf-8");
714
+ const convertedContent = convertAgentToGemini(mdContent);
715
+ await fs3.writeFile(destPath, convertedContent, "utf-8");
716
+ copied.push(agent);
717
+ } catch (err) {
718
+ errors.push({ item: agent, error: err.message });
719
+ }
720
+ }
721
+ return { copied, skipped, errors };
722
+ }
723
+ async copySkills(items, sourceDir, targetDir, mergeMode) {
724
+ const typeDir = join4(sourceDir, "skills");
725
+ const destTypeDir = join4(targetDir, "skills");
726
+ if (!fs3.existsSync(typeDir)) {
727
+ return { copied: [], skipped: [], errors: [] };
728
+ }
729
+ await fs3.ensureDir(destTypeDir);
730
+ let skillList;
731
+ if (items === "all") {
732
+ const entries = fs3.readdirSync(typeDir);
733
+ skillList = entries.filter((e) => {
734
+ const fullPath = join4(typeDir, e);
735
+ return fs3.statSync(fullPath).isDirectory() && fs3.existsSync(join4(fullPath, "SKILL.md"));
736
+ });
737
+ } else {
738
+ skillList = items;
739
+ }
740
+ const copied = [];
741
+ const skipped = [];
742
+ const errors = [];
743
+ for (const skill of skillList) {
744
+ try {
745
+ const srcPath = join4(typeDir, skill);
746
+ if (!fs3.existsSync(srcPath) || !fs3.statSync(srcPath).isDirectory()) {
747
+ skipped.push(skill);
748
+ continue;
749
+ }
750
+ if (!fs3.existsSync(join4(srcPath, "SKILL.md"))) {
751
+ skipped.push(skill);
752
+ continue;
753
+ }
754
+ const destPath = join4(destTypeDir, skill);
755
+ if (mergeMode && fs3.existsSync(destPath)) {
756
+ skipped.push(skill);
757
+ continue;
758
+ }
759
+ await fs3.copy(srcPath, destPath, { overwrite: !mergeMode });
760
+ copied.push(skill);
761
+ } catch (err) {
762
+ errors.push({ item: skill, error: err.message });
763
+ }
764
+ }
765
+ return { copied, skipped, errors };
766
+ }
767
+ async copyCommands(items, sourceDir, targetDir, mergeMode) {
768
+ const typeDir = join4(sourceDir, "commands");
769
+ const destTypeDir = join4(targetDir, "commands");
770
+ if (!fs3.existsSync(typeDir)) {
771
+ return { copied: [], skipped: [], errors: [] };
772
+ }
773
+ await fs3.ensureDir(destTypeDir);
774
+ let itemList;
775
+ if (items === "all") {
776
+ const entries = fs3.readdirSync(typeDir);
777
+ itemList = [...new Set(entries.map((e) => e.replace(".md", "")))];
778
+ } else {
779
+ itemList = items;
780
+ }
781
+ const copied = [];
782
+ const skipped = [];
783
+ const errors = [];
784
+ for (const item of itemList) {
785
+ try {
786
+ const srcPathMd = join4(typeDir, item + ".md");
787
+ const srcPathDir = join4(typeDir, item);
788
+ let copiedSomething = false;
789
+ if (fs3.existsSync(srcPathMd) && fs3.statSync(srcPathMd).isFile()) {
790
+ const destPath = join4(destTypeDir, item + ".toml");
791
+ if (!(mergeMode && fs3.existsSync(destPath))) {
792
+ await fs3.ensureDir(dirname3(destPath));
793
+ const mdContent = fs3.readFileSync(srcPathMd, "utf-8");
794
+ const tomlContent = convertCommandToToml(mdContent);
795
+ await fs3.writeFile(destPath, tomlContent, "utf-8");
796
+ copiedSomething = true;
797
+ }
798
+ }
799
+ if (fs3.existsSync(srcPathDir) && fs3.statSync(srcPathDir).isDirectory()) {
800
+ await this.convertDirectoryToToml(srcPathDir, join4(destTypeDir, item), mergeMode);
801
+ copiedSomething = true;
802
+ }
803
+ if (copiedSomething) {
804
+ copied.push(item);
805
+ } else {
806
+ skipped.push(item);
807
+ }
808
+ } catch (err) {
809
+ errors.push({ item, error: err.message });
810
+ }
811
+ }
812
+ return { copied, skipped, errors };
813
+ }
814
+ async convertDirectoryToToml(srcDir, destDir, mergeMode) {
815
+ await fs3.ensureDir(destDir);
816
+ const entries = fs3.readdirSync(srcDir);
817
+ for (const entry of entries) {
818
+ const srcPath = join4(srcDir, entry);
819
+ const stat = fs3.statSync(srcPath);
820
+ if (stat.isDirectory()) {
821
+ await this.convertDirectoryToToml(srcPath, join4(destDir, entry), mergeMode);
822
+ } else if (entry.endsWith(".md")) {
823
+ const destPath = join4(destDir, entry.replace(".md", ".toml"));
824
+ if (mergeMode && fs3.existsSync(destPath)) {
825
+ continue;
826
+ }
827
+ const mdContent = fs3.readFileSync(srcPath, "utf-8");
828
+ const tomlContent = convertCommandToToml(mdContent);
829
+ await fs3.writeFile(destPath, tomlContent, "utf-8");
830
+ } else {
831
+ const destPath = join4(destDir, entry);
832
+ if (mergeMode && fs3.existsSync(destPath)) {
833
+ continue;
834
+ }
835
+ await fs3.copy(srcPath, destPath, { overwrite: !mergeMode });
836
+ }
837
+ }
838
+ }
839
+ async copyBaseFiles(targetDir, mergeMode) {
840
+ const { CLI_ROOT: CLI_ROOT2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
841
+ const geminiTemplates = join4(CLI_ROOT2, "templates", "gemini");
842
+ const copied = [];
843
+ const settingsPath = join4(geminiTemplates, "settings.json");
844
+ const destSettingsPath = join4(targetDir, "settings.json");
845
+ if (fs3.existsSync(settingsPath)) {
846
+ if (!(mergeMode && fs3.existsSync(destSettingsPath))) {
847
+ await fs3.copy(settingsPath, destSettingsPath, { overwrite: !mergeMode });
848
+ copied.push("settings.json");
849
+ }
850
+ }
851
+ return copied;
852
+ }
853
+ };
854
+ }
855
+ });
856
+
857
+ // src/targets/discord-adapter.ts
858
+ import fs4 from "fs-extra";
859
+ import { join as join5, dirname as dirname4 } from "path";
860
+ function parseFrontmatter2(content) {
861
+ const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
862
+ if (!match) {
863
+ return { frontmatter: "", body: content, description: "", argumentHint: "" };
864
+ }
865
+ const frontmatter = match[1];
866
+ const body = match[2].trim();
867
+ const descMatch = frontmatter.match(/description:\s*(.+)/);
868
+ const argMatch = frontmatter.match(/argument-hint:\s*(.+)/);
869
+ return {
870
+ frontmatter,
871
+ body,
872
+ description: descMatch ? descMatch[1].trim() : "",
873
+ argumentHint: argMatch ? argMatch[1].trim() : ""
874
+ };
875
+ }
876
+ function convertAgentToDiscord(mdContent) {
877
+ const { frontmatter, body } = parseFrontmatter2(mdContent);
878
+ if (!frontmatter) return mdContent;
879
+ let converted = frontmatter;
880
+ for (const [claudeModel, discordModel] of Object.entries(MODEL_MAP2)) {
881
+ const regex = new RegExp(`^model:\\s*${claudeModel}\\s*$`, "m");
882
+ if (discordModel) {
883
+ converted = converted.replace(regex, `model: ${discordModel}`);
884
+ } else {
885
+ converted = converted.replace(regex, "");
886
+ }
887
+ }
888
+ converted = converted.replace(/^tools:\s*.+$/m, "");
889
+ if (!converted.includes("kind:")) {
890
+ converted = converted.trim() + "\nkind: local";
891
+ }
892
+ return `---
893
+ ${converted.trim()}
894
+ ---
895
+ ${body}`;
896
+ }
897
+ function extractKeywords(content, commandName) {
898
+ const keywords = /* @__PURE__ */ new Set();
899
+ keywords.add(commandName);
900
+ keywords.add(commandName.replace(/-/g, " "));
901
+ const intentMap = {
902
+ "plan": ["plan", "design", "architect", "implement", "create plan"],
903
+ "brainstorm": ["brainstorm", "ideas", "options", "alternatives"],
904
+ "fix": ["fix", "debug", "error", "broken", "issue", "bug"],
905
+ "code": ["code", "implement", "build", "develop", "write code"],
906
+ "review": ["review", "check", "audit", "look at"],
907
+ "test": ["test", "testing", "spec", "unit test"],
908
+ "scout": ["scout", "search", "find", "explore codebase"],
909
+ "debug": ["debug", "trace", "diagnose", "investigate"]
910
+ };
911
+ const baseName = commandName.split("/")[0].split(":")[0];
912
+ if (intentMap[baseName]) {
913
+ intentMap[baseName].forEach((k) => keywords.add(k));
914
+ }
915
+ return Array.from(keywords).slice(0, 10);
916
+ }
917
+ function convertCommandToSkill(mdContent, commandName) {
918
+ const { description, argumentHint, body } = parseFrontmatter2(mdContent);
919
+ const prompt = body.replace(/\$ARGUMENTS/g, "{{args}}");
920
+ const keywords = extractKeywords(body, commandName);
921
+ return `---
922
+ name: ${commandName.replace(/\//g, "-")}
923
+ description: ${description || `Execute ${commandName} task`}
924
+ user-invocable: true
925
+ disable-model-invocation: false
926
+ metadata: {"openclaw": {"always": true}}
927
+ ---
928
+
929
+ # ${commandName.charAt(0).toUpperCase() + commandName.slice(1).replace(/-/g, " ")}
930
+
931
+ ## Trigger Conditions
932
+
933
+ Activate when user mentions:
934
+ ${keywords.map((k) => `- "${k}"`).join("\n")}
935
+
936
+ ## Input
937
+ ${argumentHint ? `Expected input: ${argumentHint.replace("$ARGUMENTS", "{{args}}")}` : "User provides task description in natural language."}
938
+
939
+ ## Workflow
940
+
941
+ ${prompt}
942
+
943
+ ## Output Format
944
+
945
+ Provide clear, actionable response based on the workflow above.
946
+ `;
947
+ }
948
+ var MODEL_MAP2, DiscordAdapter;
949
+ var init_discord_adapter = __esm({
950
+ "src/targets/discord-adapter.ts"() {
951
+ "use strict";
952
+ init_base_adapter();
953
+ MODEL_MAP2 = {
954
+ "opus": "claude-3-opus",
955
+ "sonnet": "claude-3-sonnet",
956
+ "haiku": "claude-3-haiku",
957
+ "inherit": ""
958
+ };
959
+ DiscordAdapter = class extends BaseTargetAdapter {
960
+ config = {
961
+ name: "discord",
962
+ displayName: "Discord + OpenClaw",
963
+ directory: ".discord",
964
+ features: {
965
+ agents: true,
966
+ skills: true,
967
+ commands: true,
968
+ workflows: false,
969
+ router: false,
970
+ hooks: false,
971
+ memory: false,
972
+ scripts: false,
973
+ "output-styles": false
974
+ }
975
+ };
976
+ async copyAgents(items, sourceDir, targetDir, mergeMode) {
977
+ const typeDir = join5(sourceDir, "agents");
978
+ const destTypeDir = join5(targetDir, "agents");
979
+ if (!fs4.existsSync(typeDir)) {
980
+ return { copied: [], skipped: [], errors: [] };
981
+ }
982
+ await fs4.ensureDir(destTypeDir);
983
+ let agentList;
984
+ if (items === "all") {
985
+ const entries = fs4.readdirSync(typeDir);
986
+ agentList = entries.filter((e) => e.endsWith(".md") && e !== "README.md").map((e) => e.replace(".md", ""));
987
+ } else {
988
+ agentList = items;
989
+ }
990
+ const copied = [];
991
+ const skipped = [];
992
+ const errors = [];
993
+ for (const agent of agentList) {
994
+ try {
995
+ const srcPath = join5(typeDir, agent + ".md");
996
+ if (!fs4.existsSync(srcPath)) {
997
+ skipped.push(agent);
998
+ continue;
999
+ }
1000
+ const destPath = join5(destTypeDir, agent + ".md");
1001
+ if (mergeMode && fs4.existsSync(destPath)) {
1002
+ skipped.push(agent);
1003
+ continue;
1004
+ }
1005
+ const mdContent = fs4.readFileSync(srcPath, "utf-8");
1006
+ const convertedContent = convertAgentToDiscord(mdContent);
1007
+ await fs4.writeFile(destPath, convertedContent, "utf-8");
1008
+ copied.push(agent);
1009
+ } catch (err) {
1010
+ errors.push({ item: agent, error: err.message });
1011
+ }
1012
+ }
1013
+ return { copied, skipped, errors };
1014
+ }
1015
+ async copySkills(items, sourceDir, targetDir, mergeMode) {
1016
+ const typeDir = join5(sourceDir, "skills");
1017
+ const destTypeDir = join5(targetDir, "skills");
1018
+ if (!fs4.existsSync(typeDir)) {
1019
+ return { copied: [], skipped: [], errors: [] };
1020
+ }
1021
+ await fs4.ensureDir(destTypeDir);
1022
+ let skillList;
1023
+ if (items === "all") {
1024
+ const entries = fs4.readdirSync(typeDir);
1025
+ skillList = entries.filter((e) => {
1026
+ const fullPath = join5(typeDir, e);
1027
+ return fs4.statSync(fullPath).isDirectory() && fs4.existsSync(join5(fullPath, "SKILL.md"));
1028
+ });
1029
+ } else {
1030
+ skillList = items;
1031
+ }
1032
+ const copied = [];
1033
+ const skipped = [];
1034
+ const errors = [];
1035
+ for (const skill of skillList) {
1036
+ try {
1037
+ const srcPath = join5(typeDir, skill);
1038
+ if (!fs4.existsSync(srcPath) || !fs4.statSync(srcPath).isDirectory()) {
1039
+ skipped.push(skill);
1040
+ continue;
1041
+ }
1042
+ if (!fs4.existsSync(join5(srcPath, "SKILL.md"))) {
1043
+ skipped.push(skill);
1044
+ continue;
1045
+ }
1046
+ const destPath = join5(destTypeDir, skill);
1047
+ if (mergeMode && fs4.existsSync(destPath)) {
1048
+ skipped.push(skill);
1049
+ continue;
1050
+ }
1051
+ await fs4.copy(srcPath, destPath, { overwrite: !mergeMode });
1052
+ copied.push(skill);
1053
+ } catch (err) {
1054
+ errors.push({ item: skill, error: err.message });
1055
+ }
1056
+ }
1057
+ const bundledCopied = await this.copyBundledSkills(targetDir, mergeMode);
1058
+ copied.push(...bundledCopied);
1059
+ return { copied, skipped, errors };
1060
+ }
1061
+ async copyCommands(items, sourceDir, targetDir, mergeMode) {
1062
+ const typeDir = join5(sourceDir, "commands");
1063
+ const destTypeDir = join5(targetDir, "commands");
1064
+ const destSkillsDir = join5(targetDir, "skills");
1065
+ if (!fs4.existsSync(typeDir)) {
1066
+ return { copied: [], skipped: [], errors: [] };
1067
+ }
1068
+ await fs4.ensureDir(destTypeDir);
1069
+ await fs4.ensureDir(destSkillsDir);
1070
+ let itemList;
1071
+ if (items === "all") {
1072
+ const entries = fs4.readdirSync(typeDir);
1073
+ itemList = entries.filter((e) => e.endsWith(".md") && e !== "README.md").map((e) => e.replace(".md", ""));
1074
+ const dirs = entries.filter((e) => {
1075
+ const fullPath = join5(typeDir, e);
1076
+ return fs4.statSync(fullPath).isDirectory();
1077
+ });
1078
+ itemList = [.../* @__PURE__ */ new Set([...itemList, ...dirs])];
1079
+ } else {
1080
+ itemList = items;
1081
+ }
1082
+ const copied = [];
1083
+ const skipped = [];
1084
+ const errors = [];
1085
+ const commandsConfig = {};
1086
+ for (const item of itemList) {
1087
+ try {
1088
+ const srcPathMd = join5(typeDir, item + ".md");
1089
+ const srcPathDir = join5(typeDir, item);
1090
+ if (fs4.existsSync(srcPathMd) && fs4.statSync(srcPathMd).isFile()) {
1091
+ const destPath = join5(destTypeDir, item + ".md");
1092
+ const skillDir = join5(destSkillsDir, item.replace(/\//g, "-"));
1093
+ const skillPath = join5(skillDir, "SKILL.md");
1094
+ if (!(mergeMode && fs4.existsSync(destPath))) {
1095
+ await fs4.ensureDir(dirname4(destPath));
1096
+ const mdContent = fs4.readFileSync(srcPathMd, "utf-8");
1097
+ await fs4.copy(srcPathMd, destPath, { overwrite: !mergeMode });
1098
+ if (!(mergeMode && fs4.existsSync(skillPath))) {
1099
+ await fs4.ensureDir(skillDir);
1100
+ const skillContent = convertCommandToSkill(mdContent, item);
1101
+ await fs4.writeFile(skillPath, skillContent, "utf-8");
1102
+ }
1103
+ const { description, body } = parseFrontmatter2(mdContent);
1104
+ commandsConfig[item] = {
1105
+ description: description || `Execute ${item} command`,
1106
+ prompt: body.replace(/\$ARGUMENTS/g, "{{args}}")
1107
+ };
1108
+ copied.push(item);
1109
+ } else {
1110
+ skipped.push(item);
1111
+ }
1112
+ }
1113
+ if (fs4.existsSync(srcPathDir) && fs4.statSync(srcPathDir).isDirectory()) {
1114
+ await this.copyNestedCommands(srcPathDir, destTypeDir, destSkillsDir, item, mergeMode, commandsConfig);
1115
+ copied.push(item + "/*");
1116
+ }
1117
+ } catch (err) {
1118
+ errors.push({ item, error: err.message });
1119
+ }
1120
+ }
1121
+ const configPath = join5(targetDir, "commands.json5");
1122
+ if (Object.keys(commandsConfig).length > 0 && !(mergeMode && fs4.existsSync(configPath))) {
1123
+ const json5Content = this.generateCommandsJson5(commandsConfig);
1124
+ await fs4.writeFile(configPath, json5Content, "utf-8");
1125
+ }
1126
+ return { copied, skipped, errors };
1127
+ }
1128
+ async copyNestedCommands(srcDir, destDir, destSkillsDir, parentName, mergeMode, commandsConfig) {
1129
+ const destTypeDir = join5(destDir, parentName);
1130
+ await fs4.ensureDir(destTypeDir);
1131
+ const entries = fs4.readdirSync(srcDir);
1132
+ for (const entry of entries) {
1133
+ const srcPath = join5(srcDir, entry);
1134
+ const stat = fs4.statSync(srcPath);
1135
+ if (stat.isDirectory()) {
1136
+ await this.copyNestedCommands(
1137
+ srcPath,
1138
+ destTypeDir,
1139
+ destSkillsDir,
1140
+ entry,
1141
+ mergeMode,
1142
+ commandsConfig
1143
+ );
1144
+ } else if (entry.endsWith(".md") && entry !== "README.md") {
1145
+ const destPath = join5(destTypeDir, entry);
1146
+ const cmdName = `${parentName}/${entry.replace(".md", "")}`;
1147
+ const skillName = cmdName.replace(/\//g, "-");
1148
+ const skillDir = join5(destSkillsDir, skillName);
1149
+ const skillPath = join5(skillDir, "SKILL.md");
1150
+ if (mergeMode && fs4.existsSync(destPath)) {
1151
+ continue;
1152
+ }
1153
+ const mdContent = fs4.readFileSync(srcPath, "utf-8");
1154
+ await fs4.copy(srcPath, destPath, { overwrite: !mergeMode });
1155
+ if (!(mergeMode && fs4.existsSync(skillPath))) {
1156
+ await fs4.ensureDir(skillDir);
1157
+ const skillContent = convertCommandToSkill(mdContent, skillName);
1158
+ await fs4.writeFile(skillPath, skillContent, "utf-8");
1159
+ }
1160
+ const { description, body } = parseFrontmatter2(mdContent);
1161
+ commandsConfig[cmdName] = {
1162
+ description: description || `Execute ${cmdName} command`,
1163
+ prompt: body.replace(/\$ARGUMENTS/g, "{{args}}")
1164
+ };
1165
+ }
1166
+ }
1167
+ }
1168
+ generateCommandsJson5(commands) {
1169
+ const lines = [
1170
+ "// Clawbot Commands Configuration",
1171
+ "// Generated by Thanh Kit CLI",
1172
+ "{",
1173
+ ' "commands": {'
1174
+ ];
1175
+ const cmdEntries = Object.entries(commands);
1176
+ cmdEntries.forEach(([name, cmd], index) => {
1177
+ const safeName = name.replace(/\//g, ":");
1178
+ const isLast = index === cmdEntries.length - 1;
1179
+ lines.push(` "${safeName}": {`);
1180
+ lines.push(` "description": ${JSON.stringify(cmd.description)},`);
1181
+ lines.push(` "prompt": ${JSON.stringify(cmd.prompt)}`);
1182
+ lines.push(` }${isLast ? "" : ","}`);
1183
+ });
1184
+ lines.push(" }");
1185
+ lines.push("}");
1186
+ return lines.join("\n");
1187
+ }
1188
+ async copyBundledSkills(targetDir, mergeMode) {
1189
+ const { CLI_ROOT: CLI_ROOT2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
1190
+ const bundledSkillsDir = join5(CLI_ROOT2, "templates", "discord", "skills");
1191
+ const destSkillsDir = join5(targetDir, "skills");
1192
+ const copied = [];
1193
+ if (!fs4.existsSync(bundledSkillsDir)) {
1194
+ return copied;
1195
+ }
1196
+ await fs4.ensureDir(destSkillsDir);
1197
+ const skills = fs4.readdirSync(bundledSkillsDir);
1198
+ for (const skill of skills) {
1199
+ const srcPath = join5(bundledSkillsDir, skill);
1200
+ const destPath = join5(destSkillsDir, skill);
1201
+ if (fs4.statSync(srcPath).isDirectory()) {
1202
+ if (mergeMode && fs4.existsSync(destPath)) {
1203
+ continue;
1204
+ }
1205
+ await fs4.copy(srcPath, destPath, { overwrite: !mergeMode });
1206
+ copied.push(`bundled:${skill}`);
1207
+ }
1208
+ }
1209
+ return copied;
1210
+ }
1211
+ async copyBaseFiles(targetDir, mergeMode) {
1212
+ const { CLI_ROOT: CLI_ROOT2 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
1213
+ const discordTemplates = join5(CLI_ROOT2, "templates", "discord");
1214
+ const copied = [];
1215
+ const filesToCopy = ["config.json5", "README.md"];
1216
+ for (const file of filesToCopy) {
1217
+ const srcPath = join5(discordTemplates, file);
1218
+ const destPath = join5(targetDir, file);
1219
+ if (fs4.existsSync(srcPath)) {
1220
+ if (mergeMode && fs4.existsSync(destPath)) {
1221
+ continue;
1222
+ }
1223
+ await fs4.copy(srcPath, destPath, { overwrite: !mergeMode });
1224
+ copied.push(file);
1225
+ }
1226
+ }
1227
+ return copied;
1228
+ }
1229
+ /**
1230
+ * Update Discord config with bot token
1231
+ */
1232
+ async updateConfig(targetDir, token, guildId) {
1233
+ const configPath = join5(targetDir, "config.json5");
1234
+ if (!fs4.existsSync(configPath)) {
1235
+ return;
1236
+ }
1237
+ let content = await fs4.readFile(configPath, "utf-8");
1238
+ content = content.replace(
1239
+ '"token": "${DISCORD_BOT_TOKEN}"',
1240
+ `"token": "${token}"`
1241
+ );
1242
+ if (guildId) {
1243
+ const guildConfig = `"${guildId}": {
1244
+ "requireMention": true,
1245
+ "users": [],
1246
+ "roles": [],
1247
+ "channels": {}
1248
+ }`;
1249
+ content = content.replace(
1250
+ '"guilds": {\n // Example guild configuration',
1251
+ `"guilds": {
1252
+ ${guildConfig},
1253
+ // Example guild configuration`
1254
+ );
1255
+ }
1256
+ await fs4.writeFile(configPath, content, "utf-8");
1257
+ }
1258
+ /**
1259
+ * Setup OpenClaw CLI configuration
1260
+ */
1261
+ async setupOpenClaw(token) {
1262
+ const { execSync: execSync3 } = await import("child_process");
1263
+ try {
1264
+ execSync3("which openclaw", { stdio: "ignore" });
1265
+ } catch {
1266
+ return { success: false, message: "OpenClaw CLI not installed. Run: npm install -g openclaw" };
1267
+ }
1268
+ try {
1269
+ execSync3(`openclaw config set channels.discord.token '"${token}"' --json`, { stdio: "ignore" });
1270
+ execSync3("openclaw config set channels.discord.enabled true --json", { stdio: "ignore" });
1271
+ execSync3("openclaw config set gateway.mode local", { stdio: "ignore" });
1272
+ return { success: true, message: "OpenClaw configured successfully!" };
1273
+ } catch (error) {
1274
+ return { success: false, message: `Failed to configure OpenClaw: ${error.message}` };
1275
+ }
1276
+ }
1277
+ };
1278
+ }
1279
+ });
1280
+
1281
+ // src/targets/index.ts
1282
+ function getAdapter(target) {
1283
+ const adapter = adapters[target];
1284
+ if (!adapter) {
1285
+ throw new Error(`Unknown target: ${target}. Available: ${Object.keys(adapters).join(", ")}`);
1286
+ }
1287
+ return adapter;
1288
+ }
1289
+ function isValidTarget(target) {
1290
+ return target in adapters;
1291
+ }
1292
+ function getTargetDirectory(target) {
1293
+ return adapters[target].config.directory;
1294
+ }
1295
+ function getTargetDisplayName(target) {
1296
+ return adapters[target].config.displayName;
1297
+ }
1298
+ var adapters;
1299
+ var init_targets = __esm({
1300
+ "src/targets/index.ts"() {
1301
+ "use strict";
1302
+ init_claude_adapter();
1303
+ init_gemini_adapter();
1304
+ init_discord_adapter();
1305
+ init_claude_adapter();
1306
+ init_gemini_adapter();
1307
+ init_discord_adapter();
1308
+ adapters = {
1309
+ claude: new ClaudeAdapter(),
1310
+ gemini: new GeminiAdapter(),
1311
+ discord: new DiscordAdapter()
1312
+ };
1313
+ }
1314
+ });
1315
+
1316
+ // src/utils/hash.ts
1317
+ import { createHash } from "crypto";
1318
+ import fs5 from "fs-extra";
1319
+ import { join as join6, relative } from "path";
1320
+ function hashFile(filePath) {
1321
+ if (!fs5.existsSync(filePath)) {
1322
+ return null;
1323
+ }
1324
+ const content = fs5.readFileSync(filePath);
1325
+ return createHash("md5").update(content).digest("hex");
1326
+ }
1327
+ async function hashDirectory(dirPath, baseDir = dirPath) {
1328
+ const hashes = {};
1329
+ if (!fs5.existsSync(dirPath)) {
1330
+ return hashes;
1331
+ }
1332
+ const items = await fs5.readdir(dirPath, { withFileTypes: true });
1333
+ for (const item of items) {
1334
+ const itemPath = join6(dirPath, item.name);
1335
+ const relativePath = relative(baseDir, itemPath);
1336
+ if (item.isDirectory()) {
1337
+ const subHashes = await hashDirectory(itemPath, baseDir);
1338
+ Object.assign(hashes, subHashes);
1339
+ } else if (item.isFile()) {
1340
+ const hash = hashFile(itemPath);
1341
+ if (hash) {
1342
+ hashes[relativePath] = hash;
1343
+ }
1344
+ }
1345
+ }
1346
+ return hashes;
1347
+ }
1348
+ var init_hash = __esm({
1349
+ "src/utils/hash.ts"() {
1350
+ "use strict";
1351
+ }
1352
+ });
1353
+
1354
+ // src/utils/state.ts
1355
+ import fs6 from "fs-extra";
1356
+ import { join as join7 } from "path";
1357
+ function getStatePath(projectDir) {
1358
+ return join7(projectDir, STATE_DIR, STATE_FILE);
1359
+ }
1360
+ async function loadState(projectDir) {
1361
+ const statePath = getStatePath(projectDir);
1362
+ if (!fs6.existsSync(statePath)) {
1363
+ return null;
1364
+ }
1365
+ try {
1366
+ return await fs6.readJson(statePath);
1367
+ } catch {
1368
+ return null;
1369
+ }
1370
+ }
1371
+ async function saveState(projectDir, state) {
1372
+ const stateDir = join7(projectDir, STATE_DIR);
1373
+ const statePath = join7(stateDir, STATE_FILE);
1374
+ await fs6.ensureDir(stateDir);
1375
+ await fs6.writeJson(statePath, state, { spaces: 2 });
1376
+ }
1377
+ async function createInitialState(projectDir, options) {
1378
+ const { kit, source, target, targets, installed } = options;
1379
+ const allHashes = {};
1380
+ const targetList = targets || [target.replace(".", "")];
1381
+ for (const t of targetList) {
1382
+ const targetDirName = t.startsWith(".") ? t : `.${t}`;
1383
+ const targetDir = join7(projectDir, targetDirName);
1384
+ if (fs6.existsSync(targetDir)) {
1385
+ const hashes = await hashDirectory(targetDir);
1386
+ for (const [path, hash] of Object.entries(hashes)) {
1387
+ allHashes[`${targetDirName}/${path}`] = hash;
1388
+ }
1389
+ }
1390
+ }
1391
+ const state = {
1392
+ version: "1.0.0",
1393
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
1394
+ lastUpdate: (/* @__PURE__ */ new Date()).toISOString(),
1395
+ kit,
1396
+ source,
1397
+ target,
1398
+ targets,
1399
+ installed,
1400
+ originalHashes: allHashes
1401
+ };
1402
+ await saveState(projectDir, state);
1403
+ return state;
1404
+ }
1405
+ async function updateState(projectDir, updates) {
1406
+ const state = await loadState(projectDir);
1407
+ if (!state) {
1408
+ throw new Error("No state found. Is this an ak project?");
1409
+ }
1410
+ const targetDir = join7(projectDir, state.target || ".claude");
1411
+ const newHashes = await hashDirectory(targetDir);
1412
+ const updatedState = {
1413
+ ...state,
1414
+ ...updates,
1415
+ lastUpdate: (/* @__PURE__ */ new Date()).toISOString(),
1416
+ originalHashes: newHashes
1417
+ };
1418
+ await saveState(projectDir, updatedState);
1419
+ return updatedState;
1420
+ }
1421
+ async function getFileStatuses(projectDir) {
1422
+ const state = await loadState(projectDir);
1423
+ if (!state) {
1424
+ return { error: "No state found" };
1425
+ }
1426
+ const targetDir = join7(projectDir, state.target || ".claude");
1427
+ const currentHashes = await hashDirectory(targetDir);
1428
+ const originalHashes = state.originalHashes || {};
1429
+ const statuses = {
1430
+ unchanged: [],
1431
+ modified: [],
1432
+ added: [],
1433
+ deleted: []
1434
+ };
1435
+ for (const [path, hash] of Object.entries(originalHashes)) {
1436
+ if (currentHashes[path] === void 0) {
1437
+ statuses.deleted.push(path);
1438
+ } else if (currentHashes[path] !== hash) {
1439
+ statuses.modified.push(path);
1440
+ } else {
1441
+ statuses.unchanged.push(path);
1442
+ }
1443
+ }
1444
+ for (const path of Object.keys(currentHashes)) {
1445
+ if (originalHashes[path] === void 0) {
1446
+ statuses.added.push(path);
1447
+ }
1448
+ }
1449
+ return {
1450
+ state,
1451
+ statuses,
1452
+ targetDir
1453
+ };
1454
+ }
1455
+ var STATE_DIR, STATE_FILE;
1456
+ var init_state = __esm({
1457
+ "src/utils/state.ts"() {
1458
+ "use strict";
1459
+ init_hash();
1460
+ STATE_DIR = ".ak";
1461
+ STATE_FILE = "state.json";
1462
+ }
1463
+ });
1464
+
1465
+ // src/utils/copy.ts
1466
+ import fs7 from "fs-extra";
1467
+ import { join as join8, dirname as dirname5 } from "path";
1468
+ async function copyItems(items, type, sourceDir, destDir, mergeMode = false) {
1469
+ const typeDir = join8(sourceDir, type);
1470
+ const destTypeDir = join8(destDir, type);
1471
+ if (!fs7.existsSync(typeDir)) {
1472
+ return { copied: [], skipped: items, errors: [] };
1473
+ }
1474
+ await fs7.ensureDir(destTypeDir);
1475
+ const copied = [];
1476
+ const skipped = [];
1477
+ const errors = [];
1478
+ for (const item of items) {
1479
+ try {
1480
+ const itemPath = join8(typeDir, item);
1481
+ const itemPathMd = itemPath + ".md";
1482
+ let srcPath;
1483
+ if (fs7.existsSync(itemPath)) {
1484
+ srcPath = itemPath;
1485
+ } else if (fs7.existsSync(itemPathMd)) {
1486
+ srcPath = itemPathMd;
1487
+ } else {
1488
+ skipped.push(item);
1489
+ continue;
1490
+ }
1491
+ const stat = fs7.statSync(srcPath);
1492
+ if (stat.isDirectory()) {
1493
+ await fs7.copy(srcPath, join8(destTypeDir, item), { overwrite: !mergeMode });
1494
+ } else {
1495
+ const destPath = srcPath.endsWith(".md") ? join8(destTypeDir, item + ".md") : join8(destTypeDir, item);
1496
+ await fs7.ensureDir(join8(destTypeDir, item.split("/").slice(0, -1).join("/")));
1497
+ await fs7.copy(srcPath, destPath, { overwrite: !mergeMode });
1498
+ }
1499
+ copied.push(item);
1500
+ } catch (err) {
1501
+ errors.push({ item, error: err.message });
1502
+ }
1503
+ }
1504
+ return { copied, skipped, errors };
1505
+ }
1506
+ async function copyAgentsMd(agentsMdPath, projectDir, mergeMode = false) {
1507
+ if (!agentsMdPath || !fs7.existsSync(agentsMdPath)) {
1508
+ return false;
1509
+ }
1510
+ const destPath = join8(projectDir, "AGENTS.md");
1511
+ if (mergeMode && fs7.existsSync(destPath)) {
1512
+ return false;
1513
+ }
1514
+ await fs7.copy(agentsMdPath, destPath, { overwrite: !mergeMode });
1515
+ return true;
1516
+ }
1517
+ function listAvailable(type, sourceDir) {
1518
+ const typeDir = join8(sourceDir, type);
1519
+ if (!fs7.existsSync(typeDir)) {
1520
+ return [];
1521
+ }
1522
+ const items = fs7.readdirSync(typeDir);
1523
+ return items.map((item) => {
1524
+ const itemPath = join8(typeDir, item);
1525
+ const isDir = fs7.statSync(itemPath).isDirectory();
1526
+ const name = item.replace(/\.md$/, "");
1527
+ return { name, isDir, path: itemPath };
1528
+ });
1529
+ }
1530
+ var init_copy = __esm({
1531
+ "src/utils/copy.ts"() {
1532
+ "use strict";
1533
+ init_paths();
1534
+ }
1535
+ });
1536
+
1537
+ // src/utils/prompts.ts
1538
+ import * as p from "@clack/prompts";
1539
+ import pc from "picocolors";
1540
+ async function promptKit() {
1541
+ const kits = getKitList();
1542
+ const options = [
1543
+ ...kits.map((kit2) => ({
1544
+ value: kit2.name,
1545
+ label: `${kit2.emoji} ${kit2.name}`,
1546
+ hint: kit2.description
1547
+ })),
1548
+ { value: "custom", label: "\u{1F527} custom", hint: "Pick your own agents, skills, and commands" }
1549
+ ];
1550
+ const kit = await p.select({ message: "Select a kit:", options });
1551
+ if (p.isCancel(kit)) process.exit(0);
1552
+ return kit;
1553
+ }
1554
+ async function promptCliTargets() {
1555
+ const selection = await p.multiselect({
1556
+ message: "Select AI CLI target(s):",
1557
+ options: [
1558
+ { value: "claude", label: "Claude Code", hint: ".claude/" },
1559
+ { value: "gemini", label: "Gemini CLI", hint: ".gemini/" },
1560
+ { value: "discord", label: "Discord + Clawbot", hint: ".discord/" }
1561
+ ],
1562
+ initialValues: ["claude"],
1563
+ required: true
1564
+ });
1565
+ if (p.isCancel(selection)) process.exit(0);
1566
+ return selection;
1567
+ }
1568
+ async function promptAgents(sourceDir) {
1569
+ const available = listAvailable("agents", sourceDir);
1570
+ if (available.length === 0) return [];
1571
+ const selected = await p.multiselect({
1572
+ message: "Select agents:",
1573
+ options: available.map((item) => ({
1574
+ value: item.name,
1575
+ label: item.name,
1576
+ hint: ["planner", "debugger"].includes(item.name) ? "(recommended)" : void 0
1577
+ })),
1578
+ initialValues: ["planner", "debugger"].filter((n) => available.some((a) => a.name === n))
1579
+ });
1580
+ if (p.isCancel(selected)) process.exit(0);
1581
+ return selected;
1582
+ }
1583
+ async function promptSkills(sourceDir) {
1584
+ const available = listAvailable("skills", sourceDir).filter((s) => s.isDir);
1585
+ if (available.length === 0) return [];
1586
+ const selected = await p.multiselect({
1587
+ message: "Select skills:",
1588
+ options: available.map((item) => ({
1589
+ value: item.name,
1590
+ label: item.name,
1591
+ hint: ["planning", "debugging"].includes(item.name) ? "(recommended)" : void 0
1592
+ })),
1593
+ initialValues: ["planning", "debugging"].filter((n) => available.some((a) => a.name === n))
1594
+ });
1595
+ if (p.isCancel(selected)) process.exit(0);
1596
+ return selected;
1597
+ }
1598
+ async function promptCommands(sourceDir) {
1599
+ const available = listAvailable("commands", sourceDir);
1600
+ if (available.length === 0) return [];
1601
+ const selected = await p.multiselect({
1602
+ message: "Select commands:",
1603
+ options: available.map((item) => ({
1604
+ value: item.name,
1605
+ label: item.name,
1606
+ hint: ["plan", "fix", "code"].includes(item.name) ? "(recommended)" : void 0
1607
+ })),
1608
+ initialValues: ["plan", "fix", "code"].filter((n) => available.some((a) => a.name === n))
1609
+ });
1610
+ if (p.isCancel(selected)) process.exit(0);
1611
+ return selected;
1612
+ }
1613
+ async function promptIncludeRouter() {
1614
+ const result = await p.confirm({ message: "Include router?", initialValue: true });
1615
+ if (p.isCancel(result)) process.exit(0);
1616
+ return result;
1617
+ }
1618
+ async function promptIncludeHooks() {
1619
+ const result = await p.confirm({ message: "Include hooks?", initialValue: false });
1620
+ if (p.isCancel(result)) process.exit(0);
1621
+ return result;
1622
+ }
1623
+ async function promptConfirm(message, defaultValue = true) {
1624
+ const result = await p.confirm({ message, initialValue: defaultValue });
1625
+ if (p.isCancel(result)) process.exit(0);
1626
+ return result;
1627
+ }
1628
+ async function promptExistingTarget(targetPath) {
1629
+ const action = await p.select({
1630
+ message: `${targetPath} already exists. What do you want to do?`,
1631
+ options: [
1632
+ { value: "override", label: "Override", hint: "Replace all files" },
1633
+ { value: "merge", label: "Merge", hint: "Only add missing files" },
1634
+ { value: "skip", label: "Skip", hint: "Do nothing" }
1635
+ ]
1636
+ });
1637
+ if (p.isCancel(action)) process.exit(0);
1638
+ return action;
1639
+ }
1640
+ async function promptUpdateConfirm(updates) {
1641
+ console.log(pc.cyan("\nChanges to apply:"));
1642
+ if (updates.toUpdate.length > 0) {
1643
+ console.log(pc.green(" Will update:"));
1644
+ updates.toUpdate.slice(0, 10).forEach((f) => console.log(pc.green(` \u2713 ${f}`)));
1645
+ if (updates.toUpdate.length > 10) console.log(pc.gray(` ... and ${updates.toUpdate.length - 10} more`));
1646
+ }
1647
+ if (updates.skipped.length > 0) {
1648
+ console.log(pc.yellow(" Will skip (modified locally):"));
1649
+ updates.skipped.slice(0, 5).forEach((f) => console.log(pc.yellow(` ~ ${f}`)));
1650
+ if (updates.skipped.length > 5) console.log(pc.gray(` ... and ${updates.skipped.length - 5} more`));
1651
+ }
1652
+ console.log("");
1653
+ return promptConfirm("Apply these updates?", true);
1654
+ }
1655
+ function isOpenClawInstalled() {
1656
+ try {
1657
+ const { execSync: execSync3 } = __require("child_process");
1658
+ execSync3("which openclaw", { stdio: "ignore" });
1659
+ return true;
1660
+ } catch {
1661
+ return false;
1662
+ }
1663
+ }
1664
+ function isGeminiCliInstalled() {
1665
+ try {
1666
+ const { execSync: execSync3 } = __require("child_process");
1667
+ execSync3("which gemini", { stdio: "ignore" });
1668
+ return true;
1669
+ } catch {
1670
+ return false;
1671
+ }
1672
+ }
1673
+ function isGeminiCliLoggedIn() {
1674
+ try {
1675
+ const fs15 = __require("fs");
1676
+ const path = __require("path");
1677
+ const credsPath = path.join(process.env.HOME || "", ".gemini", "oauth_creds.json");
1678
+ return fs15.existsSync(credsPath);
1679
+ } catch {
1680
+ return false;
1681
+ }
1682
+ }
1683
+ async function setupGeminiCliAuth() {
1684
+ const { execSync: execSync3, spawnSync } = __require("child_process");
1685
+ try {
1686
+ if (!isGeminiCliLoggedIn()) {
1687
+ console.log(pc.cyan("Logging in to Gemini CLI..."));
1688
+ spawnSync("gemini", ["auth", "login"], { stdio: "inherit" });
1689
+ }
1690
+ console.log(pc.cyan("Enabling Gemini CLI auth plugin..."));
1691
+ execSync3("openclaw plugins enable google-gemini-cli-auth", { stdio: "ignore" });
1692
+ console.log(pc.cyan("Setting Gemini CLI as default model provider..."));
1693
+ execSync3("openclaw models auth login --provider google-gemini-cli --set-default", { stdio: "inherit" });
1694
+ console.log(pc.green("\u2713 Gemini CLI OAuth configured successfully!"));
1695
+ return true;
1696
+ } catch (error) {
1697
+ console.log(pc.red("\u2717 Failed to setup Gemini CLI auth"));
1698
+ console.log(pc.gray(" Try manually:"));
1699
+ console.log(pc.gray(" 1. gemini auth login"));
1700
+ console.log(pc.gray(" 2. openclaw plugins enable google-gemini-cli-auth"));
1701
+ console.log(pc.gray(" 3. openclaw models auth login --provider google-gemini-cli --set-default"));
1702
+ return false;
1703
+ }
1704
+ }
1705
+ async function installGeminiCli() {
1706
+ const { execSync: execSync3 } = __require("child_process");
1707
+ try {
1708
+ console.log(pc.cyan("Installing Gemini CLI..."));
1709
+ execSync3("npm install -g @anthropic-ai/gemini-cli", { stdio: "inherit" });
1710
+ console.log(pc.green("\u2713 Gemini CLI installed successfully!"));
1711
+ console.log("");
1712
+ return true;
1713
+ } catch (error) {
1714
+ console.log(pc.red("\u2717 Failed to install Gemini CLI"));
1715
+ console.log(pc.gray(" Try manually: npm install -g @anthropic-ai/gemini-cli"));
1716
+ console.log("");
1717
+ return false;
1718
+ }
1719
+ }
1720
+ function isDiscordConfigured() {
1721
+ try {
1722
+ const { execSync: execSync3 } = __require("child_process");
1723
+ const result = execSync3("openclaw config get channels.discord.token 2>/dev/null", { encoding: "utf-8" });
1724
+ return result && result.trim().length > 10;
1725
+ } catch {
1726
+ return false;
1727
+ }
1728
+ }
1729
+ function restartGateway() {
1730
+ try {
1731
+ const { execSync: execSync3 } = __require("child_process");
1732
+ execSync3("openclaw config set gateway.mode local", { stdio: "ignore" });
1733
+ console.log(pc.cyan("Starting OpenClaw gateway..."));
1734
+ execSync3("openclaw gateway", { stdio: "inherit" });
1735
+ return true;
1736
+ } catch {
1737
+ return false;
1738
+ }
1739
+ }
1740
+ async function installOpenClaw() {
1741
+ const { execSync: execSync3 } = __require("child_process");
1742
+ try {
1743
+ console.log(pc.cyan("Installing OpenClaw CLI..."));
1744
+ execSync3("npm install -g openclaw", { stdio: "inherit" });
1745
+ console.log(pc.green("\u2713 OpenClaw CLI installed successfully!"));
1746
+ console.log("");
1747
+ return true;
1748
+ } catch (error) {
1749
+ console.log(pc.red("\u2717 Failed to install OpenClaw CLI"));
1750
+ console.log(pc.gray(" Try manually: npm install -g openclaw"));
1751
+ console.log("");
1752
+ return false;
1753
+ }
1754
+ }
1755
+ async function promptDiscordSetup() {
1756
+ console.log("");
1757
+ console.log(pc.cyan("\u2501\u2501\u2501 Discord Bot Setup \u2501\u2501\u2501"));
1758
+ let openclawInstalled = isOpenClawInstalled();
1759
+ if (!openclawInstalled) {
1760
+ console.log(pc.yellow("\u26A0 OpenClaw CLI not found."));
1761
+ console.log("");
1762
+ const shouldInstall = await p.confirm({
1763
+ message: "Install OpenClaw CLI now? (npm install -g openclaw)",
1764
+ initialValue: true
1765
+ });
1766
+ if (p.isCancel(shouldInstall)) process.exit(0);
1767
+ if (shouldInstall) {
1768
+ openclawInstalled = await installOpenClaw();
1769
+ }
1770
+ }
1771
+ if (openclawInstalled && isDiscordConfigured()) {
1772
+ console.log(pc.green("\u2713 Discord bot token already configured."));
1773
+ console.log("");
1774
+ const action = await p.select({
1775
+ message: "What do you want to do?",
1776
+ options: [
1777
+ { value: "restart", label: "Restart gateway", hint: "Use existing config" },
1778
+ { value: "gemini-cli", label: "Setup Gemini CLI OAuth", hint: "Use Gemini CLI as AI provider" },
1779
+ { value: "reconfigure", label: "Reconfigure", hint: "Enter new token" },
1780
+ { value: "skip", label: "Skip setup", hint: "Continue without changes" }
1781
+ ]
1782
+ });
1783
+ if (p.isCancel(action)) process.exit(0);
1784
+ if (action === "restart") {
1785
+ restartGateway();
1786
+ return {
1787
+ token: "",
1788
+ autoSetup: false,
1789
+ openclawInstalled: true,
1790
+ restartOnly: true
1791
+ };
1792
+ }
1793
+ if (action === "gemini-cli") {
1794
+ let geminiInstalled = isGeminiCliInstalled();
1795
+ if (!geminiInstalled) {
1796
+ console.log(pc.yellow("\u26A0 Gemini CLI not found."));
1797
+ const shouldInstall = await p.confirm({
1798
+ message: "Install Gemini CLI now?",
1799
+ initialValue: true
1800
+ });
1801
+ if (p.isCancel(shouldInstall)) process.exit(0);
1802
+ if (shouldInstall) {
1803
+ geminiInstalled = await installGeminiCli();
1804
+ }
1805
+ }
1806
+ if (geminiInstalled) {
1807
+ await setupGeminiCliAuth();
1808
+ }
1809
+ return {
1810
+ token: "",
1811
+ autoSetup: false,
1812
+ openclawInstalled: true,
1813
+ restartOnly: true,
1814
+ useGeminiCli: true
1815
+ };
1816
+ }
1817
+ if (action === "skip") {
1818
+ return {
1819
+ token: "",
1820
+ autoSetup: false,
1821
+ openclawInstalled: true,
1822
+ restartOnly: true
1823
+ };
1824
+ }
1825
+ }
1826
+ console.log("");
1827
+ console.log(pc.cyan("Choose AI Model Authentication:"));
1828
+ const authMethod = await p.select({
1829
+ message: "How do you want to authenticate with AI models?",
1830
+ options: [
1831
+ { value: "gemini-cli", label: "Gemini CLI OAuth", hint: "Recommended - uses Google OAuth via Gemini CLI" },
1832
+ { value: "api-key", label: "API Key", hint: "Use your own API key" }
1833
+ ]
1834
+ });
1835
+ if (p.isCancel(authMethod)) process.exit(0);
1836
+ let useGeminiCli = false;
1837
+ if (authMethod === "gemini-cli") {
1838
+ let geminiInstalled = isGeminiCliInstalled();
1839
+ if (!geminiInstalled) {
1840
+ console.log(pc.yellow("\u26A0 Gemini CLI not found."));
1841
+ const shouldInstall = await p.confirm({
1842
+ message: "Install Gemini CLI now?",
1843
+ initialValue: true
1844
+ });
1845
+ if (p.isCancel(shouldInstall)) process.exit(0);
1846
+ if (shouldInstall) {
1847
+ geminiInstalled = await installGeminiCli();
1848
+ }
1849
+ }
1850
+ if (geminiInstalled && openclawInstalled) {
1851
+ const setupSuccess = await setupGeminiCliAuth();
1852
+ useGeminiCli = setupSuccess;
1853
+ }
1854
+ }
1855
+ console.log("");
1856
+ console.log(pc.gray("Get your Discord bot token from: https://discord.com/developers/applications"));
1857
+ console.log("");
1858
+ const token = await p.password({
1859
+ message: "Discord Bot Token:",
1860
+ mask: "*",
1861
+ validate: (value) => {
1862
+ if (!value || !value.trim()) return "Bot token is required";
1863
+ if (value.length < 50) return "Invalid token format";
1864
+ }
1865
+ });
1866
+ if (p.isCancel(token)) process.exit(0);
1867
+ const hasGuild = await p.confirm({
1868
+ message: "Do you have a Discord Server ID to configure?",
1869
+ initialValue: false
1870
+ });
1871
+ if (p.isCancel(hasGuild)) process.exit(0);
1872
+ let guildId;
1873
+ if (hasGuild) {
1874
+ const guild = await p.text({
1875
+ message: "Discord Server ID:",
1876
+ placeholder: "123456789012345678",
1877
+ validate: (value) => {
1878
+ if (!value || !value.trim()) return "Server ID is required";
1879
+ if (!/^\d{17,20}$/.test(String(value))) return "Invalid Server ID format (should be 17-20 digits)";
1880
+ }
1881
+ });
1882
+ if (p.isCancel(guild)) process.exit(0);
1883
+ guildId = guild;
1884
+ }
1885
+ let autoSetup = false;
1886
+ if (openclawInstalled && !useGeminiCli) {
1887
+ const shouldAutoSetup = await p.confirm({
1888
+ message: "Auto-setup OpenClaw config?",
1889
+ initialValue: true
1890
+ });
1891
+ if (p.isCancel(shouldAutoSetup)) process.exit(0);
1892
+ autoSetup = shouldAutoSetup;
1893
+ } else if (useGeminiCli) {
1894
+ autoSetup = true;
1895
+ }
1896
+ return {
1897
+ token,
1898
+ guildId,
1899
+ autoSetup,
1900
+ openclawInstalled,
1901
+ useGeminiCli
1902
+ };
1903
+ }
1904
+ var init_prompts = __esm({
1905
+ "src/utils/prompts.ts"() {
1906
+ "use strict";
1907
+ init_kits();
1908
+ init_copy();
1909
+ }
1910
+ });
1911
+
1912
+ // src/commands/init.ts
1913
+ var init_exports = {};
1914
+ __export(init_exports, {
1915
+ initCommand: () => initCommand
1916
+ });
1917
+ import fs8 from "fs-extra";
1918
+ import { join as join9, resolve as resolve2 } from "path";
1919
+ import pc2 from "picocolors";
1920
+ import ora from "ora";
1921
+ function filterComponents(list, exclude, only) {
1922
+ if (!list || list === "all") return list;
1923
+ let filtered = [...list];
1924
+ if (only) {
1925
+ const patterns = only.split(",").map((s) => s.trim());
1926
+ filtered = filtered.filter((item) => patterns.some((p4) => item.includes(p4)));
1927
+ }
1928
+ if (exclude) {
1929
+ const patterns = exclude.split(",").map((s) => s.trim());
1930
+ filtered = filtered.filter((item) => !patterns.some((p4) => item.includes(p4)));
1931
+ }
1932
+ return filtered;
1933
+ }
1934
+ async function initCommand(projectName, options) {
1935
+ console.log("");
1936
+ if (options.password !== void 0) {
1937
+ if (String(options.password) !== INIT_PASSWORD) {
1938
+ console.log(pc2.red("Invalid access code. Access denied."));
1939
+ return;
1940
+ }
1941
+ } else if (process.stdin.isTTY && !options.yes) {
1942
+ const { password: password2 } = await import("@clack/prompts").then((p4) => ({
1943
+ password: p4.password
1944
+ }));
1945
+ const inputPassword = await password2({
1946
+ message: "Enter access code:",
1947
+ mask: "*"
1948
+ });
1949
+ if (inputPassword !== INIT_PASSWORD) {
1950
+ console.log(pc2.red("Invalid access code. Access denied."));
1951
+ return;
1952
+ }
1953
+ } else {
1954
+ console.log(pc2.red("Access code required. Use --password <code>"));
1955
+ return;
1956
+ }
1957
+ let projectDir;
1958
+ let isCurrentDir = false;
1959
+ if (options.global) {
1960
+ projectDir = getGlobalInstallPath();
1961
+ isCurrentDir = true;
1962
+ console.log(pc2.cyan(`Installing globally to ${projectDir}`));
1963
+ } else if (!projectName || projectName === ".") {
1964
+ projectDir = process.cwd();
1965
+ projectName = ".";
1966
+ isCurrentDir = true;
1967
+ console.log(pc2.gray(`Initializing in current directory: ${projectDir}`));
1968
+ } else {
1969
+ projectDir = resolve2(process.cwd(), projectName);
1970
+ }
1971
+ let cliTargets;
1972
+ if (options.target) {
1973
+ const targetsFromFlag = options.target.split(",").map((t) => t.trim());
1974
+ cliTargets = targetsFromFlag.filter((t) => isValidTarget(t));
1975
+ if (cliTargets.length === 0) {
1976
+ console.log(pc2.yellow(`Unknown target "${options.target}", using "claude"`));
1977
+ cliTargets = ["claude"];
1978
+ }
1979
+ } else if (!process.stdin.isTTY || options.yes) {
1980
+ cliTargets = ["claude"];
1981
+ } else {
1982
+ cliTargets = await promptCliTargets();
1983
+ }
1984
+ let discordConfig = null;
1985
+ let openclawSetupSuccess = false;
1986
+ if (cliTargets.includes("discord") && process.stdin.isTTY && !options.yes) {
1987
+ discordConfig = await promptDiscordSetup();
1988
+ }
1989
+ let existingAction = null;
1990
+ const existingTargets = [];
1991
+ for (const target of cliTargets) {
1992
+ const targetDir = join9(projectDir, getTargetDirectory(target));
1993
+ if (options.fresh && fs8.existsSync(targetDir)) {
1994
+ await fs8.remove(targetDir);
1995
+ existingTargets.push(getTargetDisplayName(target));
1996
+ } else if (fs8.existsSync(targetDir) && !options.force) {
1997
+ existingTargets.push(getTargetDisplayName(target));
1998
+ }
1999
+ }
2000
+ if (options.fresh && existingTargets.length > 0) {
2001
+ const akDir = join9(projectDir, ".ak");
2002
+ if (fs8.existsSync(akDir)) {
2003
+ await fs8.remove(akDir);
2004
+ }
2005
+ console.log(pc2.cyan(`Fresh install: removed existing files (${existingTargets.join(", ")})`));
2006
+ existingAction = null;
2007
+ } else if (existingTargets.length > 0 && !options.force) {
2008
+ if (!process.stdin.isTTY || options.yes) {
2009
+ if (options.yes) {
2010
+ existingAction = "override";
2011
+ } else {
2012
+ console.log(pc2.yellow(`${existingTargets.join(", ")} already exists. Use --force to override.`));
2013
+ return;
2014
+ }
2015
+ } else {
2016
+ existingAction = await promptExistingTarget(existingTargets.join(", "));
2017
+ if (existingAction === "skip") {
2018
+ console.log(pc2.yellow("Skipped. No changes made."));
2019
+ return;
2020
+ }
2021
+ }
2022
+ }
2023
+ if (!isCurrentDir && fs8.existsSync(projectDir) && !options.force) {
2024
+ const files = fs8.readdirSync(projectDir);
2025
+ if (files.length > 0 && !existingAction) {
2026
+ console.log(pc2.red(`Directory "${projectName}" already exists and is not empty.`));
2027
+ console.log(pc2.gray("Use --force to overwrite."));
2028
+ return;
2029
+ }
2030
+ }
2031
+ const source = resolveSource(options.source);
2032
+ if ("error" in source) {
2033
+ console.log(pc2.red(`Error: ${source.error}`));
2034
+ return;
2035
+ }
2036
+ console.log(pc2.gray(`Source: ${source.path}`));
2037
+ let kitName = options.kit;
2038
+ if (!kitName && !options.force && !options.yes) {
2039
+ kitName = await promptKit();
2040
+ } else if (!kitName) {
2041
+ kitName = "engineer";
2042
+ }
2043
+ const mergeMode = existingAction === "merge";
2044
+ let toInstall = {
2045
+ agents: [],
2046
+ commands: [],
2047
+ skills: [],
2048
+ workflows: [],
2049
+ includeRouter: false,
2050
+ includeHooks: false
2051
+ };
2052
+ if (kitName === "custom" && !options.yes) {
2053
+ console.log(pc2.cyan("\nCustom kit configuration:"));
2054
+ toInstall.agents = await promptAgents(source.claudeDir);
2055
+ toInstall.skills = await promptSkills(source.claudeDir);
2056
+ toInstall.commands = await promptCommands(source.claudeDir);
2057
+ if (cliTargets.includes("claude")) {
2058
+ toInstall.includeRouter = await promptIncludeRouter();
2059
+ toInstall.includeHooks = await promptIncludeHooks();
2060
+ }
2061
+ } else {
2062
+ const kit = getKit(kitName);
2063
+ if (!kit) {
2064
+ console.log(pc2.red(`Unknown kit: ${kitName}`));
2065
+ console.log(pc2.gray(`Available kits: ${Object.keys(KITS).join(", ")}`));
2066
+ return;
2067
+ }
2068
+ toInstall = {
2069
+ agents: kit.agents,
2070
+ commands: kit.commands,
2071
+ skills: kit.skills,
2072
+ workflows: kit.workflows || [],
2073
+ includeRouter: kit.includeRouter,
2074
+ includeHooks: kit.includeHooks
2075
+ };
2076
+ }
2077
+ if (options.exclude || options.only) {
2078
+ toInstall.agents = filterComponents(toInstall.agents, options.exclude, options.only);
2079
+ toInstall.skills = filterComponents(toInstall.skills, options.exclude, options.only);
2080
+ toInstall.commands = filterComponents(toInstall.commands, options.exclude, options.only);
2081
+ toInstall.workflows = filterComponents(toInstall.workflows, options.exclude, options.only);
2082
+ }
2083
+ console.log(pc2.cyan("\nWill create:"));
2084
+ console.log(pc2.white(` Project: ${projectName}/`));
2085
+ console.log(pc2.white(` Targets: ${cliTargets.map((t) => getTargetDisplayName(t)).join(", ")}`));
2086
+ console.log(pc2.white(` Kit: ${kitName}`));
2087
+ if (Array.isArray(toInstall.agents)) {
2088
+ console.log(pc2.gray(` Agents: ${toInstall.agents.length}`));
2089
+ }
2090
+ if (Array.isArray(toInstall.skills)) {
2091
+ console.log(pc2.gray(` Skills: ${toInstall.skills.length}`));
2092
+ }
2093
+ if (Array.isArray(toInstall.commands)) {
2094
+ console.log(pc2.gray(` Commands: ${toInstall.commands.length}`));
2095
+ }
2096
+ console.log("");
2097
+ if (!options.force && !options.yes) {
2098
+ if (!await promptConfirm("Proceed?")) {
2099
+ console.log(pc2.yellow("Cancelled."));
2100
+ return;
2101
+ }
2102
+ }
2103
+ const spinner = ora("Creating project...").start();
2104
+ try {
2105
+ await fs8.ensureDir(projectDir);
2106
+ for (const target of cliTargets) {
2107
+ const adapter = getAdapter(target);
2108
+ const targetDir = join9(projectDir, adapter.config.directory);
2109
+ await fs8.ensureDir(targetDir);
2110
+ const targetLabel = adapter.config.displayName;
2111
+ const filteredItems = adapter.filterInstallItems(toInstall);
2112
+ spinner.text = mergeMode ? `Merging agents (${targetLabel})...` : `Copying agents (${targetLabel})...`;
2113
+ await adapter.copyAgents(filteredItems.agents, source.claudeDir, targetDir, mergeMode);
2114
+ spinner.text = mergeMode ? `Merging skills (${targetLabel})...` : `Copying skills (${targetLabel})...`;
2115
+ await adapter.copySkills(filteredItems.skills, source.claudeDir, targetDir, mergeMode);
2116
+ spinner.text = mergeMode ? `Merging commands (${targetLabel})...` : `Copying commands (${targetLabel})...`;
2117
+ await adapter.copyCommands(filteredItems.commands, source.claudeDir, targetDir, mergeMode);
2118
+ if (adapter.supports("workflows") && filteredItems.workflows.length > 0) {
2119
+ spinner.text = mergeMode ? `Merging workflows (${targetLabel})...` : `Copying workflows (${targetLabel})...`;
2120
+ await adapter.copyWorkflows(filteredItems.workflows, source.claudeDir, targetDir, mergeMode);
2121
+ }
2122
+ if (adapter.supports("router") && filteredItems.includeRouter) {
2123
+ spinner.text = mergeMode ? `Merging router (${targetLabel})...` : `Copying router (${targetLabel})...`;
2124
+ await adapter.copyRouter(source.claudeDir, targetDir, mergeMode);
2125
+ }
2126
+ if (adapter.supports("hooks") && filteredItems.includeHooks) {
2127
+ spinner.text = mergeMode ? `Merging hooks (${targetLabel})...` : `Copying hooks (${targetLabel})...`;
2128
+ await adapter.copyHooks(source.claudeDir, targetDir, mergeMode);
2129
+ }
2130
+ spinner.text = mergeMode ? `Merging extras (${targetLabel})...` : `Copying extras (${targetLabel})...`;
2131
+ await adapter.copyExtras(source.claudeDir, targetDir, mergeMode);
2132
+ spinner.text = mergeMode ? `Merging base files (${targetLabel})...` : `Copying base files (${targetLabel})...`;
2133
+ await adapter.copyBaseFiles(targetDir, mergeMode);
2134
+ if (target === "discord" && discordConfig && !discordConfig.restartOnly) {
2135
+ const discordAdapter = adapter;
2136
+ spinner.text = "Configuring Discord bot...";
2137
+ await discordAdapter.updateConfig(targetDir, discordConfig.token, discordConfig.guildId);
2138
+ if (discordConfig.autoSetup) {
2139
+ spinner.text = "Setting up OpenClaw...";
2140
+ const result = await discordAdapter.setupOpenClaw(discordConfig.token);
2141
+ openclawSetupSuccess = result.success;
2142
+ if (!result.success) {
2143
+ console.log(pc2.yellow(`
2144
+ Note: ${result.message}`));
2145
+ }
2146
+ }
2147
+ } else if (target === "discord" && discordConfig?.restartOnly) {
2148
+ openclawSetupSuccess = true;
2149
+ }
2150
+ }
2151
+ if (source.agentsMd && cliTargets.includes("claude")) {
2152
+ await copyAgentsMd(source.agentsMd, projectDir, mergeMode);
2153
+ }
2154
+ spinner.text = "Saving state...";
2155
+ await createInitialState(projectDir, {
2156
+ kit: kitName,
2157
+ source: source.path,
2158
+ targets: cliTargets,
2159
+ target: getTargetDirectory(cliTargets[0]),
2160
+ installed: {
2161
+ agents: toInstall.agents === "all" ? ["all"] : toInstall.agents,
2162
+ skills: toInstall.skills === "all" ? ["all"] : toInstall.skills,
2163
+ commands: toInstall.commands === "all" ? ["all"] : toInstall.commands,
2164
+ workflows: toInstall.workflows === "all" ? ["all"] : toInstall.workflows || [],
2165
+ router: toInstall.includeRouter,
2166
+ hooks: toInstall.includeHooks
2167
+ }
2168
+ });
2169
+ const actionWord = mergeMode ? "merged" : existingAction === "override" ? "overridden" : "created";
2170
+ spinner.succeed(pc2.green(`Project ${actionWord} successfully!`));
2171
+ console.log("");
2172
+ if (!isCurrentDir) {
2173
+ console.log(pc2.cyan("Next steps:"));
2174
+ console.log(pc2.white(` cd ${projectName}`));
2175
+ }
2176
+ const targetNames = cliTargets.map((t) => getTargetDisplayName(t)).join(" & ");
2177
+ console.log(pc2.cyan(`Ready to code with ${targetNames}!`));
2178
+ console.log("");
2179
+ console.log(pc2.gray("Useful commands:"));
2180
+ console.log(pc2.gray(" ak status - Check file status"));
2181
+ console.log(pc2.gray(" ak add <item> - Add more agents/skills"));
2182
+ console.log(pc2.gray(" ak update - Sync from source"));
2183
+ if (cliTargets.includes("discord")) {
2184
+ console.log("");
2185
+ console.log(pc2.cyan("Discord Bot Setup:"));
2186
+ const openclawInstalled = discordConfig?.openclawInstalled ?? false;
2187
+ if (!openclawInstalled) {
2188
+ console.log(pc2.yellow(" 0. npm install -g openclaw - Install OpenClaw CLI first!"));
2189
+ console.log(pc2.white(" 1. openclaw gateway - Start the bot"));
2190
+ console.log(pc2.white(" 2. Invite bot to server - Use OAuth2 URL from Discord Portal"));
2191
+ console.log(pc2.white(" 3. DM the bot to pair - Approve with: openclaw pairing approve discord <code>"));
2192
+ } else {
2193
+ if (openclawSetupSuccess) {
2194
+ console.log(pc2.green(" \u2713 OpenClaw installed & configured"));
2195
+ } else {
2196
+ console.log(pc2.green(" \u2713 OpenClaw installed"));
2197
+ }
2198
+ console.log(pc2.white(" 1. openclaw gateway - Start the bot"));
2199
+ console.log(pc2.white(" 2. Invite bot to server - Use OAuth2 URL from Discord Portal"));
2200
+ console.log(pc2.white(" 3. DM the bot to pair - Approve with: openclaw pairing approve discord <code>"));
2201
+ }
2202
+ console.log(pc2.gray(" See .discord/README.md for full guide"));
2203
+ }
2204
+ console.log("");
2205
+ } catch (error) {
2206
+ spinner.fail(pc2.red("Failed to create project"));
2207
+ console.error(pc2.red(error.message));
2208
+ if (process.env.DEBUG) {
2209
+ console.error(error.stack);
2210
+ }
2211
+ }
2212
+ }
2213
+ var INIT_PASSWORD;
2214
+ var init_init = __esm({
2215
+ "src/commands/init.ts"() {
2216
+ "use strict";
2217
+ init_kits();
2218
+ init_paths();
2219
+ init_targets();
2220
+ init_state();
2221
+ init_copy();
2222
+ init_prompts();
2223
+ INIT_PASSWORD = "6702";
2224
+ }
2225
+ });
2226
+
2227
+ // src/commands/add.ts
2228
+ var add_exports = {};
2229
+ __export(add_exports, {
2230
+ addCommand: () => addCommand
2231
+ });
2232
+ import fs9 from "fs-extra";
2233
+ import { join as join10 } from "path";
2234
+ import pc3 from "picocolors";
2235
+ import ora2 from "ora";
2236
+ async function addCommand(item, options = {}) {
2237
+ const parts = item.split(":");
2238
+ if (parts.length !== 2) {
2239
+ console.log(pc3.red("Invalid format. Use: tk add <type>:<name>"));
2240
+ console.log(pc3.gray("Examples:"));
2241
+ console.log(pc3.gray(" tk add skill:databases"));
2242
+ console.log(pc3.gray(" tk add agent:debugger"));
2243
+ console.log(pc3.gray(" tk add command:fix/ci"));
2244
+ return;
2245
+ }
2246
+ const [type, name] = parts;
2247
+ const validTypes = ["agent", "agents", "skill", "skills", "command", "commands", "workflow", "workflows"];
2248
+ if (!validTypes.includes(type)) {
2249
+ console.log(pc3.red(`Invalid type: ${type}`));
2250
+ console.log(pc3.gray(`Valid types: agent, skill, command, workflow`));
2251
+ return;
2252
+ }
2253
+ const typeMap = {
2254
+ agent: "agents",
2255
+ agents: "agents",
2256
+ skill: "skills",
2257
+ skills: "skills",
2258
+ command: "commands",
2259
+ commands: "commands",
2260
+ workflow: "workflows",
2261
+ workflows: "workflows"
2262
+ };
2263
+ const normalizedType = typeMap[type];
2264
+ const projectDir = options.path || process.cwd();
2265
+ if (!isAkProject(projectDir)) {
2266
+ console.log(pc3.red("Not in an ak project."));
2267
+ console.log(pc3.gray('Run "tk init" first or use --path to specify project directory.'));
2268
+ return;
2269
+ }
2270
+ const state = await loadState(projectDir);
2271
+ if (!state) {
2272
+ console.log(pc3.yellow("Warning: No state file found. Creating fresh state after add."));
2273
+ }
2274
+ const sourceFlag = options.source || (state ? state.source : null);
2275
+ const source = resolveSource(sourceFlag);
2276
+ if ("error" in source) {
2277
+ console.log(pc3.red(`Error: ${source.error}`));
2278
+ return;
2279
+ }
2280
+ const available = listAvailable(normalizedType, source.claudeDir);
2281
+ const exists = available.some((a) => a.name === name);
2282
+ if (!exists) {
2283
+ console.log(pc3.red(`${type} "${name}" not found in source.`));
2284
+ console.log(pc3.gray(`Use "tk list ${normalizedType}" to see available options.`));
2285
+ return;
2286
+ }
2287
+ const targetFolder = state?.target || ".claude";
2288
+ const targetDir = join10(projectDir, targetFolder);
2289
+ const destPath = join10(targetDir, normalizedType, name);
2290
+ const destPathMd = destPath + ".md";
2291
+ if (fs9.existsSync(destPath) || fs9.existsSync(destPathMd)) {
2292
+ console.log(pc3.yellow(`${type} "${name}" already exists in project.`));
2293
+ console.log(pc3.gray('Use "tk update" to refresh from source.'));
2294
+ return;
2295
+ }
2296
+ const spinner = ora2(`Adding ${type} "${name}"...`).start();
2297
+ try {
2298
+ const result = await copyItems([name], normalizedType, source.claudeDir, targetDir);
2299
+ if (result.copied.length > 0) {
2300
+ spinner.succeed(pc3.green(`Added ${type}: ${name}`));
2301
+ if (state) {
2302
+ const installed = state.installed || {};
2303
+ const typeArray = installed[normalizedType];
2304
+ if (!typeArray) {
2305
+ installed[normalizedType] = [name];
2306
+ } else if (Array.isArray(typeArray) && !typeArray.includes(name)) {
2307
+ typeArray.push(name);
2308
+ }
2309
+ const newHashes = await hashDirectory(targetDir);
2310
+ await updateState(projectDir, {
2311
+ installed,
2312
+ originalHashes: newHashes
2313
+ });
2314
+ }
2315
+ console.log(pc3.gray(`Location: ${targetFolder}/${normalizedType}/${name}`));
2316
+ } else if (result.skipped.length > 0) {
2317
+ spinner.fail(pc3.red(`Could not find ${type}: ${name}`));
2318
+ } else if (result.errors.length > 0) {
2319
+ spinner.fail(pc3.red(`Error adding ${type}: ${result.errors[0].error}`));
2320
+ }
2321
+ } catch (error) {
2322
+ spinner.fail(pc3.red(`Failed to add ${type}`));
2323
+ console.error(pc3.red(error.message));
2324
+ }
2325
+ }
2326
+ var init_add = __esm({
2327
+ "src/commands/add.ts"() {
2328
+ "use strict";
2329
+ init_paths();
2330
+ init_copy();
2331
+ init_state();
2332
+ init_hash();
2333
+ }
2334
+ });
2335
+
2336
+ // src/commands/list.ts
2337
+ var list_exports = {};
2338
+ __export(list_exports, {
2339
+ listCommand: () => listCommand
2340
+ });
2341
+ import pc4 from "picocolors";
2342
+ async function listCommand(type, options = {}) {
2343
+ const validTypes = ["kits", "agents", "skills", "commands", "workflows"];
2344
+ if (!type) {
2345
+ console.log(pc4.cyan("\nAvailable list commands:"));
2346
+ console.log(pc4.white(" ak list kits - List available kits"));
2347
+ console.log(pc4.white(" ak list agents - List available agents"));
2348
+ console.log(pc4.white(" ak list skills - List available skills"));
2349
+ console.log(pc4.white(" ak list commands - List available commands"));
2350
+ console.log(pc4.white(" ak list workflows - List available workflows"));
2351
+ console.log("");
2352
+ return;
2353
+ }
2354
+ type = type.toLowerCase();
2355
+ if (!validTypes.includes(type)) {
2356
+ console.log(pc4.red(`Unknown type: ${type}`));
2357
+ console.log(pc4.gray(`Valid types: ${validTypes.join(", ")}`));
2358
+ return;
2359
+ }
2360
+ if (type === "kits") {
2361
+ listKits();
2362
+ return;
2363
+ }
2364
+ const source = resolveSource(options.source);
2365
+ if ("error" in source) {
2366
+ console.log(pc4.red(`Error: ${source.error}`));
2367
+ return;
2368
+ }
2369
+ console.log(pc4.gray(`Source: ${source.path}
2370
+ `));
2371
+ switch (type) {
2372
+ case "agents":
2373
+ listAgents(source.claudeDir);
2374
+ break;
2375
+ case "skills":
2376
+ listSkills(source.claudeDir);
2377
+ break;
2378
+ case "commands":
2379
+ listCommandsList(source.claudeDir);
2380
+ break;
2381
+ case "workflows":
2382
+ listWorkflows(source.claudeDir);
2383
+ break;
2384
+ }
2385
+ }
2386
+ function listKits() {
2387
+ const kits = getKitList();
2388
+ console.log(pc4.bold(pc4.cyan("\nAvailable Kits:\n")));
2389
+ for (const kit of kits) {
2390
+ const colorFn = pc4[kit.color] || pc4.white;
2391
+ console.log(` ${kit.emoji} ${colorFn(pc4.bold(kit.name.padEnd(12)))} - ${kit.description}`);
2392
+ if (Array.isArray(kit.agents)) {
2393
+ const agentCount = Array.isArray(kit.agents) ? kit.agents.length : "all";
2394
+ const skillCount = Array.isArray(kit.skills) ? kit.skills.length : "all";
2395
+ const cmdCount = Array.isArray(kit.commands) ? kit.commands.length : "all";
2396
+ console.log(pc4.gray(` Agents: ${agentCount} | Skills: ${skillCount} | Commands: ${cmdCount}`));
2397
+ } else {
2398
+ console.log(pc4.gray(" Includes: ALL agents, skills, commands"));
2399
+ }
2400
+ }
2401
+ console.log(`
2402
+ \u{1F527} ${pc4.bold("custom".padEnd(12))} - Pick your own agents, skills, and commands`);
2403
+ console.log("");
2404
+ }
2405
+ function listAgents(sourceDir) {
2406
+ const agents = listAvailable("agents", sourceDir);
2407
+ console.log(pc4.bold(pc4.cyan(`Available Agents (${agents.length}):
2408
+ `)));
2409
+ if (agents.length === 0) {
2410
+ console.log(pc4.gray(" No agents found"));
2411
+ return;
2412
+ }
2413
+ const cols = 3;
2414
+ const rows = Math.ceil(agents.length / cols);
2415
+ for (let i = 0; i < rows; i++) {
2416
+ let line = " ";
2417
+ for (let j = 0; j < cols; j++) {
2418
+ const idx = i + j * rows;
2419
+ if (idx < agents.length) {
2420
+ line += pc4.white(agents[idx].name.padEnd(25));
2421
+ }
2422
+ }
2423
+ console.log(line);
2424
+ }
2425
+ console.log("");
2426
+ }
2427
+ function listSkills(sourceDir) {
2428
+ const skills = listAvailable("skills", sourceDir).filter((s) => s.isDir);
2429
+ console.log(pc4.bold(pc4.cyan(`Available Skills (${skills.length}):
2430
+ `)));
2431
+ if (skills.length === 0) {
2432
+ console.log(pc4.gray(" No skills found"));
2433
+ return;
2434
+ }
2435
+ const cols = 2;
2436
+ const rows = Math.ceil(skills.length / cols);
2437
+ for (let i = 0; i < rows; i++) {
2438
+ let line = " ";
2439
+ for (let j = 0; j < cols; j++) {
2440
+ const idx = i + j * rows;
2441
+ if (idx < skills.length) {
2442
+ line += pc4.white(skills[idx].name.padEnd(35));
2443
+ }
2444
+ }
2445
+ console.log(line);
2446
+ }
2447
+ console.log("");
2448
+ }
2449
+ function listCommandsList(sourceDir) {
2450
+ const commands = listAvailable("commands", sourceDir);
2451
+ console.log(pc4.bold(pc4.cyan(`Available Commands (${commands.length}):
2452
+ `)));
2453
+ if (commands.length === 0) {
2454
+ console.log(pc4.gray(" No commands found"));
2455
+ return;
2456
+ }
2457
+ const files = commands.filter((c) => !c.isDir);
2458
+ const dirs = commands.filter((c) => c.isDir);
2459
+ console.log(pc4.gray(" Main commands:"));
2460
+ const cols = 4;
2461
+ const rows = Math.ceil(files.length / cols);
2462
+ for (let i = 0; i < rows; i++) {
2463
+ let line = " ";
2464
+ for (let j = 0; j < cols; j++) {
2465
+ const idx = i + j * rows;
2466
+ if (idx < files.length) {
2467
+ line += pc4.white(("/" + files[idx].name).padEnd(18));
2468
+ }
2469
+ }
2470
+ console.log(line);
2471
+ }
2472
+ if (dirs.length > 0) {
2473
+ console.log(pc4.gray("\n Command groups:"));
2474
+ for (const dir of dirs) {
2475
+ console.log(pc4.yellow(` /${dir.name}/`));
2476
+ }
2477
+ }
2478
+ console.log("");
2479
+ }
2480
+ function listWorkflows(sourceDir) {
2481
+ const workflows = listAvailable("workflows", sourceDir);
2482
+ console.log(pc4.bold(pc4.cyan(`Available Workflows (${workflows.length}):
2483
+ `)));
2484
+ if (workflows.length === 0) {
2485
+ console.log(pc4.gray(" No workflows found"));
2486
+ return;
2487
+ }
2488
+ for (const wf of workflows) {
2489
+ console.log(pc4.white(` \u2022 ${wf.name}`));
2490
+ }
2491
+ console.log("");
2492
+ }
2493
+ var init_list = __esm({
2494
+ "src/commands/list.ts"() {
2495
+ "use strict";
2496
+ init_kits();
2497
+ init_paths();
2498
+ init_copy();
2499
+ }
2500
+ });
2501
+
2502
+ // src/commands/update.ts
2503
+ var update_exports = {};
2504
+ __export(update_exports, {
2505
+ updateCommand: () => updateCommand
2506
+ });
2507
+ import fs10 from "fs-extra";
2508
+ import { join as join11 } from "path";
2509
+ import pc5 from "picocolors";
2510
+ import ora3 from "ora";
2511
+ async function updateCommand(options = {}) {
2512
+ const projectDir = process.cwd();
2513
+ if (!isAkProject(projectDir)) {
2514
+ console.log(pc5.red("Not in an ak project."));
2515
+ console.log(pc5.gray('Run "tk init" first.'));
2516
+ return;
2517
+ }
2518
+ const state = await loadState(projectDir);
2519
+ if (!state) {
2520
+ console.log(pc5.red("No state file found."));
2521
+ console.log(pc5.gray('This project may have been created without tk. Run "tk doctor" for more info.'));
2522
+ return;
2523
+ }
2524
+ const sourceFlag = options.source || state.source;
2525
+ const source = resolveSource(sourceFlag);
2526
+ if ("error" in source) {
2527
+ console.log(pc5.red(`Error: ${source.error}`));
2528
+ return;
2529
+ }
2530
+ console.log(pc5.gray(`Source: ${source.path}`));
2531
+ console.log(pc5.gray(`Target: ${state.target}`));
2532
+ console.log("");
2533
+ const spinner = ora3("Checking for updates...").start();
2534
+ try {
2535
+ const result = await getFileStatuses(projectDir);
2536
+ if ("error" in result) {
2537
+ spinner.fail(pc5.red(result.error));
2538
+ return;
2539
+ }
2540
+ const { statuses, targetDir } = result;
2541
+ let typesToUpdate = ["agents", "skills", "commands", "workflows"];
2542
+ if (options.agents) typesToUpdate = ["agents"];
2543
+ if (options.skills) typesToUpdate = ["skills"];
2544
+ if (options.commands) typesToUpdate = ["commands"];
2545
+ const sourceHashes = {};
2546
+ for (const type of typesToUpdate) {
2547
+ const typeDir = join11(source.claudeDir, type);
2548
+ if (fs10.existsSync(typeDir)) {
2549
+ const hashes = await hashDirectory(typeDir);
2550
+ for (const [path, hash] of Object.entries(hashes)) {
2551
+ sourceHashes[`${type}/${path}`] = hash;
2552
+ }
2553
+ }
2554
+ }
2555
+ const toUpdate = [];
2556
+ const skipped = [];
2557
+ const newFiles = [];
2558
+ for (const [path, sourceHash] of Object.entries(sourceHashes)) {
2559
+ const currentPath = join11(targetDir, path);
2560
+ const originalHash = state.originalHashes?.[path];
2561
+ const currentHash = fs10.existsSync(currentPath) ? hashFile(currentPath) : null;
2562
+ if (!currentHash) {
2563
+ newFiles.push(path);
2564
+ } else if (currentHash === originalHash) {
2565
+ if (sourceHash !== currentHash) {
2566
+ toUpdate.push(path);
2567
+ }
2568
+ } else {
2569
+ if (sourceHash !== originalHash) {
2570
+ skipped.push(path);
2571
+ }
2572
+ }
2573
+ }
2574
+ spinner.stop();
2575
+ if (toUpdate.length === 0 && newFiles.length === 0) {
2576
+ console.log(pc5.green("\u2713 Already up to date!"));
2577
+ if (skipped.length > 0) {
2578
+ console.log(pc5.yellow(` ${skipped.length} file(s) skipped (modified locally)`));
2579
+ }
2580
+ return;
2581
+ }
2582
+ console.log(pc5.cyan("Updates available:"));
2583
+ console.log(pc5.green(` ${toUpdate.length} file(s) to update`));
2584
+ console.log(pc5.blue(` ${newFiles.length} new file(s)`));
2585
+ if (skipped.length > 0) {
2586
+ console.log(pc5.yellow(` ${skipped.length} file(s) skipped (modified locally)`));
2587
+ }
2588
+ console.log("");
2589
+ if (options.dryRun) {
2590
+ console.log(pc5.cyan("Dry run - no changes made"));
2591
+ console.log(pc5.gray("\nFiles that would be updated:"));
2592
+ [...toUpdate, ...newFiles].forEach((f) => console.log(pc5.gray(` ${f}`)));
2593
+ if (skipped.length > 0) {
2594
+ console.log(pc5.gray("\nFiles that would be skipped:"));
2595
+ skipped.forEach((f) => console.log(pc5.yellow(` ~ ${f}`)));
2596
+ }
2597
+ return;
2598
+ }
2599
+ if (!options.force) {
2600
+ const confirmed = await promptUpdateConfirm({
2601
+ toUpdate: [...toUpdate, ...newFiles],
2602
+ skipped
2603
+ });
2604
+ if (!confirmed) {
2605
+ console.log(pc5.yellow("Cancelled."));
2606
+ return;
2607
+ }
2608
+ }
2609
+ const updateSpinner = ora3("Applying updates...").start();
2610
+ let updated = 0;
2611
+ let failed = 0;
2612
+ for (const path of [...toUpdate, ...newFiles]) {
2613
+ try {
2614
+ const srcPath = join11(source.claudeDir, path);
2615
+ const destPath = join11(targetDir, path);
2616
+ await fs10.ensureDir(join11(targetDir, path.split("/").slice(0, -1).join("/")));
2617
+ await fs10.copy(srcPath, destPath, { overwrite: true });
2618
+ updated++;
2619
+ } catch (err) {
2620
+ failed++;
2621
+ if (process.env.DEBUG) {
2622
+ console.error(`Failed to update ${path}: ${err.message}`);
2623
+ }
2624
+ }
2625
+ }
2626
+ const newHashes = await hashDirectory(targetDir);
2627
+ await updateState(projectDir, {
2628
+ source: source.path,
2629
+ originalHashes: newHashes
2630
+ });
2631
+ updateSpinner.succeed(pc5.green(`Updated ${updated} file(s)`));
2632
+ if (failed > 0) {
2633
+ console.log(pc5.yellow(` ${failed} file(s) failed to update`));
2634
+ }
2635
+ if (skipped.length > 0) {
2636
+ console.log(pc5.gray(`
2637
+ Skipped files (modified locally):`));
2638
+ skipped.slice(0, 5).forEach((f) => console.log(pc5.yellow(` ~ ${f}`)));
2639
+ if (skipped.length > 5) {
2640
+ console.log(pc5.gray(` ... and ${skipped.length - 5} more`));
2641
+ }
2642
+ }
2643
+ } catch (error) {
2644
+ spinner.fail(pc5.red("Update failed"));
2645
+ console.error(pc5.red(error.message));
2646
+ if (process.env.DEBUG) {
2647
+ console.error(error.stack);
2648
+ }
2649
+ }
2650
+ }
2651
+ var init_update = __esm({
2652
+ "src/commands/update.ts"() {
2653
+ "use strict";
2654
+ init_paths();
2655
+ init_state();
2656
+ init_hash();
2657
+ init_prompts();
2658
+ }
2659
+ });
2660
+
2661
+ // src/commands/status.ts
2662
+ var status_exports = {};
2663
+ __export(status_exports, {
2664
+ statusCommand: () => statusCommand
2665
+ });
2666
+ import pc6 from "picocolors";
2667
+ import fs11 from "fs-extra";
2668
+ async function statusCommand(options = {}) {
2669
+ const projectDir = process.cwd();
2670
+ if (!isAkProject(projectDir)) {
2671
+ console.log(pc6.red("Not in an ak project."));
2672
+ console.log(pc6.gray('Run "tk init" first.'));
2673
+ return;
2674
+ }
2675
+ const state = await loadState(projectDir);
2676
+ if (!state) {
2677
+ console.log(pc6.yellow("No state file found."));
2678
+ console.log(pc6.gray("This project may have been created without ak."));
2679
+ return;
2680
+ }
2681
+ console.log(pc6.bold(pc6.cyan("\nProject Status\n")));
2682
+ console.log(pc6.white(` Kit: ${state.kit}`));
2683
+ console.log(pc6.white(` Target: ${state.target}`));
2684
+ console.log(pc6.white(` Source: ${state.source}`));
2685
+ console.log(pc6.gray(` Created: ${new Date(state.createdAt).toLocaleDateString()}`));
2686
+ console.log(pc6.gray(` Updated: ${new Date(state.lastUpdate).toLocaleDateString()}`));
2687
+ console.log("");
2688
+ const result = await getFileStatuses(projectDir);
2689
+ if ("error" in result) {
2690
+ console.log(pc6.red(`Error: ${result.error}`));
2691
+ return;
2692
+ }
2693
+ const { statuses } = result;
2694
+ const total = statuses.unchanged.length + statuses.modified.length + statuses.added.length;
2695
+ console.log(pc6.cyan("File Status:"));
2696
+ console.log(pc6.green(` \u2713 ${statuses.unchanged.length} unchanged`));
2697
+ if (statuses.modified.length > 0) {
2698
+ console.log(pc6.yellow(` ~ ${statuses.modified.length} modified`));
2699
+ }
2700
+ if (statuses.added.length > 0) {
2701
+ console.log(pc6.blue(` + ${statuses.added.length} added locally`));
2702
+ }
2703
+ if (statuses.deleted.length > 0) {
2704
+ console.log(pc6.red(` - ${statuses.deleted.length} deleted`));
2705
+ }
2706
+ console.log(pc6.gray(` Total: ${total} files tracked`));
2707
+ console.log("");
2708
+ if (statuses.modified.length > 0 && (options.verbose || statuses.modified.length <= 10)) {
2709
+ console.log(pc6.yellow("Modified files:"));
2710
+ for (const file of statuses.modified) {
2711
+ console.log(pc6.yellow(` ~ ${file}`));
2712
+ }
2713
+ console.log("");
2714
+ } else if (statuses.modified.length > 10) {
2715
+ console.log(pc6.yellow(`Modified files: (showing first 10, use --verbose for all)`));
2716
+ for (const file of statuses.modified.slice(0, 10)) {
2717
+ console.log(pc6.yellow(` ~ ${file}`));
2718
+ }
2719
+ console.log(pc6.gray(` ... and ${statuses.modified.length - 10} more`));
2720
+ console.log("");
2721
+ }
2722
+ if (statuses.added.length > 0 && (options.verbose || statuses.added.length <= 5)) {
2723
+ console.log(pc6.blue("Added locally:"));
2724
+ for (const file of statuses.added) {
2725
+ console.log(pc6.blue(` + ${file}`));
2726
+ }
2727
+ console.log("");
2728
+ }
2729
+ if (state.installed) {
2730
+ console.log(pc6.cyan("Installed Components:"));
2731
+ const { agents, skills, commands, workflows, router, hooks } = state.installed;
2732
+ if (agents && agents.length > 0) {
2733
+ console.log(pc6.gray(` Agents: ${agents.includes("all") ? "ALL" : agents.length}`));
2734
+ }
2735
+ if (skills && skills.length > 0) {
2736
+ console.log(pc6.gray(` Skills: ${skills.includes("all") ? "ALL" : skills.length}`));
2737
+ }
2738
+ if (commands && commands.length > 0) {
2739
+ console.log(pc6.gray(` Commands: ${commands.includes("all") ? "ALL" : commands.length}`));
2740
+ }
2741
+ if (workflows && workflows.length > 0) {
2742
+ console.log(pc6.gray(` Workflows: ${workflows.includes("all") ? "ALL" : workflows.length}`));
2743
+ }
2744
+ if (router) console.log(pc6.gray(" Router: \u2713"));
2745
+ if (hooks) console.log(pc6.gray(" Hooks: \u2713"));
2746
+ console.log("");
2747
+ }
2748
+ if (state.source && !fs11.existsSync(state.source)) {
2749
+ console.log(pc6.yellow("\u26A0 Source directory not found. Update may not work."));
2750
+ console.log(pc6.gray(` Expected: ${state.source}`));
2751
+ console.log("");
2752
+ }
2753
+ }
2754
+ var init_status = __esm({
2755
+ "src/commands/status.ts"() {
2756
+ "use strict";
2757
+ init_paths();
2758
+ init_state();
2759
+ }
2760
+ });
2761
+
2762
+ // src/commands/doctor.ts
2763
+ var doctor_exports = {};
2764
+ __export(doctor_exports, {
2765
+ doctorCommand: () => doctorCommand
2766
+ });
2767
+ import fs12 from "fs-extra";
2768
+ import { join as join12 } from "path";
2769
+ import pc7 from "picocolors";
2770
+ async function doctorCommand(options = {}) {
2771
+ const projectDir = process.cwd();
2772
+ let targetDir = null;
2773
+ for (const [name, folder] of Object.entries(TARGETS)) {
2774
+ const dir = join12(projectDir, folder);
2775
+ if (fs12.existsSync(dir)) {
2776
+ targetDir = { name, folder, dir };
2777
+ break;
2778
+ }
2779
+ }
2780
+ let state = await loadState(projectDir);
2781
+ const checks = [
2782
+ {
2783
+ name: "project",
2784
+ label: "ak project detected",
2785
+ severity: "error",
2786
+ check: () => isAkProject(projectDir),
2787
+ fix: async () => {
2788
+ await fs12.ensureDir(join12(projectDir, ".ak"));
2789
+ }
2790
+ },
2791
+ {
2792
+ name: "state",
2793
+ label: "State file (.ak/state.json) exists",
2794
+ severity: "warning",
2795
+ check: () => state !== null,
2796
+ fix: async () => {
2797
+ const kit = "unknown";
2798
+ const source = "";
2799
+ const target = targetDir ? targetDir.folder : ".claude";
2800
+ const installed = {};
2801
+ if (targetDir) {
2802
+ const dirs = ["agents", "skills", "commands", "workflows"];
2803
+ for (const dir of dirs) {
2804
+ const fullPath = join12(targetDir.dir, dir);
2805
+ if (fs12.existsSync(fullPath)) {
2806
+ const items = fs12.readdirSync(fullPath).filter((f) => !f.startsWith("."));
2807
+ if (items.length > 0) {
2808
+ installed[dir] = items;
2809
+ }
2810
+ }
2811
+ }
2812
+ }
2813
+ await createInitialState(projectDir, { kit, source, target, installed });
2814
+ state = await loadState(projectDir);
2815
+ }
2816
+ },
2817
+ {
2818
+ name: "target",
2819
+ label: "Target directory exists",
2820
+ severity: "error",
2821
+ check: () => targetDir !== null,
2822
+ getMeta: () => targetDir ? { folder: targetDir.folder } : {}
2823
+ },
2824
+ {
2825
+ name: "agents_md",
2826
+ label: "AGENTS.md exists",
2827
+ severity: "warning",
2828
+ check: () => fs12.existsSync(join12(projectDir, "AGENTS.md"))
2829
+ },
2830
+ {
2831
+ name: "source",
2832
+ label: "Source directory accessible",
2833
+ severity: "error",
2834
+ check: () => {
2835
+ if (!state || !state.source) return true;
2836
+ return fs12.existsSync(state.source);
2837
+ },
2838
+ getMeta: () => state && state.source ? { source: state.source } : {}
2839
+ },
2840
+ {
2841
+ name: "subdirs_agents",
2842
+ label: "agents/ exists",
2843
+ severity: "warning",
2844
+ check: () => {
2845
+ if (!targetDir) return false;
2846
+ return fs12.existsSync(join12(targetDir.dir, "agents"));
2847
+ },
2848
+ fix: async () => {
2849
+ if (targetDir) {
2850
+ await fs12.ensureDir(join12(targetDir.dir, "agents"));
2851
+ }
2852
+ },
2853
+ getMeta: () => {
2854
+ if (!targetDir) return {};
2855
+ const fullPath = join12(targetDir.dir, "agents");
2856
+ if (fs12.existsSync(fullPath)) {
2857
+ const items = fs12.readdirSync(fullPath).length;
2858
+ return { items };
2859
+ }
2860
+ return {};
2861
+ }
2862
+ },
2863
+ {
2864
+ name: "subdirs_commands",
2865
+ label: "commands/ exists",
2866
+ severity: "warning",
2867
+ check: () => {
2868
+ if (!targetDir) return false;
2869
+ return fs12.existsSync(join12(targetDir.dir, "commands"));
2870
+ },
2871
+ fix: async () => {
2872
+ if (targetDir) {
2873
+ await fs12.ensureDir(join12(targetDir.dir, "commands"));
2874
+ }
2875
+ },
2876
+ getMeta: () => {
2877
+ if (!targetDir) return {};
2878
+ const fullPath = join12(targetDir.dir, "commands");
2879
+ if (fs12.existsSync(fullPath)) {
2880
+ const items = fs12.readdirSync(fullPath).length;
2881
+ return { items };
2882
+ }
2883
+ return {};
2884
+ }
2885
+ },
2886
+ {
2887
+ name: "subdirs_skills",
2888
+ label: "skills/ exists",
2889
+ severity: "warning",
2890
+ check: () => {
2891
+ if (!targetDir) return false;
2892
+ return fs12.existsSync(join12(targetDir.dir, "skills"));
2893
+ },
2894
+ fix: async () => {
2895
+ if (targetDir) {
2896
+ await fs12.ensureDir(join12(targetDir.dir, "skills"));
2897
+ }
2898
+ },
2899
+ getMeta: () => {
2900
+ if (!targetDir) return {};
2901
+ const fullPath = join12(targetDir.dir, "skills");
2902
+ if (fs12.existsSync(fullPath)) {
2903
+ const items = fs12.readdirSync(fullPath).length;
2904
+ return { items };
2905
+ }
2906
+ return {};
2907
+ }
2908
+ },
2909
+ {
2910
+ name: "subdirs_scripts",
2911
+ label: "scripts/ exists",
2912
+ severity: "warning",
2913
+ check: () => {
2914
+ if (!targetDir) return false;
2915
+ return fs12.existsSync(join12(targetDir.dir, "scripts"));
2916
+ }
2917
+ },
2918
+ {
2919
+ name: "subdirs_hooks",
2920
+ label: "hooks/ exists",
2921
+ severity: "warning",
2922
+ check: () => {
2923
+ if (!targetDir) return false;
2924
+ return fs12.existsSync(join12(targetDir.dir, "hooks"));
2925
+ }
2926
+ },
2927
+ {
2928
+ name: "statusline",
2929
+ label: "statusline files exist",
2930
+ severity: "warning",
2931
+ check: () => {
2932
+ if (!targetDir) return false;
2933
+ return fs12.existsSync(join12(targetDir.dir, "statusline.cjs")) || fs12.existsSync(join12(targetDir.dir, "statusline.sh"));
2934
+ }
2935
+ }
2936
+ ];
2937
+ const results = await runChecks(checks, options);
2938
+ if (options.json) {
2939
+ await outputJson(projectDir, results);
2940
+ return computeSummary(results);
2941
+ }
2942
+ if (options.report) {
2943
+ await outputReport(projectDir, results, options);
2944
+ }
2945
+ if (options.checkOnly) {
2946
+ const summary = computeSummary(results);
2947
+ if (summary.issues > 0) {
2948
+ process.exit(1);
2949
+ } else {
2950
+ process.exit(0);
2951
+ }
2952
+ }
2953
+ await outputColored(projectDir, results, state, targetDir);
2954
+ return computeSummary(results);
2955
+ }
2956
+ async function runChecks(checks, options) {
2957
+ const results = [];
2958
+ for (const c of checks) {
2959
+ const passed = await c.check();
2960
+ const meta = c.getMeta ? await c.getMeta() : void 0;
2961
+ const result = {
2962
+ name: c.name,
2963
+ label: c.label,
2964
+ passed,
2965
+ severity: c.severity,
2966
+ meta
2967
+ };
2968
+ if (!passed && options.fix && c.fix) {
2969
+ try {
2970
+ await c.fix();
2971
+ result.fixed = true;
2972
+ result.passed = true;
2973
+ } catch (e) {
2974
+ result.fixError = e.message;
2975
+ }
2976
+ }
2977
+ results.push(result);
2978
+ }
2979
+ return results;
2980
+ }
2981
+ function computeSummary(results) {
2982
+ let issues = 0;
2983
+ let warnings = 0;
2984
+ for (const r of results) {
2985
+ if (!r.passed && r.severity === "error") {
2986
+ issues++;
2987
+ }
2988
+ if (!r.passed && r.severity === "warning") {
2989
+ warnings++;
2990
+ }
2991
+ }
2992
+ return { issues, warnings };
2993
+ }
2994
+ async function outputJson(projectDir, results) {
2995
+ const summary = computeSummary(results);
2996
+ const fixed = results.filter((r) => r.fixed).length;
2997
+ const output = {
2998
+ project: projectDir,
2999
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
3000
+ checks: results,
3001
+ summary: {
3002
+ total: results.length,
3003
+ passed: results.filter((r) => r.passed).length,
3004
+ failed: results.filter((r) => !r.passed).length,
3005
+ warnings: summary.warnings,
3006
+ fixed
3007
+ }
3008
+ };
3009
+ console.log(JSON.stringify(output, null, 2));
3010
+ }
3011
+ async function outputReport(projectDir, results, options) {
3012
+ const summary = computeSummary(results);
3013
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
3014
+ let markdown = `# Thanh Kit Doctor Report
3015
+
3016
+ `;
3017
+ markdown += `**Project:** ${projectDir}
3018
+ `;
3019
+ markdown += `**Timestamp:** ${timestamp}
3020
+
3021
+ `;
3022
+ markdown += `## Summary
3023
+
3024
+ `;
3025
+ markdown += `- Total checks: ${results.length}
3026
+ `;
3027
+ markdown += `- Passed: ${results.filter((r) => r.passed).length}
3028
+ `;
3029
+ markdown += `- Failed: ${results.filter((r) => !r.passed).length}
3030
+ `;
3031
+ markdown += `- Errors: ${summary.issues}
3032
+ `;
3033
+ markdown += `- Warnings: ${summary.warnings}
3034
+ `;
3035
+ if (options.fix) {
3036
+ markdown += `- Fixed: ${results.filter((r) => r.fixed).length}
3037
+ `;
3038
+ }
3039
+ markdown += `
3040
+ `;
3041
+ markdown += `## Check Results
3042
+
3043
+ `;
3044
+ for (const r of results) {
3045
+ const icon = r.passed ? "\u2713" : r.severity === "error" ? "\u2717" : "\u26A0";
3046
+ markdown += `### ${icon} ${r.label}
3047
+
3048
+ `;
3049
+ markdown += `- **Status:** ${r.passed ? "PASS" : "FAIL"}
3050
+ `;
3051
+ markdown += `- **Severity:** ${r.severity}
3052
+ `;
3053
+ if (r.fixed) {
3054
+ markdown += `- **Fixed:** Yes
3055
+ `;
3056
+ }
3057
+ if (r.fixError) {
3058
+ markdown += `- **Fix Error:** ${r.fixError}
3059
+ `;
3060
+ }
3061
+ if (r.meta && Object.keys(r.meta).length > 0) {
3062
+ markdown += `- **Details:** ${JSON.stringify(r.meta)}
3063
+ `;
3064
+ }
3065
+ markdown += `
3066
+ `;
3067
+ }
3068
+ markdown += `## Suggestions
3069
+
3070
+ `;
3071
+ const failedChecks = results.filter((r) => !r.passed);
3072
+ if (failedChecks.length === 0) {
3073
+ markdown += `All checks passed! No suggestions.
3074
+ `;
3075
+ } else {
3076
+ for (const r of failedChecks) {
3077
+ if (r.name === "project") {
3078
+ markdown += `- Run "tk init ." to initialize this directory
3079
+ `;
3080
+ }
3081
+ if (r.name === "state") {
3082
+ markdown += `- State file is missing. Re-run "tk init" or create manually
3083
+ `;
3084
+ }
3085
+ if (r.name === "source" && r.meta?.source) {
3086
+ markdown += `- Update source path: tk update --source <new-path>
3087
+ `;
3088
+ }
3089
+ }
3090
+ }
3091
+ const reportPath = join12(projectDir, ".ak", "doctor-report.md");
3092
+ await fs12.ensureDir(join12(projectDir, ".ak"));
3093
+ await fs12.writeFile(reportPath, markdown, "utf-8");
3094
+ if (!options.json) {
3095
+ console.log(pc7.green(`
3096
+ \u2713 Report saved to ${reportPath}
3097
+ `));
3098
+ }
3099
+ }
3100
+ async function outputColored(projectDir, results, state, targetDir) {
3101
+ console.log(pc7.bold(pc7.cyan("\nThanh Kit Doctor\n")));
3102
+ console.log(pc7.gray("Checking project health...\n"));
3103
+ for (const r of results) {
3104
+ if (r.passed) {
3105
+ let msg = `\u2713 ${r.label}`;
3106
+ if (r.name === "target" && r.meta?.folder) {
3107
+ msg += ` (${r.meta.folder})`;
3108
+ }
3109
+ if (r.name.startsWith("subdirs_") && r.meta?.items !== void 0) {
3110
+ msg += ` (${r.meta.items} items)`;
3111
+ }
3112
+ console.log(pc7.green(msg));
3113
+ } else {
3114
+ const icon = r.severity === "error" ? "\u2717" : "\u26A0";
3115
+ const color = r.severity === "error" ? pc7.red : pc7.yellow;
3116
+ let msg = `${icon} ${r.label}`;
3117
+ if (r.name === "target") {
3118
+ msg = `${icon} No target directory (.claude/, .opencode/, .agent/)`;
3119
+ }
3120
+ if (r.name === "agents_md") {
3121
+ msg = `${icon} AGENTS.md not found (optional but recommended)`;
3122
+ }
3123
+ if (r.name === "source" && r.meta?.source) {
3124
+ msg = `${icon} Source directory not found: ${r.meta.source}`;
3125
+ }
3126
+ if (r.name.startsWith("subdirs_")) {
3127
+ const dir = r.name.replace("subdirs_", "");
3128
+ msg = `${icon} ${dir}/ not found`;
3129
+ }
3130
+ console.log(color(msg));
3131
+ }
3132
+ }
3133
+ console.log("");
3134
+ console.log(pc7.gray("Source detection:"));
3135
+ const source = resolveSource();
3136
+ if ("error" in source) {
3137
+ console.log(pc7.yellow(` \u26A0 ${source.error}`));
3138
+ } else {
3139
+ console.log(pc7.green(` \u2713 Found source: ${source.path}`));
3140
+ console.log(pc7.gray(` Type: ${source.type || "unknown"}`));
3141
+ }
3142
+ const summary = computeSummary(results);
3143
+ console.log("");
3144
+ console.log(pc7.cyan("\u2500".repeat(40)));
3145
+ if (summary.issues === 0 && summary.warnings === 0) {
3146
+ console.log(pc7.bold(pc7.green("\n\u2713 All checks passed!\n")));
3147
+ } else if (summary.issues === 0) {
3148
+ console.log(pc7.yellow(`
3149
+ \u26A0 ${summary.warnings} warning(s), no critical issues
3150
+ `));
3151
+ } else {
3152
+ console.log(pc7.red(`
3153
+ \u2717 ${summary.issues} issue(s), ${summary.warnings} warning(s)
3154
+ `));
3155
+ }
3156
+ if (summary.issues > 0 || summary.warnings > 0) {
3157
+ console.log(pc7.cyan("Suggestions:"));
3158
+ const isProject = results.find((r) => r.name === "project")?.passed;
3159
+ const hasState = results.find((r) => r.name === "state")?.passed;
3160
+ if (!isProject) {
3161
+ console.log(pc7.white(' \u2022 Run "tk init ." to initialize this directory'));
3162
+ }
3163
+ if (!hasState && isProject) {
3164
+ console.log(pc7.white(' \u2022 State file is missing. Re-run "tk init" or create manually'));
3165
+ }
3166
+ if (state && state.source && !fs12.existsSync(state.source)) {
3167
+ console.log(pc7.white(" \u2022 Update source path: tk update --source <new-path>"));
3168
+ }
3169
+ console.log("");
3170
+ }
3171
+ }
3172
+ var init_doctor = __esm({
3173
+ "src/commands/doctor.ts"() {
3174
+ "use strict";
3175
+ init_paths();
3176
+ init_state();
3177
+ }
3178
+ });
3179
+
3180
+ // src/commands/help.ts
3181
+ var help_exports = {};
3182
+ __export(help_exports, {
3183
+ helpCommand: () => helpCommand
3184
+ });
3185
+ import { exec } from "child_process";
3186
+ import pc8 from "picocolors";
3187
+ async function helpCommand(options) {
3188
+ console.log(pc8.cyan("\n\u{1F4DA} Opening VividKit documentation...\n"));
3189
+ console.log(pc8.green(` ${HELP_URL}
3190
+ `));
3191
+ const openCommand = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
3192
+ exec(`${openCommand} ${HELP_URL}`);
3193
+ }
3194
+ var HELP_URL;
3195
+ var init_help = __esm({
3196
+ "src/commands/help.ts"() {
3197
+ "use strict";
3198
+ HELP_URL = "https://www.vividkit.dev/vi/guides/what-is-claudekit";
3199
+ }
3200
+ });
3201
+
3202
+ // src/commands/uninstall.ts
3203
+ var uninstall_exports = {};
3204
+ __export(uninstall_exports, {
3205
+ uninstallCommand: () => uninstallCommand
3206
+ });
3207
+ import fs13 from "fs-extra";
3208
+ import { join as join13 } from "path";
3209
+ import pc9 from "picocolors";
3210
+ import ora4 from "ora";
3211
+ import * as p2 from "@clack/prompts";
3212
+ async function uninstallCommand(options) {
3213
+ p2.intro(pc9.bgCyan(pc9.black(" AK Uninstall ")));
3214
+ const targets = [];
3215
+ if (options.local || !options.global && !options.local) {
3216
+ targets.push({ type: "local", dir: process.cwd() });
3217
+ }
3218
+ if (options.global) {
3219
+ targets.push({ type: "global", dir: getGlobalInstallPath() });
3220
+ }
3221
+ let totalRemoved = 0;
3222
+ for (const target of targets) {
3223
+ const count = await uninstallFromDir(target.type, target.dir, options);
3224
+ totalRemoved += count;
3225
+ }
3226
+ if (totalRemoved === 0) {
3227
+ p2.outro(pc9.yellow("No installations found to remove."));
3228
+ } else {
3229
+ p2.outro(pc9.green(`Successfully removed ${totalRemoved} item(s).`));
3230
+ }
3231
+ }
3232
+ async function uninstallFromDir(type, dir, options) {
3233
+ const spinner = ora4(`Scanning ${type} installation at ${pc9.dim(dir)}`).start();
3234
+ const state = await loadState(dir);
3235
+ const existingTargets = [];
3236
+ for (const [name, folder] of Object.entries(TARGETS)) {
3237
+ const targetPath = join13(dir, folder);
3238
+ if (fs13.existsSync(targetPath)) {
3239
+ existingTargets.push({ name, path: targetPath });
3240
+ }
3241
+ }
3242
+ const akDir = join13(dir, ".ak");
3243
+ const hasAkState = fs13.existsSync(akDir);
3244
+ if (existingTargets.length === 0 && !hasAkState) {
3245
+ spinner.warn(pc9.yellow(`No AK installation found in ${type}`));
3246
+ return 0;
3247
+ }
3248
+ spinner.succeed(pc9.green(`Found AK installation in ${type}`));
3249
+ const removalList = [];
3250
+ for (const target of existingTargets) {
3251
+ for (const subdir of AK_SUBDIRS) {
3252
+ const subdirPath = join13(target.path, subdir);
3253
+ if (fs13.existsSync(subdirPath)) {
3254
+ removalList.push(subdirPath);
3255
+ }
3256
+ }
3257
+ }
3258
+ if (hasAkState) {
3259
+ removalList.push(akDir);
3260
+ }
3261
+ if (removalList.length === 0) {
3262
+ console.log(pc9.yellow(` No files to remove from ${type}`));
3263
+ return 0;
3264
+ }
3265
+ console.log(pc9.cyan(`
3266
+ Items to remove from ${type}:`));
3267
+ for (const path of removalList) {
3268
+ const relativePath = path.replace(dir + "/", "");
3269
+ console.log(pc9.dim(` \u2022 ${relativePath}`));
3270
+ }
3271
+ if (state) {
3272
+ console.log(pc9.dim(`
3273
+ Kit: ${state.kit}`));
3274
+ console.log(pc9.dim(` Target: ${state.target}`));
3275
+ }
3276
+ console.log(pc9.yellow(`
3277
+ Preserved files: ${PRESERVED_FILES.join(", ")}`));
3278
+ if (options.dryRun) {
3279
+ console.log(pc9.yellow(`
3280
+ [DRY RUN] Would remove ${removalList.length} item(s)`));
3281
+ return 0;
3282
+ }
3283
+ if (!options.yes) {
3284
+ const confirmed = await p2.confirm({
3285
+ message: `Remove ${removalList.length} item(s) from ${type}?`,
3286
+ initialValue: false
3287
+ });
3288
+ if (p2.isCancel(confirmed) || !confirmed) {
3289
+ console.log(pc9.dim(" Cancelled."));
3290
+ return 0;
3291
+ }
3292
+ }
3293
+ const result = await removeItems(removalList, dir);
3294
+ if (result.removed.length > 0) {
3295
+ console.log(pc9.green(`
3296
+ \u2713 Removed ${result.removed.length} item(s) from ${type}`));
3297
+ for (const path of result.removed) {
3298
+ const relativePath = path.replace(dir + "/", "");
3299
+ console.log(pc9.dim(` \u2022 ${relativePath}`));
3300
+ }
3301
+ }
3302
+ if (result.errors.length > 0) {
3303
+ console.log(pc9.red(`
3304
+ \u2717 Failed to remove ${result.errors.length} item(s):`));
3305
+ for (const error of result.errors) {
3306
+ const relativePath = error.path.replace(dir + "/", "");
3307
+ console.log(pc9.red(` \u2022 ${relativePath}: ${error.error}`));
3308
+ }
3309
+ }
3310
+ return result.removed.length;
3311
+ }
3312
+ async function removeItems(paths, baseDir) {
3313
+ const result = {
3314
+ removed: [],
3315
+ errors: []
3316
+ };
3317
+ for (const path of paths) {
3318
+ if (!path.startsWith(baseDir)) {
3319
+ result.errors.push({
3320
+ path,
3321
+ error: "Path outside base directory (security check failed)"
3322
+ });
3323
+ continue;
3324
+ }
3325
+ const isExpectedPath = path.includes("/.ak") || AK_SUBDIRS.some((subdir) => path.includes(`/${subdir}`));
3326
+ if (!isExpectedPath) {
3327
+ result.errors.push({
3328
+ path,
3329
+ error: "Path is not an expected AK directory (security check failed)"
3330
+ });
3331
+ continue;
3332
+ }
3333
+ try {
3334
+ await fs13.remove(path);
3335
+ result.removed.push(path);
3336
+ } catch (error) {
3337
+ result.errors.push({
3338
+ path,
3339
+ error: error instanceof Error ? error.message : String(error)
3340
+ });
3341
+ }
3342
+ }
3343
+ return result;
3344
+ }
3345
+ var PRESERVED_FILES, AK_SUBDIRS;
3346
+ var init_uninstall = __esm({
3347
+ "src/commands/uninstall.ts"() {
3348
+ "use strict";
3349
+ init_paths();
3350
+ init_state();
3351
+ PRESERVED_FILES = ["CLAUDE.md", "settings.json", "AGENTS.md"];
3352
+ AK_SUBDIRS = ["agents", "skills", "commands", "workflows", "hooks", "router"];
3353
+ }
3354
+ });
3355
+
3356
+ // src/utils/git-tags.ts
3357
+ import { execSync } from "child_process";
3358
+ function fetchRemoteTags(repoUrl = REMOTE_REPO_URL) {
3359
+ const output = execSync(`git ls-remote --tags "${repoUrl}"`, {
3360
+ encoding: "utf-8",
3361
+ timeout: 15e3,
3362
+ stdio: ["pipe", "pipe", "pipe"]
3363
+ });
3364
+ return output.split("\n").filter((line) => line.includes("refs/tags/")).map((line) => {
3365
+ const tag = line.split("refs/tags/")[1]?.replace("^{}", "");
3366
+ return tag;
3367
+ }).filter(Boolean).filter((v, i, a) => a.indexOf(v) === i);
3368
+ }
3369
+ function sortSemver(tags) {
3370
+ return [...tags].sort((a, b) => {
3371
+ const pa = a.replace(/^v/, "").split(/[.-]/);
3372
+ const pb = b.replace(/^v/, "").split(/[.-]/);
3373
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
3374
+ const na = parseInt(pa[i]) || 0;
3375
+ const nb = parseInt(pb[i]) || 0;
3376
+ if (na !== nb) return nb - na;
3377
+ }
3378
+ return 0;
3379
+ });
3380
+ }
3381
+ var REMOTE_REPO_URL;
3382
+ var init_git_tags = __esm({
3383
+ "src/utils/git-tags.ts"() {
3384
+ "use strict";
3385
+ REMOTE_REPO_URL = "https://github.com/Thanhnguyen6702/CK-Internal.git";
3386
+ }
3387
+ });
3388
+
3389
+ // src/commands/versions.ts
3390
+ var versions_exports = {};
3391
+ __export(versions_exports, {
3392
+ versionsCommand: () => versionsCommand
3393
+ });
3394
+ import pc10 from "picocolors";
3395
+ import ora5 from "ora";
3396
+ async function versionsCommand(options) {
3397
+ const spinner = ora5("Fetching available versions...").start();
3398
+ try {
3399
+ const tags = fetchRemoteTags();
3400
+ spinner.stop();
3401
+ if (!tags || tags.length === 0) {
3402
+ console.log(pc10.yellow("\nNo versions found."));
3403
+ return;
3404
+ }
3405
+ let filtered = tags;
3406
+ if (!options.all) {
3407
+ filtered = tags.filter((tag) => !tag.includes("-"));
3408
+ }
3409
+ const sorted = sortSemver(filtered);
3410
+ const limit = options.limit ? parseInt(options.limit, 10) : 10;
3411
+ const limited = sorted.slice(0, limit);
3412
+ console.log(pc10.bold("\nAvailable versions:\n"));
3413
+ limited.forEach((tag, index) => {
3414
+ const isLatest = index === 0;
3415
+ const marker = isLatest ? pc10.green(" (latest)") : "";
3416
+ console.log(` ${pc10.cyan(tag)}${marker}`);
3417
+ });
3418
+ if (sorted.length > limited.length) {
3419
+ console.log(pc10.gray(`
3420
+ ... and ${sorted.length - limited.length} more (use --limit or --all)`));
3421
+ }
3422
+ console.log("");
3423
+ } catch (err) {
3424
+ spinner.stop();
3425
+ console.log(pc10.red("\nFailed to fetch versions."));
3426
+ console.log(pc10.gray(err.message));
3427
+ if (err.message.includes("timeout")) {
3428
+ console.log(pc10.gray("Network timeout. Check your connection."));
3429
+ }
3430
+ }
3431
+ }
3432
+ var init_versions = __esm({
3433
+ "src/commands/versions.ts"() {
3434
+ "use strict";
3435
+ init_git_tags();
3436
+ }
3437
+ });
3438
+
3439
+ // src/commands/update-cli.ts
3440
+ var update_cli_exports = {};
3441
+ __export(update_cli_exports, {
3442
+ updateCliCommand: () => updateCliCommand
3443
+ });
3444
+ import { execSync as execSync2 } from "child_process";
3445
+ import pc11 from "picocolors";
3446
+ import ora6 from "ora";
3447
+ import { readFileSync } from "fs";
3448
+ import { join as join14 } from "path";
3449
+ function getCurrentVersion() {
3450
+ try {
3451
+ const pkg = JSON.parse(readFileSync(join14(CLI_ROOT, "package.json"), "utf-8"));
3452
+ return pkg.version;
3453
+ } catch {
3454
+ return "0.0.0";
3455
+ }
3456
+ }
3457
+ function getLatestVersion() {
3458
+ const output = execSync2("npm view thanh-kit version", {
3459
+ encoding: "utf-8",
3460
+ timeout: 15e3,
3461
+ stdio: ["pipe", "pipe", "pipe"]
3462
+ });
3463
+ return output.trim();
3464
+ }
3465
+ async function updateCliCommand(options) {
3466
+ const current = getCurrentVersion();
3467
+ const spinner = ora6("Checking for updates...").start();
3468
+ try {
3469
+ const latest = options.version || getLatestVersion();
3470
+ spinner.stop();
3471
+ console.log(`
3472
+ Current: ${pc11.gray(current)}`);
3473
+ console.log(` Latest: ${pc11.green(latest)}`);
3474
+ if (current === latest && !options.version && !options.force) {
3475
+ console.log(pc11.green("\nAlready up to date!"));
3476
+ console.log(pc11.gray("Use --force to reinstall anyway."));
3477
+ return;
3478
+ }
3479
+ if (options.check) {
3480
+ console.log(pc11.yellow('\nUpdate available! Run "tk update-cli" to install.'));
3481
+ return;
3482
+ }
3483
+ const target = options.version || "latest";
3484
+ const installSpinner = ora6(`Installing thanh-kit@${target}...`).start();
3485
+ execSync2(`npm install -g thanh-kit@${target}`, {
3486
+ encoding: "utf-8",
3487
+ timeout: 6e4,
3488
+ stdio: ["pipe", "pipe", "pipe"]
3489
+ });
3490
+ installSpinner.succeed(pc11.green(`Updated to ${target}!`));
3491
+ } catch (err) {
3492
+ spinner.stop();
3493
+ console.log(pc11.red("\nUpdate failed."));
3494
+ console.log(pc11.gray(err.message));
3495
+ console.log(pc11.gray("\nTry manually: npm install -g thanh-kit"));
3496
+ }
3497
+ }
3498
+ var init_update_cli = __esm({
3499
+ "src/commands/update-cli.ts"() {
3500
+ "use strict";
3501
+ init_paths();
3502
+ }
3503
+ });
3504
+
3505
+ // src/commands/skills.ts
3506
+ var skills_exports = {};
3507
+ __export(skills_exports, {
3508
+ skillsCommand: () => skillsCommand
3509
+ });
3510
+ import pc12 from "picocolors";
3511
+ import fs14 from "fs-extra";
3512
+ import { join as join15 } from "path";
3513
+ import * as p3 from "@clack/prompts";
3514
+ async function skillsCommand(options) {
3515
+ const { name, agent, list, installed, uninstall, yes } = options;
3516
+ if (list || !name && !installed) {
3517
+ await listSkillsWithStatus();
3518
+ return;
3519
+ }
3520
+ if (installed && !name) {
3521
+ await showInstalledSkills();
3522
+ return;
3523
+ }
3524
+ if (!name) {
3525
+ console.log(pc12.red("Error: --name <skill> is required"));
3526
+ console.log(pc12.gray("Usage: ak skills --name <skill> [--agent <agents>] [--uninstall]"));
3527
+ process.exit(1);
3528
+ }
3529
+ const targetAgents = parseAgents(agent);
3530
+ if (uninstall) {
3531
+ await uninstallSkill(name, targetAgents, yes);
3532
+ return;
3533
+ }
3534
+ await installSkill(name, targetAgents, yes);
3535
+ }
3536
+ async function listSkillsWithStatus() {
3537
+ const source = resolveSource();
3538
+ if ("error" in source) {
3539
+ console.log(pc12.red(`Error: ${source.error}`));
3540
+ process.exit(1);
3541
+ }
3542
+ const skills = listAvailable("skills", source.claudeDir).filter((s) => s.isDir);
3543
+ if (skills.length === 0) {
3544
+ console.log(pc12.yellow("No skills found in source"));
3545
+ return;
3546
+ }
3547
+ console.log(pc12.bold(pc12.cyan(`
3548
+ Available Skills (${skills.length}):`)));
3549
+ console.log(pc12.gray(`Source: ${source.path}
3550
+ `));
3551
+ const header = " Skill".padEnd(40) + "Claude Cursor Codex";
3552
+ console.log(pc12.bold(header));
3553
+ console.log(pc12.gray(" " + "\u2500".repeat(58)));
3554
+ for (const skill of skills) {
3555
+ const claudeInstalled = isSkillInstalled(skill.name, "claude");
3556
+ const cursorInstalled = isSkillInstalled(skill.name, "cursor");
3557
+ const codexInstalled = isSkillInstalled(skill.name, "codex");
3558
+ const statusLine = " " + skill.name.padEnd(38) + (claudeInstalled ? pc12.green("\u2713") : pc12.gray("-")).padEnd(8) + (cursorInstalled ? pc12.green("\u2713") : pc12.gray("-")).padEnd(8) + (codexInstalled ? pc12.green("\u2713") : pc12.gray("-"));
3559
+ console.log(statusLine);
3560
+ }
3561
+ console.log("");
3562
+ console.log(pc12.gray("Install: ak skills --name <skill> --agent <claude|cursor|codex>"));
3563
+ console.log("");
3564
+ }
3565
+ async function showInstalledSkills() {
3566
+ console.log(pc12.bold(pc12.cyan("\nInstalled Skills:\n")));
3567
+ let hasAny = false;
3568
+ for (const [agentType, skillPath] of Object.entries(AGENT_SKILL_PATHS)) {
3569
+ const installed = getInstalledSkills(agentType);
3570
+ if (installed.length > 0) {
3571
+ hasAny = true;
3572
+ console.log(pc12.bold(` ${agentType}:`));
3573
+ for (const skill of installed) {
3574
+ console.log(pc12.white(` \u2022 ${skill}`));
3575
+ }
3576
+ console.log("");
3577
+ }
3578
+ }
3579
+ if (!hasAny) {
3580
+ console.log(pc12.gray(" No skills installed"));
3581
+ console.log("");
3582
+ }
3583
+ }
3584
+ async function installSkill(skillName, agents, skipConfirm) {
3585
+ const source = resolveSource();
3586
+ if ("error" in source) {
3587
+ console.log(pc12.red(`Error: ${source.error}`));
3588
+ process.exit(1);
3589
+ }
3590
+ const skillPath = join15(source.claudeDir, "skills", skillName);
3591
+ if (!fs14.existsSync(skillPath)) {
3592
+ console.log(pc12.red(`Error: Skill "${skillName}" not found in source`));
3593
+ console.log(pc12.gray(`Available skills: ak skills --list`));
3594
+ process.exit(1);
3595
+ }
3596
+ if (!skipConfirm) {
3597
+ const confirm4 = await p3.confirm({
3598
+ message: `Install skill "${skillName}" to ${agents.join(", ")}?`
3599
+ });
3600
+ if (p3.isCancel(confirm4) || !confirm4) {
3601
+ console.log(pc12.gray("Cancelled"));
3602
+ process.exit(0);
3603
+ }
3604
+ }
3605
+ const results = [];
3606
+ for (const agent of agents) {
3607
+ try {
3608
+ const targetPath = join15(process.cwd(), AGENT_SKILL_PATHS[agent], skillName);
3609
+ await fs14.ensureDir(join15(process.cwd(), AGENT_SKILL_PATHS[agent]));
3610
+ await fs14.copy(skillPath, targetPath, { overwrite: true });
3611
+ results.push({ agent, success: true });
3612
+ } catch (err) {
3613
+ results.push({ agent, success: false, error: err.message });
3614
+ }
3615
+ }
3616
+ console.log("");
3617
+ const allSuccess = results.every((r) => r.success);
3618
+ if (allSuccess) {
3619
+ console.log(pc12.green(`\u2713 Installed "${skillName}" to ${agents.join(", ")}`));
3620
+ } else {
3621
+ for (const result of results) {
3622
+ if (result.success) {
3623
+ console.log(pc12.green(`\u2713 ${result.agent}: installed`));
3624
+ } else {
3625
+ console.log(pc12.red(`\u2717 ${result.agent}: ${result.error}`));
3626
+ }
3627
+ }
3628
+ }
3629
+ console.log("");
3630
+ }
3631
+ async function uninstallSkill(skillName, agents, skipConfirm) {
3632
+ const installedIn = agents.filter((agent) => isSkillInstalled(skillName, agent));
3633
+ if (installedIn.length === 0) {
3634
+ console.log(pc12.yellow(`Skill "${skillName}" is not installed in ${agents.join(", ")}`));
3635
+ process.exit(0);
3636
+ }
3637
+ if (!skipConfirm) {
3638
+ const confirm4 = await p3.confirm({
3639
+ message: `Uninstall skill "${skillName}" from ${installedIn.join(", ")}?`
3640
+ });
3641
+ if (p3.isCancel(confirm4) || !confirm4) {
3642
+ console.log(pc12.gray("Cancelled"));
3643
+ process.exit(0);
3644
+ }
3645
+ }
3646
+ const results = [];
3647
+ for (const agent of installedIn) {
3648
+ try {
3649
+ const targetPath = join15(process.cwd(), AGENT_SKILL_PATHS[agent], skillName);
3650
+ await fs14.remove(targetPath);
3651
+ results.push({ agent, success: true });
3652
+ } catch (err) {
3653
+ results.push({ agent, success: false, error: err.message });
3654
+ }
3655
+ }
3656
+ console.log("");
3657
+ const allSuccess = results.every((r) => r.success);
3658
+ if (allSuccess) {
3659
+ console.log(pc12.green(`\u2713 Uninstalled "${skillName}" from ${installedIn.join(", ")}`));
3660
+ } else {
3661
+ for (const result of results) {
3662
+ if (result.success) {
3663
+ console.log(pc12.green(`\u2713 ${result.agent}: uninstalled`));
3664
+ } else {
3665
+ console.log(pc12.red(`\u2717 ${result.agent}: ${result.error}`));
3666
+ }
3667
+ }
3668
+ }
3669
+ console.log("");
3670
+ }
3671
+ function parseAgents(agentFlag) {
3672
+ if (!agentFlag) {
3673
+ return ["claude"];
3674
+ }
3675
+ const agents = agentFlag.split(",").map((a) => a.trim().toLowerCase());
3676
+ const valid = agents.filter((a) => a in AGENT_SKILL_PATHS);
3677
+ if (valid.length === 0) {
3678
+ console.log(pc12.red("Error: No valid agents specified"));
3679
+ console.log(pc12.gray("Valid agents: claude, cursor, codex"));
3680
+ process.exit(1);
3681
+ }
3682
+ return valid;
3683
+ }
3684
+ function isSkillInstalled(skillName, agent) {
3685
+ const skillPath = join15(process.cwd(), AGENT_SKILL_PATHS[agent], skillName);
3686
+ return fs14.existsSync(skillPath);
3687
+ }
3688
+ function getInstalledSkills(agent) {
3689
+ const skillsDir = join15(process.cwd(), AGENT_SKILL_PATHS[agent]);
3690
+ if (!fs14.existsSync(skillsDir)) {
3691
+ return [];
3692
+ }
3693
+ try {
3694
+ const items = fs14.readdirSync(skillsDir);
3695
+ return items.filter((item) => {
3696
+ const itemPath = join15(skillsDir, item);
3697
+ return fs14.statSync(itemPath).isDirectory();
3698
+ });
3699
+ } catch {
3700
+ return [];
3701
+ }
3702
+ }
3703
+ var AGENT_SKILL_PATHS;
3704
+ var init_skills = __esm({
3705
+ "src/commands/skills.ts"() {
3706
+ "use strict";
3707
+ init_paths();
3708
+ init_copy();
3709
+ AGENT_SKILL_PATHS = {
3710
+ claude: ".claude/skills",
3711
+ cursor: ".cursor/rules",
3712
+ codex: ".codex/skills"
3713
+ };
3714
+ }
3715
+ });
3716
+
3717
+ // src/index.ts
3718
+ import cac from "cac";
3719
+ import { readFileSync as readFileSync3 } from "fs";
3720
+ import { fileURLToPath as fileURLToPath2 } from "url";
3721
+ import { dirname as dirname6, join as join17 } from "path";
3722
+ import pc13 from "picocolors";
3723
+
3724
+ // src/cli/command-registry.ts
3725
+ function registerCommands(cli2) {
3726
+ cli2.command("init [project-name]", "Initialize a new project with an agent kit").option("-k, --kit <type>", "Kit type (engineer, researcher, designer, minimal, full, custom)").option("-t, --target <target>", "Target CLI (claude, gemini, discord or combination)").option("-s, --source <path>", "Custom source path for templates").option("-f, --force", "Overwrite existing directory").option("-g, --global", "Install to global ~/.claude/ directory").option("--fresh", "Remove existing installation before re-init").option("-y, --yes", "Skip prompts, use defaults").option("-p, --password <code>", "Access code for initialization").option("--exclude <patterns>", "Exclude components (comma-separated)").option("--only <patterns>", "Include only matching components (comma-separated)").action(async (projectName, options) => {
3727
+ const { initCommand: initCommand2 } = await Promise.resolve().then(() => (init_init(), init_exports));
3728
+ await initCommand2(projectName, options);
3729
+ });
3730
+ cli2.command("add <item>", "Add agent, skill, or command (e.g., tk add skill:databases)").option("-s, --source <path>", "Custom source path").option("-p, --path <path>", "Target project path").action(async (item, options) => {
3731
+ const { addCommand: addCommand2 } = await Promise.resolve().then(() => (init_add(), add_exports));
3732
+ await addCommand2(item, options);
3733
+ });
3734
+ cli2.command("list [type]", "List available kits, agents, skills, or commands").option("-s, --source <path>", "Custom source path").action(async (type, options) => {
3735
+ const { listCommand: listCommand2 } = await Promise.resolve().then(() => (init_list(), list_exports));
3736
+ await listCommand2(type, options);
3737
+ });
3738
+ cli2.command("update", "Update/sync from source templates").option("-s, --source <path>", "Source path to sync from").option("--agents", "Update only agents").option("--skills", "Update only skills").option("--commands", "Update only commands").option("--all", "Update everything").option("-n, --dry-run", "Show what would be updated without making changes").option("-f, --force", "Force update without confirmation").action(async (options) => {
3739
+ const { updateCommand: updateCommand2 } = await Promise.resolve().then(() => (init_update(), update_exports));
3740
+ await updateCommand2(options);
3741
+ });
3742
+ cli2.command("status", "Show project status and file changes").option("-v, --verbose", "Show all files").action(async (options) => {
3743
+ const { statusCommand: statusCommand2 } = await Promise.resolve().then(() => (init_status(), status_exports));
3744
+ await statusCommand2(options);
3745
+ });
3746
+ cli2.command("doctor", "Check project health and diagnose issues").option("--fix", "Auto-fix common issues").option("--report", "Generate diagnostic report").option("--json", "Output JSON format").option("--check-only", "CI mode: exit 1 on failures").action(async (options) => {
3747
+ const { doctorCommand: doctorCommand2 } = await Promise.resolve().then(() => (init_doctor(), doctor_exports));
3748
+ await doctorCommand2(options);
3749
+ });
3750
+ cli2.command("kits", "List all available kits").action(async () => {
3751
+ const { listCommand: listCommand2 } = await Promise.resolve().then(() => (init_list(), list_exports));
3752
+ await listCommand2("kits", {});
3753
+ });
3754
+ cli2.command("help", "Open interactive help documentation in browser").option("-s, --source <path>", "Custom source path").action(async (options) => {
3755
+ const { helpCommand: helpCommand2 } = await Promise.resolve().then(() => (init_help(), help_exports));
3756
+ await helpCommand2(options);
3757
+ });
3758
+ cli2.command("uninstall", "Remove ClaudeKit installations").option("-y, --yes", "Skip confirmation").option("-l, --local", "Uninstall only local installation").option("-g, --global", "Uninstall only global installation").option("--dry-run", "Preview what would be removed").action(async (options) => {
3759
+ const { uninstallCommand: uninstallCommand2 } = await Promise.resolve().then(() => (init_uninstall(), uninstall_exports));
3760
+ await uninstallCommand2(options);
3761
+ });
3762
+ cli2.command("versions", "List available versions").option("--kit <kit>", "Filter by kit").option("--limit <limit>", "Number of versions to show").option("--all", "Show all including prereleases").action(async (options) => {
3763
+ const { versionsCommand: versionsCommand2 } = await Promise.resolve().then(() => (init_versions(), versions_exports));
3764
+ await versionsCommand2(options);
3765
+ });
3766
+ cli2.command("update-cli", "Update the CLI itself to latest version").option("--check", "Check for updates without installing").option("--version <version>", "Update to specific version").option("-f, --force", "Force reinstall even if already up to date").action(async (options) => {
3767
+ const { updateCliCommand: updateCliCommand2 } = await Promise.resolve().then(() => (init_update_cli(), update_cli_exports));
3768
+ await updateCliCommand2(options);
3769
+ });
3770
+ cli2.command("skills", "Manage skills across coding agents").option("-n, --name <skill>", "Skill name").option("-a, --agent <agents>", "Target agents").option("-l, --list", "List available skills").option("--installed", "Show installed skills").option("-u, --uninstall", "Uninstall skill").option("-y, --yes", "Skip confirmation").action(async (options) => {
3771
+ const { skillsCommand: skillsCommand2 } = await Promise.resolve().then(() => (init_skills(), skills_exports));
3772
+ await skillsCommand2(options);
3773
+ });
3774
+ }
3775
+
3776
+ // src/utils/version-check.ts
3777
+ import { join as join16 } from "path";
3778
+ import { homedir as homedir2 } from "os";
3779
+ import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync, mkdirSync } from "fs";
3780
+ var CACHE_DIR = join16(homedir2(), ".thanh-kit");
3781
+ var CACHE_FILE = join16(CACHE_DIR, "version-check.json");
3782
+ var CACHE_TTL = 7 * 24 * 60 * 60 * 1e3;
3783
+ function getCachedVersionNoFetch() {
3784
+ try {
3785
+ if (existsSync2(CACHE_FILE)) {
3786
+ const cache = JSON.parse(readFileSync2(CACHE_FILE, "utf-8"));
3787
+ return cache.version;
3788
+ }
3789
+ } catch {
3790
+ }
3791
+ return null;
3792
+ }
3793
+ function isNewerVersion(current, latest) {
3794
+ const c = current.replace(/^v/, "").split(".").map(Number);
3795
+ const l = latest.replace(/^v/, "").split(".").map(Number);
3796
+ for (let i = 0; i < 3; i++) {
3797
+ if ((l[i] || 0) > (c[i] || 0)) return true;
3798
+ if ((l[i] || 0) < (c[i] || 0)) return false;
3799
+ }
3800
+ return false;
3801
+ }
3802
+
3803
+ // src/index.ts
3804
+ var __filename2 = fileURLToPath2(import.meta.url);
3805
+ var __dirname2 = dirname6(__filename2);
3806
+ function getVersion() {
3807
+ try {
3808
+ const pkg = JSON.parse(readFileSync3(join17(__dirname2, "..", "package.json"), "utf-8"));
3809
+ return pkg.version;
3810
+ } catch {
3811
+ return "0.0.0";
3812
+ }
3813
+ }
3814
+ var cli = cac("tk");
3815
+ registerCommands(cli);
3816
+ cli.help();
3817
+ cli.version(getVersion());
3818
+ cli.parse();
3819
+ try {
3820
+ const version = getVersion();
3821
+ const cachedLatest = getCachedVersionNoFetch();
3822
+ if (cachedLatest && isNewerVersion(version, cachedLatest)) {
3823
+ console.log(pc13.yellow(`
3824
+ Update available: v${version} \u2192 v${cachedLatest}`));
3825
+ console.log(pc13.gray(' Run "tk update-cli" to update\n'));
3826
+ }
3827
+ } catch {
3828
+ }
3829
+ //# sourceMappingURL=index.js.map