claude-code-workflow 6.3.18 → 6.3.19

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 (822) hide show
  1. package/.claude/CLAUDE.md +8 -5
  2. package/.claude/agents/action-planning-agent.md +26 -2
  3. package/.claude/agents/code-developer.md +132 -43
  4. package/.claude/agents/debug-explore-agent.md +434 -0
  5. package/.claude/agents/test-fix-agent.md +14 -0
  6. package/.claude/commands/issue/discover.md +41 -0
  7. package/.claude/commands/issue/execute.md +200 -19
  8. package/.claude/commands/issue/new.md +1 -1
  9. package/.claude/commands/issue/plan.md +6 -1
  10. package/.claude/commands/issue/queue.md +94 -39
  11. package/.claude/commands/memory/swagger-docs.md +773 -0
  12. package/.claude/commands/workflow/brainstorm/auto-parallel.md +21 -21
  13. package/.claude/commands/workflow/execute.md +54 -34
  14. package/.claude/commands/workflow/lite-execute.md +48 -164
  15. package/.claude/commands/workflow/lite-fix.md +4 -4
  16. package/.claude/commands/workflow/lite-plan.md +5 -5
  17. package/.claude/commands/workflow/plan.md +27 -27
  18. package/.claude/commands/workflow/review.md +42 -17
  19. package/.claude/commands/workflow/tdd-plan.md +25 -25
  20. package/.claude/commands/workflow/test-fix-gen.md +10 -10
  21. package/.claude/commands/workflow/test-gen.md +14 -14
  22. package/.claude/commands/workflow/ui-design/explore-auto.md +21 -21
  23. package/.claude/commands/workflow/ui-design/imitate-auto.md +24 -24
  24. package/.claude/skills/_shared/SKILL-DESIGN-SPEC.md +693 -0
  25. package/.claude/skills/ccw/SKILL.md +462 -0
  26. package/.claude/skills/ccw/index/command-capabilities.json +127 -0
  27. package/.claude/skills/ccw/index/intent-rules.json +136 -0
  28. package/.claude/skills/ccw/index/workflow-chains.json +451 -0
  29. package/.claude/skills/ccw/phases/actions/bugfix.md +218 -0
  30. package/.claude/skills/ccw/phases/actions/coupled.md +194 -0
  31. package/.claude/skills/ccw/phases/actions/docs.md +93 -0
  32. package/.claude/skills/ccw/phases/actions/full.md +154 -0
  33. package/.claude/skills/ccw/phases/actions/issue.md +201 -0
  34. package/.claude/skills/ccw/phases/actions/rapid.md +104 -0
  35. package/.claude/skills/ccw/phases/actions/review-fix.md +84 -0
  36. package/.claude/skills/ccw/phases/actions/tdd.md +66 -0
  37. package/.claude/skills/ccw/phases/actions/ui.md +79 -0
  38. package/.claude/skills/ccw/phases/orchestrator.md +435 -0
  39. package/.claude/skills/ccw/specs/intent-classification.md +336 -0
  40. package/.claude/skills/ccw-help/SKILL.md +177 -0
  41. package/.claude/skills/ccw-help/index/all-agents.json +82 -0
  42. package/.claude/skills/{command-guide → ccw-help}/index/all-commands.json +183 -73
  43. package/.claude/skills/{command-guide → ccw-help}/index/by-category.json +187 -73
  44. package/.claude/skills/{command-guide → ccw-help}/index/by-use-case.json +295 -185
  45. package/.claude/skills/{command-guide → ccw-help}/index/command-relationships.json +19 -166
  46. package/.claude/skills/{command-guide → ccw-help}/index/essential-commands.json +10 -10
  47. package/.claude/skills/ccw-help/scripts/analyze_commands.py +337 -0
  48. package/.claude/skills/code-reviewer/README.md +340 -0
  49. package/.claude/skills/code-reviewer/SKILL.md +308 -0
  50. package/.claude/skills/code-reviewer/phases/01-code-discovery.md +246 -0
  51. package/.claude/skills/code-reviewer/phases/02-security-analysis.md +442 -0
  52. package/.claude/skills/code-reviewer/phases/03-best-practices-review.md +36 -0
  53. package/.claude/skills/code-reviewer/phases/04-report-generation.md +278 -0
  54. package/.claude/skills/code-reviewer/specs/best-practices-requirements.md +346 -0
  55. package/.claude/skills/code-reviewer/specs/quality-standards.md +252 -0
  56. package/.claude/skills/code-reviewer/specs/security-requirements.md +243 -0
  57. package/.claude/skills/code-reviewer/templates/best-practice-finding.md +234 -0
  58. package/.claude/skills/code-reviewer/templates/report-template.md +316 -0
  59. package/.claude/skills/code-reviewer/templates/security-finding.md +161 -0
  60. package/.claude/skills/skill-generator/SKILL.md +187 -0
  61. package/.claude/skills/skill-generator/phases/01-requirements-discovery.md +239 -0
  62. package/.claude/skills/skill-generator/phases/02-structure-generation.md +207 -0
  63. package/.claude/skills/skill-generator/phases/03-phase-generation.md +802 -0
  64. package/.claude/skills/skill-generator/phases/04-specs-templates.md +328 -0
  65. package/.claude/skills/skill-generator/phases/05-validation.md +334 -0
  66. package/.claude/skills/skill-generator/specs/cli-integration.md +448 -0
  67. package/.claude/skills/skill-generator/specs/execution-modes.md +396 -0
  68. package/.claude/skills/skill-generator/specs/scripting-integration.md +265 -0
  69. package/.claude/skills/skill-generator/specs/skill-requirements.md +466 -0
  70. package/.claude/skills/skill-generator/templates/autonomous-action.md +517 -0
  71. package/.claude/skills/skill-generator/templates/autonomous-orchestrator.md +276 -0
  72. package/.claude/skills/skill-generator/templates/code-analysis-action.md +503 -0
  73. package/.claude/skills/skill-generator/templates/llm-action.md +355 -0
  74. package/.claude/skills/skill-generator/templates/script-bash.md +277 -0
  75. package/.claude/skills/skill-generator/templates/script-python.md +198 -0
  76. package/.claude/skills/skill-generator/templates/sequential-phase.md +441 -0
  77. package/.claude/skills/skill-generator/templates/skill-md.md +156 -0
  78. package/.claude/workflows/chinese-response.md +15 -28
  79. package/.claude/workflows/cli-templates/prompts/documentation/swagger-api.txt +266 -0
  80. package/.claude/workflows/cli-tools-usage.md +221 -177
  81. package/.claude/workflows/windows-platform.md +13 -10
  82. package/.codex/prompts/issue-execute.md +305 -82
  83. package/.codex/prompts/issue-queue.md +22 -0
  84. package/.codex/prompts/lite-execute.md +36 -11
  85. package/README.md +309 -305
  86. package/ccw/README.md +10 -4
  87. package/ccw/dist/cli.d.ts.map +1 -1
  88. package/ccw/dist/cli.js +4 -1
  89. package/ccw/dist/cli.js.map +1 -1
  90. package/ccw/dist/commands/cli.d.ts.map +1 -1
  91. package/ccw/dist/commands/cli.js +131 -34
  92. package/ccw/dist/commands/cli.js.map +1 -1
  93. package/ccw/dist/commands/issue.d.ts +152 -0
  94. package/ccw/dist/commands/issue.d.ts.map +1 -1
  95. package/ccw/dist/commands/issue.js +550 -85
  96. package/ccw/dist/commands/issue.js.map +1 -1
  97. package/ccw/dist/commands/serve.d.ts +1 -0
  98. package/ccw/dist/commands/serve.d.ts.map +1 -1
  99. package/ccw/dist/commands/serve.js +12 -5
  100. package/ccw/dist/commands/serve.js.map +1 -1
  101. package/ccw/dist/commands/stop.d.ts.map +1 -1
  102. package/ccw/dist/commands/stop.js +29 -5
  103. package/ccw/dist/commands/stop.js.map +1 -1
  104. package/ccw/dist/commands/tool.d.ts.map +1 -1
  105. package/ccw/dist/commands/tool.js +19 -2
  106. package/ccw/dist/commands/tool.js.map +1 -1
  107. package/ccw/dist/commands/view.d.ts +1 -0
  108. package/ccw/dist/commands/view.d.ts.map +1 -1
  109. package/ccw/dist/commands/view.js +10 -3
  110. package/ccw/dist/commands/view.js.map +1 -1
  111. package/ccw/dist/config/cli-settings-manager.d.ts +86 -0
  112. package/ccw/dist/config/cli-settings-manager.d.ts.map +1 -0
  113. package/ccw/dist/config/cli-settings-manager.js +392 -0
  114. package/ccw/dist/config/cli-settings-manager.js.map +1 -0
  115. package/ccw/dist/config/litellm-api-config-manager.d.ts +71 -5
  116. package/ccw/dist/config/litellm-api-config-manager.d.ts.map +1 -1
  117. package/ccw/dist/config/litellm-api-config-manager.js +290 -20
  118. package/ccw/dist/config/litellm-api-config-manager.js.map +1 -1
  119. package/ccw/dist/core/auth/csrf-manager.d.ts +18 -0
  120. package/ccw/dist/core/auth/csrf-manager.d.ts.map +1 -0
  121. package/ccw/dist/core/auth/csrf-manager.js +80 -0
  122. package/ccw/dist/core/auth/csrf-manager.js.map +1 -0
  123. package/ccw/dist/core/auth/csrf-middleware.d.ts +8 -0
  124. package/ccw/dist/core/auth/csrf-middleware.d.ts.map +1 -0
  125. package/ccw/dist/core/auth/csrf-middleware.js +141 -0
  126. package/ccw/dist/core/auth/csrf-middleware.js.map +1 -0
  127. package/ccw/dist/core/auth/middleware.d.ts +15 -0
  128. package/ccw/dist/core/auth/middleware.d.ts.map +1 -0
  129. package/ccw/dist/core/auth/middleware.js +76 -0
  130. package/ccw/dist/core/auth/middleware.js.map +1 -0
  131. package/ccw/dist/core/auth/token-manager.d.ts +41 -0
  132. package/ccw/dist/core/auth/token-manager.d.ts.map +1 -0
  133. package/ccw/dist/core/auth/token-manager.js +171 -0
  134. package/ccw/dist/core/auth/token-manager.js.map +1 -0
  135. package/ccw/dist/core/cache-manager.d.ts +6 -6
  136. package/ccw/dist/core/cache-manager.d.ts.map +1 -1
  137. package/ccw/dist/core/cache-manager.js +70 -48
  138. package/ccw/dist/core/cache-manager.js.map +1 -1
  139. package/ccw/dist/core/claude-freshness.d.ts.map +1 -1
  140. package/ccw/dist/core/claude-freshness.js +23 -3
  141. package/ccw/dist/core/claude-freshness.js.map +1 -1
  142. package/ccw/dist/core/core-memory-store.d.ts.map +1 -1
  143. package/ccw/dist/core/core-memory-store.js +2 -1
  144. package/ccw/dist/core/core-memory-store.js.map +1 -1
  145. package/ccw/dist/core/cors.d.ts +3 -0
  146. package/ccw/dist/core/cors.d.ts.map +1 -0
  147. package/ccw/dist/core/cors.js +10 -0
  148. package/ccw/dist/core/cors.js.map +1 -0
  149. package/ccw/dist/core/dashboard-generator-patch.js +0 -1
  150. package/ccw/dist/core/dashboard-generator-patch.js.map +1 -1
  151. package/ccw/dist/core/dashboard-generator.d.ts.map +1 -1
  152. package/ccw/dist/core/dashboard-generator.js +417 -416
  153. package/ccw/dist/core/dashboard-generator.js.map +1 -1
  154. package/ccw/dist/core/data-aggregator.js +2 -2
  155. package/ccw/dist/core/data-aggregator.js.map +1 -1
  156. package/ccw/dist/core/lite-scanner.d.ts +1 -1
  157. package/ccw/dist/core/lite-scanner.d.ts.map +1 -1
  158. package/ccw/dist/core/lite-scanner.js +130 -127
  159. package/ccw/dist/core/lite-scanner.js.map +1 -1
  160. package/ccw/dist/core/routes/auth-routes.d.ts +12 -0
  161. package/ccw/dist/core/routes/auth-routes.d.ts.map +1 -0
  162. package/ccw/dist/core/routes/auth-routes.js +80 -0
  163. package/ccw/dist/core/routes/auth-routes.js.map +1 -0
  164. package/ccw/dist/core/routes/ccw-routes.d.ts +1 -14
  165. package/ccw/dist/core/routes/ccw-routes.d.ts.map +1 -1
  166. package/ccw/dist/core/routes/ccw-routes.js +9 -4
  167. package/ccw/dist/core/routes/ccw-routes.js.map +1 -1
  168. package/ccw/dist/core/routes/claude-routes.d.ts +1 -14
  169. package/ccw/dist/core/routes/claude-routes.d.ts.map +1 -1
  170. package/ccw/dist/core/routes/claude-routes.js +98 -39
  171. package/ccw/dist/core/routes/claude-routes.js.map +1 -1
  172. package/ccw/dist/core/routes/cli-routes.d.ts +14 -12
  173. package/ccw/dist/core/routes/cli-routes.d.ts.map +1 -1
  174. package/ccw/dist/core/routes/cli-routes.js +122 -43
  175. package/ccw/dist/core/routes/cli-routes.js.map +1 -1
  176. package/ccw/dist/core/routes/cli-settings-routes.d.ts +11 -0
  177. package/ccw/dist/core/routes/cli-settings-routes.d.ts.map +1 -0
  178. package/ccw/dist/core/routes/cli-settings-routes.js +204 -0
  179. package/ccw/dist/core/routes/cli-settings-routes.js.map +1 -0
  180. package/ccw/dist/core/routes/codexlens/config-handlers.d.ts +6 -0
  181. package/ccw/dist/core/routes/codexlens/config-handlers.d.ts.map +1 -0
  182. package/ccw/dist/core/routes/codexlens/config-handlers.js +1195 -0
  183. package/ccw/dist/core/routes/codexlens/config-handlers.js.map +1 -0
  184. package/ccw/dist/core/routes/codexlens/index-handlers.d.ts +10 -0
  185. package/ccw/dist/core/routes/codexlens/index-handlers.d.ts.map +1 -0
  186. package/ccw/dist/core/routes/codexlens/index-handlers.js +322 -0
  187. package/ccw/dist/core/routes/codexlens/index-handlers.js.map +1 -0
  188. package/ccw/dist/core/routes/codexlens/semantic-handlers.d.ts +6 -0
  189. package/ccw/dist/core/routes/codexlens/semantic-handlers.d.ts.map +1 -0
  190. package/ccw/dist/core/routes/codexlens/semantic-handlers.js +865 -0
  191. package/ccw/dist/core/routes/codexlens/semantic-handlers.js.map +1 -0
  192. package/ccw/dist/core/routes/codexlens/utils.d.ts +23 -0
  193. package/ccw/dist/core/routes/codexlens/utils.d.ts.map +1 -0
  194. package/ccw/dist/core/routes/codexlens/utils.js +85 -0
  195. package/ccw/dist/core/routes/codexlens/utils.js.map +1 -0
  196. package/ccw/dist/core/routes/codexlens/watcher-handlers.d.ts +13 -0
  197. package/ccw/dist/core/routes/codexlens/watcher-handlers.d.ts.map +1 -0
  198. package/ccw/dist/core/routes/codexlens/watcher-handlers.js +235 -0
  199. package/ccw/dist/core/routes/codexlens/watcher-handlers.js.map +1 -0
  200. package/ccw/dist/core/routes/codexlens-routes.d.ts +2 -11
  201. package/ccw/dist/core/routes/codexlens-routes.d.ts.map +1 -1
  202. package/ccw/dist/core/routes/codexlens-routes.js +10 -981
  203. package/ccw/dist/core/routes/codexlens-routes.js.map +1 -1
  204. package/ccw/dist/core/routes/discovery-routes.d.ts +1 -35
  205. package/ccw/dist/core/routes/discovery-routes.d.ts.map +1 -1
  206. package/ccw/dist/core/routes/discovery-routes.js +25 -0
  207. package/ccw/dist/core/routes/discovery-routes.js.map +1 -1
  208. package/ccw/dist/core/routes/files-routes.d.ts +1 -14
  209. package/ccw/dist/core/routes/files-routes.d.ts.map +1 -1
  210. package/ccw/dist/core/routes/files-routes.js +57 -14
  211. package/ccw/dist/core/routes/files-routes.js.map +1 -1
  212. package/ccw/dist/core/routes/graph-routes.d.ts +1 -14
  213. package/ccw/dist/core/routes/graph-routes.d.ts.map +1 -1
  214. package/ccw/dist/core/routes/graph-routes.js +36 -37
  215. package/ccw/dist/core/routes/graph-routes.js.map +1 -1
  216. package/ccw/dist/core/routes/help-routes.d.ts +1 -14
  217. package/ccw/dist/core/routes/help-routes.d.ts.map +1 -1
  218. package/ccw/dist/core/routes/help-routes.js +5 -0
  219. package/ccw/dist/core/routes/help-routes.js.map +1 -1
  220. package/ccw/dist/core/routes/hooks-routes.d.ts +4 -14
  221. package/ccw/dist/core/routes/hooks-routes.d.ts.map +1 -1
  222. package/ccw/dist/core/routes/hooks-routes.js +43 -21
  223. package/ccw/dist/core/routes/hooks-routes.js.map +1 -1
  224. package/ccw/dist/core/routes/issue-routes.d.ts +1 -34
  225. package/ccw/dist/core/routes/issue-routes.d.ts.map +1 -1
  226. package/ccw/dist/core/routes/issue-routes.js +24 -0
  227. package/ccw/dist/core/routes/issue-routes.js.map +1 -1
  228. package/ccw/dist/core/routes/litellm-api-routes.d.ts +1 -14
  229. package/ccw/dist/core/routes/litellm-api-routes.d.ts.map +1 -1
  230. package/ccw/dist/core/routes/litellm-api-routes.js +505 -48
  231. package/ccw/dist/core/routes/litellm-api-routes.js.map +1 -1
  232. package/ccw/dist/core/routes/litellm-routes.d.ts +1 -14
  233. package/ccw/dist/core/routes/litellm-routes.d.ts.map +1 -1
  234. package/ccw/dist/core/routes/litellm-routes.js +28 -11
  235. package/ccw/dist/core/routes/litellm-routes.js.map +1 -1
  236. package/ccw/dist/core/routes/mcp-routes.d.ts +1 -14
  237. package/ccw/dist/core/routes/mcp-routes.d.ts.map +1 -1
  238. package/ccw/dist/core/routes/mcp-routes.js +99 -30
  239. package/ccw/dist/core/routes/mcp-routes.js.map +1 -1
  240. package/ccw/dist/core/routes/mcp-templates-db.d.ts.map +1 -1
  241. package/ccw/dist/core/routes/mcp-templates-db.js +30 -31
  242. package/ccw/dist/core/routes/mcp-templates-db.js.map +1 -1
  243. package/ccw/dist/core/routes/memory-routes.d.ts.map +1 -1
  244. package/ccw/dist/core/routes/memory-routes.js +74 -24
  245. package/ccw/dist/core/routes/memory-routes.js.map +1 -1
  246. package/ccw/dist/core/routes/nav-status-routes.d.ts +3 -0
  247. package/ccw/dist/core/routes/nav-status-routes.d.ts.map +1 -0
  248. package/ccw/dist/core/routes/nav-status-routes.js +217 -0
  249. package/ccw/dist/core/routes/nav-status-routes.js.map +1 -0
  250. package/ccw/dist/core/routes/rules-routes.d.ts +1 -14
  251. package/ccw/dist/core/routes/rules-routes.d.ts.map +1 -1
  252. package/ccw/dist/core/routes/rules-routes.js +481 -58
  253. package/ccw/dist/core/routes/rules-routes.js.map +1 -1
  254. package/ccw/dist/core/routes/session-routes.d.ts +1 -14
  255. package/ccw/dist/core/routes/session-routes.d.ts.map +1 -1
  256. package/ccw/dist/core/routes/session-routes.js +15 -3
  257. package/ccw/dist/core/routes/session-routes.js.map +1 -1
  258. package/ccw/dist/core/routes/skills-routes.d.ts +1 -14
  259. package/ccw/dist/core/routes/skills-routes.d.ts.map +1 -1
  260. package/ccw/dist/core/routes/skills-routes.js +394 -112
  261. package/ccw/dist/core/routes/skills-routes.js.map +1 -1
  262. package/ccw/dist/core/routes/status-routes.d.ts +1 -14
  263. package/ccw/dist/core/routes/status-routes.d.ts.map +1 -1
  264. package/ccw/dist/core/routes/status-routes.js +4 -0
  265. package/ccw/dist/core/routes/status-routes.js.map +1 -1
  266. package/ccw/dist/core/routes/system-routes.d.ts +4 -10
  267. package/ccw/dist/core/routes/system-routes.d.ts.map +1 -1
  268. package/ccw/dist/core/routes/system-routes.js +6 -4
  269. package/ccw/dist/core/routes/system-routes.js.map +1 -1
  270. package/ccw/dist/core/routes/types.d.ts +19 -0
  271. package/ccw/dist/core/routes/types.d.ts.map +1 -0
  272. package/ccw/dist/core/routes/types.js +2 -0
  273. package/ccw/dist/core/routes/types.js.map +1 -0
  274. package/ccw/dist/core/server.d.ts.map +1 -1
  275. package/ccw/dist/core/server.js +201 -29
  276. package/ccw/dist/core/server.js.map +1 -1
  277. package/ccw/dist/core/services/api-key-tester.d.ts +31 -0
  278. package/ccw/dist/core/services/api-key-tester.d.ts.map +1 -0
  279. package/ccw/dist/core/services/api-key-tester.js +106 -0
  280. package/ccw/dist/core/services/api-key-tester.js.map +1 -0
  281. package/ccw/dist/core/services/health-check-service.d.ts +82 -0
  282. package/ccw/dist/core/services/health-check-service.d.ts.map +1 -0
  283. package/ccw/dist/core/services/health-check-service.js +271 -0
  284. package/ccw/dist/core/services/health-check-service.js.map +1 -0
  285. package/ccw/dist/core/websocket.d.ts +9 -7
  286. package/ccw/dist/core/websocket.d.ts.map +1 -1
  287. package/ccw/dist/core/websocket.js +9 -4
  288. package/ccw/dist/core/websocket.js.map +1 -1
  289. package/ccw/dist/tools/claude-cli-tools.d.ts +152 -28
  290. package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -1
  291. package/ccw/dist/tools/claude-cli-tools.js +490 -100
  292. package/ccw/dist/tools/claude-cli-tools.js.map +1 -1
  293. package/ccw/dist/tools/cli-config-manager.d.ts +24 -8
  294. package/ccw/dist/tools/cli-config-manager.d.ts.map +1 -1
  295. package/ccw/dist/tools/cli-config-manager.js +76 -156
  296. package/ccw/dist/tools/cli-config-manager.js.map +1 -1
  297. package/ccw/dist/tools/cli-executor-core.d.ts +85 -0
  298. package/ccw/dist/tools/cli-executor-core.d.ts.map +1 -0
  299. package/ccw/dist/tools/cli-executor-core.js +1310 -0
  300. package/ccw/dist/tools/cli-executor-core.js.map +1 -0
  301. package/ccw/dist/tools/cli-executor-state.d.ts +241 -0
  302. package/ccw/dist/tools/cli-executor-state.d.ts.map +1 -0
  303. package/ccw/dist/tools/cli-executor-state.js +392 -0
  304. package/ccw/dist/tools/cli-executor-state.js.map +1 -0
  305. package/ccw/dist/tools/cli-executor-utils.d.ts +36 -0
  306. package/ccw/dist/tools/cli-executor-utils.d.ts.map +1 -0
  307. package/ccw/dist/tools/cli-executor-utils.js +298 -0
  308. package/ccw/dist/tools/cli-executor-utils.js.map +1 -0
  309. package/ccw/dist/tools/cli-executor.d.ts +3 -377
  310. package/ccw/dist/tools/cli-executor.d.ts.map +1 -1
  311. package/ccw/dist/tools/cli-executor.js +3 -1884
  312. package/ccw/dist/tools/cli-executor.js.map +1 -1
  313. package/ccw/dist/tools/cli-history-store.d.ts +2 -0
  314. package/ccw/dist/tools/cli-history-store.d.ts.map +1 -1
  315. package/ccw/dist/tools/cli-history-store.js.map +1 -1
  316. package/ccw/dist/tools/cli-output-converter.d.ts +192 -0
  317. package/ccw/dist/tools/cli-output-converter.d.ts.map +1 -0
  318. package/ccw/dist/tools/cli-output-converter.js +1047 -0
  319. package/ccw/dist/tools/cli-output-converter.js.map +1 -0
  320. package/ccw/dist/tools/cli-prompt-builder.d.ts +113 -0
  321. package/ccw/dist/tools/cli-prompt-builder.d.ts.map +1 -0
  322. package/ccw/dist/tools/cli-prompt-builder.js +363 -0
  323. package/ccw/dist/tools/cli-prompt-builder.js.map +1 -0
  324. package/ccw/dist/tools/codex-lens.d.ts +15 -1
  325. package/ccw/dist/tools/codex-lens.d.ts.map +1 -1
  326. package/ccw/dist/tools/codex-lens.js +289 -55
  327. package/ccw/dist/tools/codex-lens.js.map +1 -1
  328. package/ccw/dist/tools/detect-changed-modules.d.ts.map +1 -1
  329. package/ccw/dist/tools/detect-changed-modules.js +22 -4
  330. package/ccw/dist/tools/detect-changed-modules.js.map +1 -1
  331. package/ccw/dist/tools/index.d.ts.map +1 -1
  332. package/ccw/dist/tools/index.js +2 -0
  333. package/ccw/dist/tools/index.js.map +1 -1
  334. package/ccw/dist/tools/litellm-client.d.ts.map +1 -1
  335. package/ccw/dist/tools/litellm-client.js +10 -4
  336. package/ccw/dist/tools/litellm-client.js.map +1 -1
  337. package/ccw/dist/tools/litellm-executor.d.ts +2 -4
  338. package/ccw/dist/tools/litellm-executor.d.ts.map +1 -1
  339. package/ccw/dist/tools/litellm-executor.js +39 -8
  340. package/ccw/dist/tools/litellm-executor.js.map +1 -1
  341. package/ccw/dist/tools/native-session-discovery.d.ts +2 -0
  342. package/ccw/dist/tools/native-session-discovery.d.ts.map +1 -1
  343. package/ccw/dist/tools/native-session-discovery.js +197 -1
  344. package/ccw/dist/tools/native-session-discovery.js.map +1 -1
  345. package/ccw/dist/tools/session-manager.d.ts.map +1 -1
  346. package/ccw/dist/tools/session-manager.js +79 -0
  347. package/ccw/dist/tools/session-manager.js.map +1 -1
  348. package/ccw/dist/tools/skill-context-loader.d.ts +15 -0
  349. package/ccw/dist/tools/skill-context-loader.d.ts.map +1 -0
  350. package/ccw/dist/tools/skill-context-loader.js +198 -0
  351. package/ccw/dist/tools/skill-context-loader.js.map +1 -0
  352. package/ccw/dist/tools/smart-search.d.ts +8 -3
  353. package/ccw/dist/tools/smart-search.d.ts.map +1 -1
  354. package/ccw/dist/tools/smart-search.js +378 -75
  355. package/ccw/dist/tools/smart-search.js.map +1 -1
  356. package/ccw/dist/types/cli-settings.d.ts +86 -0
  357. package/ccw/dist/types/cli-settings.d.ts.map +1 -0
  358. package/ccw/dist/types/cli-settings.js +54 -0
  359. package/ccw/dist/types/cli-settings.js.map +1 -0
  360. package/ccw/dist/types/litellm-api-config.d.ts +40 -1
  361. package/ccw/dist/types/litellm-api-config.d.ts.map +1 -1
  362. package/ccw/dist/utils/exec-constants.d.ts +25 -0
  363. package/ccw/dist/utils/exec-constants.d.ts.map +1 -0
  364. package/ccw/dist/utils/exec-constants.js +25 -0
  365. package/ccw/dist/utils/exec-constants.js.map +1 -0
  366. package/ccw/dist/utils/path-resolver.d.ts +1 -0
  367. package/ccw/dist/utils/path-resolver.d.ts.map +1 -1
  368. package/ccw/dist/utils/path-resolver.js +48 -3
  369. package/ccw/dist/utils/path-resolver.js.map +1 -1
  370. package/ccw/dist/utils/path-validator.d.ts.map +1 -1
  371. package/ccw/dist/utils/path-validator.js +25 -6
  372. package/ccw/dist/utils/path-validator.js.map +1 -1
  373. package/ccw/dist/utils/python-utils.d.ts.map +1 -1
  374. package/ccw/dist/utils/python-utils.js +27 -7
  375. package/ccw/dist/utils/python-utils.js.map +1 -1
  376. package/ccw/dist/utils/shell-escape.d.ts +8 -0
  377. package/ccw/dist/utils/shell-escape.d.ts.map +1 -0
  378. package/ccw/dist/utils/shell-escape.js +24 -0
  379. package/ccw/dist/utils/shell-escape.js.map +1 -0
  380. package/ccw/dist/utils/uv-manager.d.ts +167 -0
  381. package/ccw/dist/utils/uv-manager.d.ts.map +1 -0
  382. package/ccw/dist/utils/uv-manager.js +644 -0
  383. package/ccw/dist/utils/uv-manager.js.map +1 -0
  384. package/ccw/src/cli.ts +4 -1
  385. package/ccw/src/commands/cli.ts +132 -34
  386. package/ccw/src/commands/issue.ts +605 -91
  387. package/ccw/src/commands/serve.ts +15 -5
  388. package/ccw/src/commands/stop.ts +32 -5
  389. package/ccw/src/commands/tool.ts +17 -2
  390. package/ccw/src/commands/view.ts +13 -3
  391. package/ccw/src/config/cli-settings-manager.ts +460 -0
  392. package/ccw/src/config/litellm-api-config-manager.ts +392 -57
  393. package/ccw/src/core/auth/csrf-manager.ts +104 -0
  394. package/ccw/src/core/auth/csrf-middleware.ts +159 -0
  395. package/ccw/src/core/auth/middleware.ts +94 -0
  396. package/ccw/src/core/auth/token-manager.ts +219 -0
  397. package/ccw/src/core/cache-manager.ts +64 -52
  398. package/ccw/src/core/claude-freshness.ts +26 -6
  399. package/ccw/src/core/core-memory-store.ts +2 -1
  400. package/ccw/src/core/cors.ts +10 -0
  401. package/ccw/src/core/dashboard-generator-patch.ts +47 -48
  402. package/ccw/src/core/dashboard-generator.ts +797 -744
  403. package/ccw/src/core/data-aggregator.ts +667 -667
  404. package/ccw/src/core/lite-scanner.ts +156 -140
  405. package/ccw/src/core/routes/auth-routes.ts +98 -0
  406. package/ccw/src/core/routes/ccw-routes.ts +10 -20
  407. package/ccw/src/core/routes/claude-routes.ts +101 -51
  408. package/ccw/src/core/routes/cli-routes.ts +152 -55
  409. package/ccw/src/core/routes/cli-settings-routes.ts +232 -0
  410. package/ccw/src/core/routes/codexlens/README.md +37 -0
  411. package/ccw/src/core/routes/codexlens/config-handlers.ts +1269 -0
  412. package/ccw/src/core/routes/codexlens/index-handlers.ts +354 -0
  413. package/ccw/src/core/routes/codexlens/semantic-handlers.ts +931 -0
  414. package/ccw/src/core/routes/codexlens/utils.ts +96 -0
  415. package/ccw/src/core/routes/codexlens/watcher-handlers.ts +265 -0
  416. package/ccw/src/core/routes/codexlens-routes.ts +11 -1044
  417. package/ccw/src/core/routes/discovery-routes.ts +1 -12
  418. package/ccw/src/core/routes/files-routes.ts +112 -40
  419. package/ccw/src/core/routes/graph-routes.ts +39 -46
  420. package/ccw/src/core/routes/help-routes.ts +2 -12
  421. package/ccw/src/core/routes/hooks-routes.ts +83 -44
  422. package/ccw/src/core/routes/issue-routes.ts +1 -12
  423. package/ccw/src/core/routes/litellm-api-routes.ts +566 -60
  424. package/ccw/src/core/routes/litellm-routes.ts +35 -27
  425. package/ccw/src/core/routes/mcp-routes.ts +157 -60
  426. package/ccw/src/core/routes/mcp-routes.ts.backup +549 -550
  427. package/ccw/src/core/routes/mcp-templates-db.ts +267 -268
  428. package/ccw/src/core/routes/memory-routes.ts +76 -22
  429. package/ccw/src/core/routes/nav-status-routes.ts +231 -0
  430. package/ccw/src/core/routes/rules-routes.ts +600 -81
  431. package/ccw/src/core/routes/session-routes.ts +28 -22
  432. package/ccw/src/core/routes/skills-routes.ts +452 -132
  433. package/ccw/src/core/routes/status-routes.ts +1 -12
  434. package/ccw/src/core/routes/system-routes.ts +15 -22
  435. package/ccw/src/core/routes/types.ts +25 -0
  436. package/ccw/src/core/server.ts +651 -468
  437. package/ccw/src/core/services/api-key-tester.ts +137 -0
  438. package/ccw/src/core/services/health-check-service.ts +340 -0
  439. package/ccw/src/core/websocket.ts +20 -12
  440. package/ccw/src/templates/dashboard-css/01-base.css +109 -0
  441. package/ccw/src/templates/dashboard-css/10-cli-status.css +202 -0
  442. package/ccw/src/templates/dashboard-css/21-cli-toolmgmt.css +308 -0
  443. package/ccw/src/templates/dashboard-css/30-core-memory.css +20 -0
  444. package/ccw/src/templates/dashboard-css/31-api-settings.css +751 -14
  445. package/ccw/src/templates/dashboard-css/33-cli-stream-viewer.css +230 -2
  446. package/ccw/src/templates/dashboard-js/api.js +5 -0
  447. package/ccw/src/templates/dashboard-js/components/cli-status.js +279 -107
  448. package/ccw/src/templates/dashboard-js/components/cli-stream-viewer.js +262 -20
  449. package/ccw/src/templates/dashboard-js/components/hook-manager.js +105 -5
  450. package/ccw/src/templates/dashboard-js/components/mcp-manager.js +317 -0
  451. package/ccw/src/templates/dashboard-js/components/navigation.js +45 -0
  452. package/ccw/src/templates/dashboard-js/components/notifications.js +128 -0
  453. package/ccw/src/templates/dashboard-js/i18n.js +4438 -3983
  454. package/ccw/src/templates/dashboard-js/main.js +71 -0
  455. package/ccw/src/templates/dashboard-js/services.js +289 -0
  456. package/ccw/src/templates/dashboard-js/views/api-settings.js +5613 -3361
  457. package/ccw/src/templates/dashboard-js/views/claude-manager.js +1 -7
  458. package/ccw/src/templates/dashboard-js/views/cli-manager.js +581 -87
  459. package/ccw/src/templates/dashboard-js/views/codexlens-manager.js +6091 -1965
  460. package/ccw/src/templates/dashboard-js/views/core-memory.js +129 -20
  461. package/ccw/src/templates/dashboard-js/views/hook-manager.js +17 -3
  462. package/ccw/src/templates/dashboard-js/views/mcp-manager.js +63 -0
  463. package/ccw/src/templates/dashboard-js/views/project-overview.js +182 -37
  464. package/ccw/src/templates/dashboard-js/views/rules-manager.js +26 -3
  465. package/ccw/src/templates/dashboard-js/views/skills-manager.js +2 -42
  466. package/ccw/src/templates/dashboard.html +6 -0
  467. package/ccw/src/tools/README.md +29 -0
  468. package/ccw/src/tools/claude-cli-tools.ts +640 -125
  469. package/ccw/src/tools/cli-config-manager.ts +102 -172
  470. package/ccw/src/tools/cli-executor-core.ts +1533 -0
  471. package/ccw/src/tools/cli-executor-state.ts +560 -0
  472. package/ccw/src/tools/cli-executor-utils.ts +349 -0
  473. package/ccw/src/tools/cli-executor.ts +3 -2309
  474. package/ccw/src/tools/cli-history-store.ts +2 -0
  475. package/ccw/src/tools/cli-output-converter.ts +1237 -0
  476. package/ccw/src/tools/cli-prompt-builder.ts +487 -0
  477. package/ccw/src/tools/codex-lens.ts +324 -59
  478. package/ccw/src/tools/detect-changed-modules.ts +24 -6
  479. package/ccw/src/tools/index.ts +2 -0
  480. package/ccw/src/tools/litellm-client.ts +10 -4
  481. package/ccw/src/tools/litellm-executor.ts +146 -114
  482. package/ccw/src/tools/native-session-discovery.ts +209 -1
  483. package/ccw/src/tools/session-manager.ts +88 -0
  484. package/ccw/src/tools/skill-context-loader.ts +213 -0
  485. package/ccw/src/tools/smart-search.ts +427 -76
  486. package/ccw/src/types/cli-settings.ts +137 -0
  487. package/ccw/src/types/litellm-api-config.ts +55 -1
  488. package/ccw/src/utils/exec-constants.ts +24 -0
  489. package/ccw/src/utils/path-resolver.ts +49 -3
  490. package/ccw/src/utils/path-validator.ts +28 -6
  491. package/ccw/src/utils/python-utils.ts +140 -121
  492. package/ccw/src/utils/shell-escape.ts +30 -0
  493. package/ccw/src/utils/uv-manager.ts +796 -0
  494. package/ccw-litellm/src/ccw_litellm/__pycache__/__init__.cpython-310.pyc +0 -0
  495. package/ccw-litellm/src/ccw_litellm/__pycache__/__init__.cpython-312.pyc +0 -0
  496. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/__init__.cpython-310.pyc +0 -0
  497. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/__init__.cpython-312.pyc +0 -0
  498. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_embedder.cpython-310.pyc +0 -0
  499. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_embedder.cpython-312.pyc +0 -0
  500. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_embedder.cpython-313.pyc +0 -0
  501. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_llm.cpython-310.pyc +0 -0
  502. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_llm.cpython-312.pyc +0 -0
  503. package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_llm.cpython-313.pyc +0 -0
  504. package/ccw-litellm/src/ccw_litellm/clients/litellm_embedder.py +270 -251
  505. package/ccw-litellm/src/ccw_litellm/clients/litellm_llm.py +33 -0
  506. package/ccw-litellm/src/ccw_litellm/config/__pycache__/__init__.cpython-310.pyc +0 -0
  507. package/ccw-litellm/src/ccw_litellm/config/__pycache__/__init__.cpython-312.pyc +0 -0
  508. package/ccw-litellm/src/ccw_litellm/config/__pycache__/loader.cpython-310.pyc +0 -0
  509. package/ccw-litellm/src/ccw_litellm/config/__pycache__/loader.cpython-312.pyc +0 -0
  510. package/ccw-litellm/src/ccw_litellm/config/__pycache__/loader.cpython-313.pyc +0 -0
  511. package/ccw-litellm/src/ccw_litellm/config/__pycache__/models.cpython-310.pyc +0 -0
  512. package/ccw-litellm/src/ccw_litellm/config/__pycache__/models.cpython-312.pyc +0 -0
  513. package/ccw-litellm/src/ccw_litellm/config/__pycache__/models.cpython-313.pyc +0 -0
  514. package/ccw-litellm/src/ccw_litellm/config/loader.py +343 -316
  515. package/ccw-litellm/src/ccw_litellm/config/models.py +162 -130
  516. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/__init__.cpython-310.pyc +0 -0
  517. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/__init__.cpython-312.pyc +0 -0
  518. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/embedder.cpython-310.pyc +0 -0
  519. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/embedder.cpython-312.pyc +0 -0
  520. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/llm.cpython-310.pyc +0 -0
  521. package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/llm.cpython-312.pyc +0 -0
  522. package/codex-lens/pyproject.toml +43 -0
  523. package/codex-lens/src/codexlens/__pycache__/__init__.cpython-310.pyc +0 -0
  524. package/codex-lens/src/codexlens/__pycache__/__init__.cpython-312.pyc +0 -0
  525. package/codex-lens/src/codexlens/__pycache__/__main__.cpython-310.pyc +0 -0
  526. package/codex-lens/src/codexlens/__pycache__/__main__.cpython-312.pyc +0 -0
  527. package/codex-lens/src/codexlens/__pycache__/config.cpython-310.pyc +0 -0
  528. package/codex-lens/src/codexlens/__pycache__/config.cpython-312.pyc +0 -0
  529. package/codex-lens/src/codexlens/__pycache__/config.cpython-313.pyc +0 -0
  530. package/codex-lens/src/codexlens/__pycache__/entities.cpython-310.pyc +0 -0
  531. package/codex-lens/src/codexlens/__pycache__/entities.cpython-312.pyc +0 -0
  532. package/codex-lens/src/codexlens/__pycache__/entities.cpython-313.pyc +0 -0
  533. package/codex-lens/src/codexlens/__pycache__/env_config.cpython-310.pyc +0 -0
  534. package/codex-lens/src/codexlens/__pycache__/env_config.cpython-312.pyc +0 -0
  535. package/codex-lens/src/codexlens/__pycache__/env_config.cpython-313.pyc +0 -0
  536. package/codex-lens/src/codexlens/__pycache__/errors.cpython-310.pyc +0 -0
  537. package/codex-lens/src/codexlens/__pycache__/errors.cpython-312.pyc +0 -0
  538. package/codex-lens/src/codexlens/cli/__pycache__/__init__.cpython-310.pyc +0 -0
  539. package/codex-lens/src/codexlens/cli/__pycache__/__init__.cpython-312.pyc +0 -0
  540. package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-310.pyc +0 -0
  541. package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-312.pyc +0 -0
  542. package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-313.pyc +0 -0
  543. package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-310.pyc +0 -0
  544. package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-312.pyc +0 -0
  545. package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-313.pyc +0 -0
  546. package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-310.pyc +0 -0
  547. package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-312.pyc +0 -0
  548. package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-313.pyc +0 -0
  549. package/codex-lens/src/codexlens/cli/__pycache__/output.cpython-310.pyc +0 -0
  550. package/codex-lens/src/codexlens/cli/__pycache__/output.cpython-312.pyc +0 -0
  551. package/codex-lens/src/codexlens/cli/commands.py +4416 -2295
  552. package/codex-lens/src/codexlens/cli/embedding_manager.py +767 -14
  553. package/codex-lens/src/codexlens/cli/model_manager.py +676 -0
  554. package/codex-lens/src/codexlens/config.py +321 -12
  555. package/codex-lens/src/codexlens/entities.py +4 -1
  556. package/codex-lens/src/codexlens/env_config.py +298 -0
  557. package/codex-lens/src/codexlens/indexing/__init__.py +23 -1
  558. package/codex-lens/src/codexlens/indexing/__pycache__/__init__.cpython-313.pyc +0 -0
  559. package/codex-lens/src/codexlens/indexing/__pycache__/embedding.cpython-313.pyc +0 -0
  560. package/codex-lens/src/codexlens/indexing/__pycache__/symbol_extractor.cpython-313.pyc +0 -0
  561. package/codex-lens/src/codexlens/indexing/embedding.py +582 -0
  562. package/codex-lens/src/codexlens/indexing/symbol_extractor.py +62 -28
  563. package/codex-lens/src/codexlens/parsers/__pycache__/__init__.cpython-310.pyc +0 -0
  564. package/codex-lens/src/codexlens/parsers/__pycache__/__init__.cpython-312.pyc +0 -0
  565. package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-310.pyc +0 -0
  566. package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-312.pyc +0 -0
  567. package/codex-lens/src/codexlens/parsers/__pycache__/factory.cpython-313.pyc +0 -0
  568. package/codex-lens/src/codexlens/parsers/__pycache__/tokenizer.cpython-310.pyc +0 -0
  569. package/codex-lens/src/codexlens/parsers/__pycache__/tokenizer.cpython-312.pyc +0 -0
  570. package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-310.pyc +0 -0
  571. package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-312.pyc +0 -0
  572. package/codex-lens/src/codexlens/parsers/__pycache__/treesitter_parser.cpython-313.pyc +0 -0
  573. package/codex-lens/src/codexlens/parsers/factory.py +139 -10
  574. package/codex-lens/src/codexlens/parsers/treesitter_parser.py +487 -13
  575. package/codex-lens/src/codexlens/search/__pycache__/__init__.cpython-310.pyc +0 -0
  576. package/codex-lens/src/codexlens/search/__pycache__/__init__.cpython-312.pyc +0 -0
  577. package/codex-lens/src/codexlens/search/__pycache__/binary_searcher.cpython-313.pyc +0 -0
  578. package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-310.pyc +0 -0
  579. package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-312.pyc +0 -0
  580. package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-313.pyc +0 -0
  581. package/codex-lens/src/codexlens/search/__pycache__/enrichment.cpython-313.pyc +0 -0
  582. package/codex-lens/src/codexlens/search/__pycache__/graph_expander.cpython-313.pyc +0 -0
  583. package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-310.pyc +0 -0
  584. package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-312.pyc +0 -0
  585. package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-313.pyc +0 -0
  586. package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-310.pyc +0 -0
  587. package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-312.pyc +0 -0
  588. package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-313.pyc +0 -0
  589. package/codex-lens/src/codexlens/search/binary_searcher.py +277 -0
  590. package/codex-lens/src/codexlens/search/chain_search.py +1642 -8
  591. package/codex-lens/src/codexlens/search/enrichment.py +21 -0
  592. package/codex-lens/src/codexlens/search/graph_expander.py +264 -0
  593. package/codex-lens/src/codexlens/search/hybrid_search.py +772 -37
  594. package/codex-lens/src/codexlens/search/ranking.py +347 -8
  595. package/codex-lens/src/codexlens/semantic/SPLADE_IMPLEMENTATION.md +225 -0
  596. package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-310.pyc +0 -0
  597. package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-312.pyc +0 -0
  598. package/codex-lens/src/codexlens/semantic/__pycache__/ann_index.cpython-310.pyc +0 -0
  599. package/codex-lens/src/codexlens/semantic/__pycache__/ann_index.cpython-312.pyc +0 -0
  600. package/codex-lens/src/codexlens/semantic/__pycache__/ann_index.cpython-313.pyc +0 -0
  601. package/codex-lens/src/codexlens/semantic/__pycache__/base.cpython-310.pyc +0 -0
  602. package/codex-lens/src/codexlens/semantic/__pycache__/base.cpython-312.pyc +0 -0
  603. package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-310.pyc +0 -0
  604. package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-312.pyc +0 -0
  605. package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-310.pyc +0 -0
  606. package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-312.pyc +0 -0
  607. package/codex-lens/src/codexlens/semantic/__pycache__/factory.cpython-310.pyc +0 -0
  608. package/codex-lens/src/codexlens/semantic/__pycache__/factory.cpython-312.pyc +0 -0
  609. package/codex-lens/src/codexlens/semantic/__pycache__/factory.cpython-313.pyc +0 -0
  610. package/codex-lens/src/codexlens/semantic/__pycache__/gpu_support.cpython-310.pyc +0 -0
  611. package/codex-lens/src/codexlens/semantic/__pycache__/gpu_support.cpython-312.pyc +0 -0
  612. package/codex-lens/src/codexlens/semantic/__pycache__/gpu_support.cpython-313.pyc +0 -0
  613. package/codex-lens/src/codexlens/semantic/__pycache__/litellm_embedder.cpython-310.pyc +0 -0
  614. package/codex-lens/src/codexlens/semantic/__pycache__/litellm_embedder.cpython-312.pyc +0 -0
  615. package/codex-lens/src/codexlens/semantic/__pycache__/litellm_embedder.cpython-313.pyc +0 -0
  616. package/codex-lens/src/codexlens/semantic/__pycache__/reranker.cpython-313.pyc +0 -0
  617. package/codex-lens/src/codexlens/semantic/__pycache__/splade_encoder.cpython-310.pyc +0 -0
  618. package/codex-lens/src/codexlens/semantic/__pycache__/splade_encoder.cpython-312.pyc +0 -0
  619. package/codex-lens/src/codexlens/semantic/__pycache__/splade_encoder.cpython-313.pyc +0 -0
  620. package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-310.pyc +0 -0
  621. package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-312.pyc +0 -0
  622. package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-313.pyc +0 -0
  623. package/codex-lens/src/codexlens/semantic/ann_index.py +654 -0
  624. package/codex-lens/src/codexlens/semantic/factory.py +63 -3
  625. package/codex-lens/src/codexlens/semantic/gpu_support.py +19 -2
  626. package/codex-lens/src/codexlens/semantic/litellm_embedder.py +144 -144
  627. package/codex-lens/src/codexlens/semantic/reranker/__init__.py +25 -0
  628. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/__init__.cpython-310.pyc +0 -0
  629. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/__init__.cpython-313.pyc +0 -0
  630. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/api_reranker.cpython-310.pyc +0 -0
  631. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/api_reranker.cpython-313.pyc +0 -0
  632. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/base.cpython-310.pyc +0 -0
  633. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/base.cpython-313.pyc +0 -0
  634. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/factory.cpython-310.pyc +0 -0
  635. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/factory.cpython-313.pyc +0 -0
  636. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/fastembed_reranker.cpython-310.pyc +0 -0
  637. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/fastembed_reranker.cpython-313.pyc +0 -0
  638. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/legacy.cpython-310.pyc +0 -0
  639. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/legacy.cpython-313.pyc +0 -0
  640. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/litellm_reranker.cpython-313.pyc +0 -0
  641. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/onnx_reranker.cpython-310.pyc +0 -0
  642. package/codex-lens/src/codexlens/semantic/reranker/__pycache__/onnx_reranker.cpython-313.pyc +0 -0
  643. package/codex-lens/src/codexlens/semantic/reranker/api_reranker.py +403 -0
  644. package/codex-lens/src/codexlens/semantic/reranker/base.py +46 -0
  645. package/codex-lens/src/codexlens/semantic/reranker/factory.py +159 -0
  646. package/codex-lens/src/codexlens/semantic/reranker/fastembed_reranker.py +257 -0
  647. package/codex-lens/src/codexlens/semantic/reranker/legacy.py +91 -0
  648. package/codex-lens/src/codexlens/semantic/reranker/litellm_reranker.py +214 -0
  649. package/codex-lens/src/codexlens/semantic/reranker/onnx_reranker.py +268 -0
  650. package/codex-lens/src/codexlens/semantic/splade_encoder.py +567 -0
  651. package/codex-lens/src/codexlens/semantic/vector_store.py +472 -352
  652. package/codex-lens/src/codexlens/storage/__init__.py +3 -0
  653. package/codex-lens/src/codexlens/storage/__pycache__/__init__.cpython-310.pyc +0 -0
  654. package/codex-lens/src/codexlens/storage/__pycache__/__init__.cpython-312.pyc +0 -0
  655. package/codex-lens/src/codexlens/storage/__pycache__/__init__.cpython-313.pyc +0 -0
  656. package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-310.pyc +0 -0
  657. package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-312.pyc +0 -0
  658. package/codex-lens/src/codexlens/storage/__pycache__/dir_index.cpython-313.pyc +0 -0
  659. package/codex-lens/src/codexlens/storage/__pycache__/global_index.cpython-310.pyc +0 -0
  660. package/codex-lens/src/codexlens/storage/__pycache__/global_index.cpython-312.pyc +0 -0
  661. package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-310.pyc +0 -0
  662. package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-312.pyc +0 -0
  663. package/codex-lens/src/codexlens/storage/__pycache__/index_tree.cpython-313.pyc +0 -0
  664. package/codex-lens/src/codexlens/storage/__pycache__/merkle_tree.cpython-313.pyc +0 -0
  665. package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-310.pyc +0 -0
  666. package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-312.pyc +0 -0
  667. package/codex-lens/src/codexlens/storage/__pycache__/registry.cpython-310.pyc +0 -0
  668. package/codex-lens/src/codexlens/storage/__pycache__/registry.cpython-312.pyc +0 -0
  669. package/codex-lens/src/codexlens/storage/__pycache__/splade_index.cpython-310.pyc +0 -0
  670. package/codex-lens/src/codexlens/storage/__pycache__/splade_index.cpython-312.pyc +0 -0
  671. package/codex-lens/src/codexlens/storage/__pycache__/splade_index.cpython-313.pyc +0 -0
  672. package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-310.pyc +0 -0
  673. package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-312.pyc +0 -0
  674. package/codex-lens/src/codexlens/storage/__pycache__/sqlite_store.cpython-313.pyc +0 -0
  675. package/codex-lens/src/codexlens/storage/__pycache__/sqlite_utils.cpython-310.pyc +0 -0
  676. package/codex-lens/src/codexlens/storage/__pycache__/sqlite_utils.cpython-312.pyc +0 -0
  677. package/codex-lens/src/codexlens/storage/__pycache__/vector_meta_store.cpython-310.pyc +0 -0
  678. package/codex-lens/src/codexlens/storage/__pycache__/vector_meta_store.cpython-312.pyc +0 -0
  679. package/codex-lens/src/codexlens/storage/__pycache__/vector_meta_store.cpython-313.pyc +0 -0
  680. package/codex-lens/src/codexlens/storage/dir_index.py +310 -12
  681. package/codex-lens/src/codexlens/storage/index_tree.py +194 -23
  682. package/codex-lens/src/codexlens/storage/merkle_tree.py +136 -0
  683. package/codex-lens/src/codexlens/storage/migrations/__pycache__/__init__.cpython-310.pyc +0 -0
  684. package/codex-lens/src/codexlens/storage/migrations/__pycache__/__init__.cpython-312.pyc +0 -0
  685. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_006_enhance_relationships.cpython-313.pyc +0 -0
  686. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_007_add_graph_neighbors.cpython-310.pyc +0 -0
  687. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_007_add_graph_neighbors.cpython-312.pyc +0 -0
  688. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_007_add_graph_neighbors.cpython-313.pyc +0 -0
  689. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_008_add_merkle_hashes.cpython-313.pyc +0 -0
  690. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_009_add_splade.cpython-313.pyc +0 -0
  691. package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_010_add_multi_vector_chunks.cpython-313.pyc +0 -0
  692. package/codex-lens/src/codexlens/storage/migrations/migration_006_enhance_relationships.py +37 -0
  693. package/codex-lens/src/codexlens/storage/migrations/migration_007_add_graph_neighbors.py +47 -0
  694. package/codex-lens/src/codexlens/storage/migrations/migration_008_add_merkle_hashes.py +81 -0
  695. package/codex-lens/src/codexlens/storage/migrations/migration_009_add_splade.py +103 -0
  696. package/codex-lens/src/codexlens/storage/migrations/migration_010_add_multi_vector_chunks.py +162 -0
  697. package/codex-lens/src/codexlens/storage/splade_index.py +578 -0
  698. package/codex-lens/src/codexlens/storage/sqlite_store.py +508 -184
  699. package/codex-lens/src/codexlens/storage/vector_meta_store.py +415 -0
  700. package/codex-lens/src/codexlens/watcher/__init__.py +17 -0
  701. package/codex-lens/src/codexlens/watcher/__pycache__/__init__.cpython-310.pyc +0 -0
  702. package/codex-lens/src/codexlens/watcher/__pycache__/__init__.cpython-312.pyc +0 -0
  703. package/codex-lens/src/codexlens/watcher/__pycache__/__init__.cpython-313.pyc +0 -0
  704. package/codex-lens/src/codexlens/watcher/__pycache__/events.cpython-310.pyc +0 -0
  705. package/codex-lens/src/codexlens/watcher/__pycache__/events.cpython-312.pyc +0 -0
  706. package/codex-lens/src/codexlens/watcher/__pycache__/events.cpython-313.pyc +0 -0
  707. package/codex-lens/src/codexlens/watcher/__pycache__/file_watcher.cpython-310.pyc +0 -0
  708. package/codex-lens/src/codexlens/watcher/__pycache__/file_watcher.cpython-312.pyc +0 -0
  709. package/codex-lens/src/codexlens/watcher/__pycache__/file_watcher.cpython-313.pyc +0 -0
  710. package/codex-lens/src/codexlens/watcher/__pycache__/incremental_indexer.cpython-310.pyc +0 -0
  711. package/codex-lens/src/codexlens/watcher/__pycache__/incremental_indexer.cpython-312.pyc +0 -0
  712. package/codex-lens/src/codexlens/watcher/__pycache__/incremental_indexer.cpython-313.pyc +0 -0
  713. package/codex-lens/src/codexlens/watcher/__pycache__/manager.cpython-310.pyc +0 -0
  714. package/codex-lens/src/codexlens/watcher/__pycache__/manager.cpython-312.pyc +0 -0
  715. package/codex-lens/src/codexlens/watcher/__pycache__/manager.cpython-313.pyc +0 -0
  716. package/codex-lens/src/codexlens/watcher/events.py +82 -0
  717. package/codex-lens/src/codexlens/watcher/file_watcher.py +347 -0
  718. package/codex-lens/src/codexlens/watcher/incremental_indexer.py +369 -0
  719. package/codex-lens/src/codexlens/watcher/manager.py +255 -0
  720. package/package.json +4 -1
  721. package/.claude/commands/workflow/docs/analyze.md +0 -1467
  722. package/.claude/commands/workflow/docs/copyright.md +0 -1265
  723. package/.claude/skills/command-guide/SKILL.md +0 -388
  724. package/.claude/skills/command-guide/UPDATE-GUIDELINE.md +0 -592
  725. package/.claude/skills/command-guide/guides/cli-tools-guide.md +0 -410
  726. package/.claude/skills/command-guide/guides/examples.md +0 -537
  727. package/.claude/skills/command-guide/guides/getting-started.md +0 -242
  728. package/.claude/skills/command-guide/guides/implementation-details.md +0 -1010
  729. package/.claude/skills/command-guide/guides/index-structure.md +0 -326
  730. package/.claude/skills/command-guide/guides/troubleshooting.md +0 -92
  731. package/.claude/skills/command-guide/guides/ui-design-workflow-guide.md +0 -316
  732. package/.claude/skills/command-guide/guides/workflow-patterns.md +0 -662
  733. package/.claude/skills/command-guide/reference/agents/action-planning-agent.md +0 -855
  734. package/.claude/skills/command-guide/reference/agents/cli-execution-agent.md +0 -267
  735. package/.claude/skills/command-guide/reference/agents/cli-explore-agent.md +0 -182
  736. package/.claude/skills/command-guide/reference/agents/cli-lite-planning-agent.md +0 -446
  737. package/.claude/skills/command-guide/reference/agents/cli-planning-agent.md +0 -558
  738. package/.claude/skills/command-guide/reference/agents/code-developer.md +0 -311
  739. package/.claude/skills/command-guide/reference/agents/conceptual-planning-agent.md +0 -308
  740. package/.claude/skills/command-guide/reference/agents/context-search-agent.md +0 -581
  741. package/.claude/skills/command-guide/reference/agents/doc-generator.md +0 -330
  742. package/.claude/skills/command-guide/reference/agents/memory-bridge.md +0 -94
  743. package/.claude/skills/command-guide/reference/agents/test-context-search-agent.md +0 -400
  744. package/.claude/skills/command-guide/reference/agents/test-fix-agent.md +0 -344
  745. package/.claude/skills/command-guide/reference/agents/ui-design-agent.md +0 -593
  746. package/.claude/skills/command-guide/reference/agents/universal-executor.md +0 -131
  747. package/.claude/skills/command-guide/reference/commands/cli/cli-init.md +0 -440
  748. package/.claude/skills/command-guide/reference/commands/enhance-prompt.md +0 -93
  749. package/.claude/skills/command-guide/reference/commands/memory/code-map-memory.md +0 -687
  750. package/.claude/skills/command-guide/reference/commands/memory/docs-full-cli.md +0 -471
  751. package/.claude/skills/command-guide/reference/commands/memory/docs-related-cli.md +0 -386
  752. package/.claude/skills/command-guide/reference/commands/memory/docs.md +0 -616
  753. package/.claude/skills/command-guide/reference/commands/memory/load-skill-memory.md +0 -182
  754. package/.claude/skills/command-guide/reference/commands/memory/load.md +0 -240
  755. package/.claude/skills/command-guide/reference/commands/memory/skill-memory.md +0 -525
  756. package/.claude/skills/command-guide/reference/commands/memory/style-skill-memory.md +0 -396
  757. package/.claude/skills/command-guide/reference/commands/memory/tech-research.md +0 -314
  758. package/.claude/skills/command-guide/reference/commands/memory/update-full.md +0 -332
  759. package/.claude/skills/command-guide/reference/commands/memory/update-related.md +0 -332
  760. package/.claude/skills/command-guide/reference/commands/memory/workflow-skill-memory.md +0 -517
  761. package/.claude/skills/command-guide/reference/commands/task/breakdown.md +0 -204
  762. package/.claude/skills/command-guide/reference/commands/task/create.md +0 -152
  763. package/.claude/skills/command-guide/reference/commands/task/execute.md +0 -270
  764. package/.claude/skills/command-guide/reference/commands/task/replan.md +0 -437
  765. package/.claude/skills/command-guide/reference/commands/version.md +0 -254
  766. package/.claude/skills/command-guide/reference/commands/workflow/action-plan-verify.md +0 -447
  767. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/api-designer.md +0 -585
  768. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/artifacts.md +0 -452
  769. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/auto-parallel.md +0 -443
  770. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/data-architect.md +0 -220
  771. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-manager.md +0 -200
  772. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/product-owner.md +0 -200
  773. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/scrum-master.md +0 -200
  774. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/subject-matter-expert.md +0 -200
  775. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/synthesis.md +0 -398
  776. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/system-architect.md +0 -387
  777. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ui-designer.md +0 -221
  778. package/.claude/skills/command-guide/reference/commands/workflow/brainstorm/ux-expert.md +0 -221
  779. package/.claude/skills/command-guide/reference/commands/workflow/execute.md +0 -465
  780. package/.claude/skills/command-guide/reference/commands/workflow/init.md +0 -164
  781. package/.claude/skills/command-guide/reference/commands/workflow/lite-execute.md +0 -748
  782. package/.claude/skills/command-guide/reference/commands/workflow/lite-fix.md +0 -664
  783. package/.claude/skills/command-guide/reference/commands/workflow/lite-plan.md +0 -645
  784. package/.claude/skills/command-guide/reference/commands/workflow/plan.md +0 -551
  785. package/.claude/skills/command-guide/reference/commands/workflow/replan.md +0 -515
  786. package/.claude/skills/command-guide/reference/commands/workflow/review-fix.md +0 -606
  787. package/.claude/skills/command-guide/reference/commands/workflow/review-module-cycle.md +0 -765
  788. package/.claude/skills/command-guide/reference/commands/workflow/review-session-cycle.md +0 -776
  789. package/.claude/skills/command-guide/reference/commands/workflow/review.md +0 -298
  790. package/.claude/skills/command-guide/reference/commands/workflow/session/complete.md +0 -547
  791. package/.claude/skills/command-guide/reference/commands/workflow/session/list.md +0 -114
  792. package/.claude/skills/command-guide/reference/commands/workflow/session/resume.md +0 -77
  793. package/.claude/skills/command-guide/reference/commands/workflow/session/start.md +0 -257
  794. package/.claude/skills/command-guide/reference/commands/workflow/tdd-plan.md +0 -460
  795. package/.claude/skills/command-guide/reference/commands/workflow/tdd-verify.md +0 -400
  796. package/.claude/skills/command-guide/reference/commands/workflow/test-cycle-execute.md +0 -498
  797. package/.claude/skills/command-guide/reference/commands/workflow/test-fix-gen.md +0 -699
  798. package/.claude/skills/command-guide/reference/commands/workflow/test-gen.md +0 -529
  799. package/.claude/skills/command-guide/reference/commands/workflow/tools/conflict-resolution.md +0 -766
  800. package/.claude/skills/command-guide/reference/commands/workflow/tools/context-gather.md +0 -433
  801. package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-agent.md +0 -487
  802. package/.claude/skills/command-guide/reference/commands/workflow/tools/task-generate-tdd.md +0 -518
  803. package/.claude/skills/command-guide/reference/commands/workflow/tools/tdd-coverage-analysis.md +0 -309
  804. package/.claude/skills/command-guide/reference/commands/workflow/tools/test-concept-enhanced.md +0 -163
  805. package/.claude/skills/command-guide/reference/commands/workflow/tools/test-context-gather.md +0 -232
  806. package/.claude/skills/command-guide/reference/commands/workflow/tools/test-task-generate.md +0 -254
  807. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/animation-extract.md +0 -1150
  808. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/codify-style.md +0 -652
  809. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/design-sync.md +0 -454
  810. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/explore-auto.md +0 -678
  811. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/generate.md +0 -504
  812. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/imitate-auto.md +0 -745
  813. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/import-from-code.md +0 -537
  814. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/layout-extract.md +0 -788
  815. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/reference-page-generator.md +0 -356
  816. package/.claude/skills/command-guide/reference/commands/workflow/ui-design/style-extract.md +0 -773
  817. package/.claude/skills/command-guide/scripts/analyze_commands.py +0 -502
  818. package/.claude/skills/command-guide/scripts/update-index.sh +0 -130
  819. package/.claude/skills/command-guide/templates/issue-bug.md +0 -104
  820. package/.claude/skills/command-guide/templates/issue-diagnosis.md +0 -275
  821. package/.claude/skills/command-guide/templates/issue-feature.md +0 -97
  822. package/.claude/skills/command-guide/templates/issue-question.md +0 -141
@@ -1,22 +1,66 @@
1
- // @ts-nocheck
2
1
  /**
3
2
  * Skills Routes Module
4
3
  * Handles all Skills-related API endpoints
5
4
  */
6
- import type { IncomingMessage, ServerResponse } from 'http';
7
5
  import { readFileSync, existsSync, readdirSync, statSync, unlinkSync, promises as fsPromises } from 'fs';
8
6
  import { join } from 'path';
9
7
  import { homedir } from 'os';
10
8
  import { executeCliTool } from '../../tools/cli-executor.js';
9
+ import { SmartContentFormatter } from '../../tools/cli-output-converter.js';
10
+ import { validatePath as validateAllowedPath } from '../../utils/path-validator.js';
11
+ import type { RouteContext } from './types.js';
12
+
13
+ type SkillLocation = 'project' | 'user';
14
+
15
+ interface ParsedSkillFrontmatter {
16
+ name: string;
17
+ description: string;
18
+ version: string | null;
19
+ allowedTools: string[];
20
+ content: string;
21
+ }
22
+
23
+ interface SkillSummary {
24
+ name: string;
25
+ folderName: string;
26
+ description: string;
27
+ version: string | null;
28
+ allowedTools: string[];
29
+ location: SkillLocation;
30
+ path: string;
31
+ supportingFiles: string[];
32
+ }
33
+
34
+ interface SkillsConfig {
35
+ projectSkills: SkillSummary[];
36
+ userSkills: SkillSummary[];
37
+ }
38
+
39
+ interface SkillInfo {
40
+ name: string;
41
+ description: string;
42
+ version: string | null;
43
+ allowedTools: string[];
44
+ supportingFiles: string[];
45
+ }
46
+
47
+ type SkillFolderValidation =
48
+ | { valid: true; errors: string[]; skillInfo: SkillInfo }
49
+ | { valid: false; errors: string[]; skillInfo: null };
50
+
51
+ type GenerationType = 'description' | 'template';
11
52
 
12
- export interface RouteContext {
13
- pathname: string;
14
- url: URL;
15
- req: IncomingMessage;
16
- res: ServerResponse;
17
- initialPath: string;
18
- handlePostRequest: (req: IncomingMessage, res: ServerResponse, handler: (body: unknown) => Promise<any>) => void;
19
- broadcastToClients: (data: unknown) => void;
53
+ interface GenerationParams {
54
+ generationType: GenerationType;
55
+ description?: string;
56
+ skillName: string;
57
+ location: SkillLocation;
58
+ projectPath: string;
59
+ broadcastToClients?: (data: unknown) => void;
60
+ }
61
+
62
+ function isRecord(value: unknown): value is Record<string, unknown> {
63
+ return typeof value === 'object' && value !== null;
20
64
  }
21
65
 
22
66
  // ========== Skills Helper Functions ==========
@@ -26,8 +70,8 @@ export interface RouteContext {
26
70
  * @param {string} content - Skill file content
27
71
  * @returns {Object} Parsed frontmatter and content
28
72
  */
29
- function parseSkillFrontmatter(content) {
30
- const result = {
73
+ function parseSkillFrontmatter(content: string): ParsedSkillFrontmatter {
74
+ const result: ParsedSkillFrontmatter = {
31
75
  name: '',
32
76
  description: '',
33
77
  version: null,
@@ -58,7 +102,11 @@ function parseSkillFrontmatter(content) {
58
102
  result.version = value.replace(/^["']|["']$/g, '');
59
103
  } else if (key === 'allowed-tools' || key === 'allowedtools') {
60
104
  // Parse as comma-separated or YAML array
61
- result.allowedTools = value.replace(/^\[|\]$/g, '').split(',').map(t => t.trim()).filter(Boolean);
105
+ result.allowedTools = value
106
+ .replace(/^\[|\]$/g, '')
107
+ .split(',')
108
+ .map((tool) => tool.trim())
109
+ .filter(Boolean);
62
110
  }
63
111
  }
64
112
  }
@@ -75,8 +123,8 @@ function parseSkillFrontmatter(content) {
75
123
  * @param {string} skillDir
76
124
  * @returns {string[]}
77
125
  */
78
- function getSupportingFiles(skillDir) {
79
- const files = [];
126
+ function getSupportingFiles(skillDir: string): string[] {
127
+ const files: string[] = [];
80
128
  try {
81
129
  const entries = readdirSync(skillDir, { withFileTypes: true });
82
130
  for (const entry of entries) {
@@ -99,8 +147,8 @@ function getSupportingFiles(skillDir) {
99
147
  * @param {string} projectPath
100
148
  * @returns {Object}
101
149
  */
102
- function getSkillsConfig(projectPath) {
103
- const result = {
150
+ function getSkillsConfig(projectPath: string): SkillsConfig {
151
+ const result: SkillsConfig = {
104
152
  projectSkills: [],
105
153
  userSkills: []
106
154
  };
@@ -179,17 +227,44 @@ function getSkillsConfig(projectPath) {
179
227
  * @param {string} projectPath
180
228
  * @returns {Object}
181
229
  */
182
- function getSkillDetail(skillName, location, projectPath) {
230
+ async function getSkillDetail(skillName: string, location: SkillLocation, projectPath: string, initialPath: string) {
183
231
  try {
184
- const baseDir = location === 'project'
185
- ? join(projectPath, '.claude', 'skills')
186
- : join(homedir(), '.claude', 'skills');
232
+ if (skillName.includes('/') || skillName.includes('\\')) {
233
+ return { error: 'Access denied', status: 403 };
234
+ }
235
+ if (skillName.includes('..')) {
236
+ return { error: 'Invalid skill name', status: 400 };
237
+ }
238
+
239
+ let baseDir;
240
+ if (location === 'project') {
241
+ try {
242
+ const validatedProjectPath = await validateAllowedPath(projectPath, { mustExist: true, allowedDirectories: [initialPath] });
243
+ baseDir = join(validatedProjectPath, '.claude', 'skills');
244
+ } catch (err) {
245
+ const message = err instanceof Error ? err.message : String(err);
246
+ const status = message.includes('Access denied') ? 403 : 400;
247
+ console.error(`[Skills] Project path validation failed: ${message}`);
248
+ return { error: status === 403 ? 'Access denied' : 'Invalid path', status };
249
+ }
250
+ } else {
251
+ baseDir = join(homedir(), '.claude', 'skills');
252
+ }
187
253
 
188
254
  const skillDir = join(baseDir, skillName);
189
- const skillMdPath = join(skillDir, 'SKILL.md');
255
+ const skillMdCandidate = join(skillDir, 'SKILL.md');
190
256
 
191
- if (!existsSync(skillMdPath)) {
192
- return { error: 'Skill not found' };
257
+ let skillMdPath;
258
+ try {
259
+ skillMdPath = await validateAllowedPath(skillMdCandidate, { mustExist: true, allowedDirectories: [skillDir] });
260
+ } catch (err) {
261
+ const message = err instanceof Error ? err.message : String(err);
262
+ if (message.includes('File not found')) {
263
+ return { error: 'Skill not found', status: 404 };
264
+ }
265
+ const status = message.includes('Access denied') ? 403 : 400;
266
+ console.error(`[Skills] Path validation failed: ${message}`);
267
+ return { error: status === 403 ? 'Access denied' : 'Invalid path', status };
193
268
  }
194
269
 
195
270
  const content = readFileSync(skillMdPath, 'utf8');
@@ -210,7 +285,7 @@ function getSkillDetail(skillName, location, projectPath) {
210
285
  }
211
286
  };
212
287
  } catch (error) {
213
- return { error: (error as Error).message };
288
+ return { error: (error as Error).message, status: 500 };
214
289
  }
215
290
  }
216
291
 
@@ -221,38 +296,50 @@ function getSkillDetail(skillName, location, projectPath) {
221
296
  * @param {string} projectPath
222
297
  * @returns {Object}
223
298
  */
224
- function deleteSkill(skillName, location, projectPath) {
299
+ async function deleteSkill(skillName: string, location: SkillLocation, projectPath: string, initialPath: string) {
225
300
  try {
226
- const baseDir = location === 'project'
227
- ? join(projectPath, '.claude', 'skills')
228
- : join(homedir(), '.claude', 'skills');
229
-
230
- const skillDir = join(baseDir, skillName);
301
+ if (skillName.includes('/') || skillName.includes('\\')) {
302
+ return { error: 'Access denied', status: 403 };
303
+ }
304
+ if (skillName.includes('..')) {
305
+ return { error: 'Invalid skill name', status: 400 };
306
+ }
231
307
 
232
- if (!existsSync(skillDir)) {
233
- return { error: 'Skill not found' };
308
+ let baseDir;
309
+ if (location === 'project') {
310
+ try {
311
+ const validatedProjectPath = await validateAllowedPath(projectPath, { mustExist: true, allowedDirectories: [initialPath] });
312
+ baseDir = join(validatedProjectPath, '.claude', 'skills');
313
+ } catch (err) {
314
+ const message = err instanceof Error ? err.message : String(err);
315
+ const status = message.includes('Access denied') ? 403 : 400;
316
+ console.error(`[Skills] Project path validation failed: ${message}`);
317
+ return { error: status === 403 ? 'Access denied' : 'Invalid path', status };
318
+ }
319
+ } else {
320
+ baseDir = join(homedir(), '.claude', 'skills');
234
321
  }
235
322
 
236
- // Recursively delete directory
237
- const deleteRecursive = (dirPath) => {
238
- if (existsSync(dirPath)) {
239
- readdirSync(dirPath).forEach((file) => {
240
- const curPath = join(dirPath, file);
241
- if (statSync(curPath).isDirectory()) {
242
- deleteRecursive(curPath);
243
- } else {
244
- unlinkSync(curPath);
245
- }
246
- });
247
- fsPromises.rmdir(dirPath);
323
+ const skillDirCandidate = join(baseDir, skillName);
324
+
325
+ let skillDir;
326
+ try {
327
+ skillDir = await validateAllowedPath(skillDirCandidate, { mustExist: true, allowedDirectories: [baseDir] });
328
+ } catch (err) {
329
+ const message = err instanceof Error ? err.message : String(err);
330
+ if (message.includes('File not found')) {
331
+ return { error: 'Skill not found', status: 404 };
248
332
  }
249
- };
333
+ const status = message.includes('Access denied') ? 403 : 400;
334
+ console.error(`[Skills] Path validation failed: ${message}`);
335
+ return { error: status === 403 ? 'Access denied' : 'Invalid path', status };
336
+ }
250
337
 
251
- deleteRecursive(skillDir);
338
+ await fsPromises.rm(skillDir, { recursive: true, force: true });
252
339
 
253
340
  return { success: true, skillName, location };
254
341
  } catch (error) {
255
- return { error: (error as Error).message };
342
+ return { error: (error as Error).message, status: 500 };
256
343
  }
257
344
  }
258
345
 
@@ -261,8 +348,8 @@ function deleteSkill(skillName, location, projectPath) {
261
348
  * @param {string} folderPath - Path to skill folder
262
349
  * @returns {Object} Validation result with skill info
263
350
  */
264
- function validateSkillFolder(folderPath) {
265
- const errors = [];
351
+ function validateSkillFolder(folderPath: string): SkillFolderValidation {
352
+ const errors: string[] = [];
266
353
 
267
354
  // Check if folder exists
268
355
  if (!existsSync(folderPath)) {
@@ -327,7 +414,7 @@ function validateSkillFolder(folderPath) {
327
414
  * @param {string} source - Source directory path
328
415
  * @param {string} target - Target directory path
329
416
  */
330
- async function copyDirectoryRecursive(source, target) {
417
+ async function copyDirectoryRecursive(source: string, target: string): Promise<void> {
331
418
  await fsPromises.mkdir(target, { recursive: true });
332
419
 
333
420
  const entries = await fsPromises.readdir(source, { withFileTypes: true });
@@ -352,7 +439,7 @@ async function copyDirectoryRecursive(source, target) {
352
439
  * @param {string} customName - Optional custom name for skill
353
440
  * @returns {Object}
354
441
  */
355
- async function importSkill(sourcePath, location, projectPath, customName) {
442
+ async function importSkill(sourcePath: string, location: SkillLocation, projectPath: string, customName?: string) {
356
443
  try {
357
444
  // Validate source folder
358
445
  const validation = validateSkillFolder(sourcePath);
@@ -371,6 +458,9 @@ async function importSkill(sourcePath, location, projectPath, customName) {
371
458
 
372
459
  // Determine target folder name
373
460
  const skillName = customName || validation.skillInfo.name;
461
+ if (skillName.includes('/') || skillName.includes('\\') || skillName.includes('..')) {
462
+ return { error: 'Invalid skill name', status: 400 };
463
+ }
374
464
  const targetPath = join(baseDir, skillName);
375
465
 
376
466
  // Check if already exists
@@ -400,9 +490,13 @@ async function importSkill(sourcePath, location, projectPath, customName) {
400
490
  * @param {string} params.skillName - Name for the skill
401
491
  * @param {string} params.location - 'project' or 'user'
402
492
  * @param {string} params.projectPath - Project root path
493
+ * @param {Function} params.broadcastToClients - WebSocket broadcast function
403
494
  * @returns {Object}
404
495
  */
405
- async function generateSkillViaCLI({ generationType, description, skillName, location, projectPath }) {
496
+ async function generateSkillViaCLI({ generationType, description, skillName, location, projectPath, broadcastToClients }: GenerationParams) {
497
+ // Generate unique execution ID for tracking
498
+ const executionId = `skill-gen-${skillName}-${Date.now()}`;
499
+
406
500
  try {
407
501
  // Validate inputs
408
502
  if (!skillName) {
@@ -429,50 +523,107 @@ async function generateSkillViaCLI({ generationType, description, skillName, loc
429
523
  await fsPromises.mkdir(baseDir, { recursive: true });
430
524
  }
431
525
 
432
- // Build CLI prompt
526
+ // Build structured skill parameters for /skill-generator
433
527
  const targetLocationDisplay = location === 'project'
434
528
  ? '.claude/skills/'
435
529
  : '~/.claude/skills/';
436
530
 
437
- const prompt = `PURPOSE: Generate a complete Claude Code skill from description
438
- TASK: Parse skill requirements • Create SKILL.md with proper frontmatter (name, description, version, allowed-tools) • Generate supporting files if needed in skill folder
439
- MODE: write
440
- CONTEXT: @**/*
441
- EXPECTED: Complete skill folder structure with SKILL.md and all necessary files
442
- RULES: $(cat ~/.claude/workflows/cli-templates/prompts/universal/00-universal-rigorous-style.txt) | Follow Claude Code skill format | Include name, description in frontmatter | write=CREATE
443
-
444
- SKILL DESCRIPTION:
445
- ${description || 'Generate a basic skill template'}
446
-
447
- SKILL NAME: ${skillName}
448
- TARGET LOCATION: ${targetLocationDisplay}
449
- TARGET PATH: ${targetPath}
450
-
451
- REQUIREMENTS:
452
- 1. Create SKILL.md with frontmatter containing:
453
- - name: "${skillName}"
454
- - description: Brief description of the skill
455
- - version: "1.0.0"
456
- - allowed-tools: List of tools this skill can use (e.g., [Read, Write, Edit, Bash])
457
- 2. Add skill content below frontmatter explaining what the skill does and how to use it
458
- 3. If the skill requires supporting files (e.g., templates, scripts), create them in the skill folder
459
- 4. Ensure all files are properly formatted and follow best practices`;
531
+ // Structured fields from user input
532
+ const skillParams = {
533
+ skill_name: skillName,
534
+ description: description || 'Generate a basic skill template',
535
+ target_location: targetLocationDisplay,
536
+ target_path: targetPath,
537
+ location_type: location // 'project' | 'user'
538
+ };
539
+
540
+ // Prompt that invokes /skill-generator skill with structured parameters
541
+ const prompt = `/skill-generator
542
+
543
+ ## Skill Parameters (Structured Input)
544
+
545
+ \`\`\`json
546
+ ${JSON.stringify(skillParams, null, 2)}
547
+ \`\`\`
548
+
549
+ ## User Request
550
+
551
+ Create a new Claude Code skill with the following specifications:
552
+
553
+ - **Skill Name**: ${skillName}
554
+ - **Description**: ${description || 'Generate a basic skill template'}
555
+ - **Target Location**: ${targetLocationDisplay}${skillName}
556
+ - **Location Type**: ${location === 'project' ? 'Project-level (.claude/skills/)' : 'User-level (~/.claude/skills/)'}
557
+
558
+ ## Instructions
559
+
560
+ 1. Use the skill-generator to create a complete skill structure
561
+ 2. Generate SKILL.md with proper frontmatter (name, description, version, allowed-tools)
562
+ 3. Create necessary supporting files (phases, specs, templates as needed)
563
+ 4. Follow Claude Code skill design patterns and best practices
564
+ 5. Output all files to: ${targetPath}`;
565
+
566
+ // Broadcast CLI_EXECUTION_STARTED event
567
+ if (broadcastToClients) {
568
+ broadcastToClients({
569
+ type: 'CLI_EXECUTION_STARTED',
570
+ payload: {
571
+ executionId,
572
+ tool: 'claude',
573
+ mode: 'write',
574
+ category: 'internal',
575
+ context: 'skill-generation',
576
+ skillName
577
+ }
578
+ });
579
+ }
580
+
581
+ // Create onOutput callback for real-time streaming
582
+ const onOutput = broadcastToClients
583
+ ? (unit: import('../../tools/cli-output-converter.js').CliOutputUnit) => {
584
+ // CliOutputUnit handler: use SmartContentFormatter for intelligent formatting (never returns null)
585
+ const content = SmartContentFormatter.format(unit.content, unit.type);
586
+ broadcastToClients({
587
+ type: 'CLI_OUTPUT',
588
+ payload: {
589
+ executionId,
590
+ chunkType: unit.type,
591
+ data: content
592
+ }
593
+ });
594
+ }
595
+ : undefined;
460
596
 
461
597
  // Execute CLI tool (Claude) with write mode
598
+ const startTime = Date.now();
462
599
  const result = await executeCliTool({
463
600
  tool: 'claude',
464
601
  prompt,
465
602
  mode: 'write',
466
603
  cd: baseDir,
467
604
  timeout: 600000, // 10 minutes
468
- category: 'internal'
469
- });
605
+ category: 'internal',
606
+ id: executionId
607
+ }, onOutput);
608
+
609
+ // Broadcast CLI_EXECUTION_COMPLETED event
610
+ if (broadcastToClients) {
611
+ broadcastToClients({
612
+ type: 'CLI_EXECUTION_COMPLETED',
613
+ payload: {
614
+ executionId,
615
+ success: result.success,
616
+ status: result.execution?.status || (result.success ? 'success' : 'error'),
617
+ duration_ms: Date.now() - startTime
618
+ }
619
+ });
620
+ }
470
621
 
471
622
  // Check if execution was successful
472
623
  if (!result.success) {
473
624
  return {
474
625
  error: `CLI generation failed: ${result.stderr || 'Unknown error'}`,
475
- stdout: result.stdout,
626
+ stdout: result.parsedOutput || result.stdout,
476
627
  stderr: result.stderr
477
628
  };
478
629
  }
@@ -482,7 +633,7 @@ REQUIREMENTS:
482
633
  if (!validation.valid) {
483
634
  return {
484
635
  error: `Generated skill is invalid: ${validation.errors.join(', ')}`,
485
- stdout: result.stdout,
636
+ stdout: result.parsedOutput || result.stdout,
486
637
  stderr: result.stderr
487
638
  };
488
639
  }
@@ -492,7 +643,7 @@ REQUIREMENTS:
492
643
  skillName: validation.skillInfo.name,
493
644
  location,
494
645
  path: targetPath,
495
- stdout: result.stdout,
646
+ stdout: result.parsedOutput || result.stdout,
496
647
  stderr: result.stderr
497
648
  };
498
649
  } catch (error) {
@@ -507,14 +658,24 @@ REQUIREMENTS:
507
658
  * @returns true if route was handled, false otherwise
508
659
  */
509
660
  export async function handleSkillsRoutes(ctx: RouteContext): Promise<boolean> {
510
- const { pathname, url, req, res, initialPath, handlePostRequest } = ctx;
661
+ const { pathname, url, req, res, initialPath, handlePostRequest, broadcastToClients } = ctx;
511
662
 
512
663
  // API: Get all skills (project and user)
513
664
  if (pathname === '/api/skills') {
514
665
  const projectPathParam = url.searchParams.get('path') || initialPath;
515
- const skillsData = getSkillsConfig(projectPathParam);
516
- res.writeHead(200, { 'Content-Type': 'application/json' });
517
- res.end(JSON.stringify(skillsData));
666
+
667
+ try {
668
+ const validatedProjectPath = await validateAllowedPath(projectPathParam, { mustExist: true, allowedDirectories: [initialPath] });
669
+ const skillsData = getSkillsConfig(validatedProjectPath);
670
+ res.writeHead(200, { 'Content-Type': 'application/json' });
671
+ res.end(JSON.stringify(skillsData));
672
+ } catch (err) {
673
+ const message = err instanceof Error ? err.message : String(err);
674
+ const status = message.includes('Access denied') ? 403 : 400;
675
+ console.error(`[Skills] Project path validation failed: ${message}`);
676
+ res.writeHead(status, { 'Content-Type': 'application/json' });
677
+ res.end(JSON.stringify({ error: status === 403 ? 'Access denied' : 'Invalid path', projectSkills: [], userSkills: [] }));
678
+ }
518
679
  return true;
519
680
  }
520
681
 
@@ -526,18 +687,46 @@ export async function handleSkillsRoutes(ctx: RouteContext): Promise<boolean> {
526
687
  const location = url.searchParams.get('location') || 'project';
527
688
  const projectPathParam = url.searchParams.get('path') || initialPath;
528
689
 
529
- const baseDir = location === 'project'
530
- ? join(projectPathParam, '.claude', 'skills')
531
- : join(homedir(), '.claude', 'skills');
690
+ if (skillName.includes('/') || skillName.includes('\\') || skillName.includes('..')) {
691
+ res.writeHead(400, { 'Content-Type': 'application/json' });
692
+ res.end(JSON.stringify({ error: 'Invalid skill name' }));
693
+ return true;
694
+ }
532
695
 
533
- const dirPath = subPath
534
- ? join(baseDir, skillName, subPath)
535
- : join(baseDir, skillName);
696
+ let baseDir: string;
697
+ if (location === 'project') {
698
+ try {
699
+ const validatedProjectPath = await validateAllowedPath(projectPathParam, { mustExist: true, allowedDirectories: [initialPath] });
700
+ baseDir = join(validatedProjectPath, '.claude', 'skills');
701
+ } catch (err) {
702
+ const message = err instanceof Error ? err.message : String(err);
703
+ const status = message.includes('Access denied') ? 403 : 400;
704
+ console.error(`[Skills] Project path validation failed: ${message}`);
705
+ res.writeHead(status, { 'Content-Type': 'application/json' });
706
+ res.end(JSON.stringify({ error: status === 403 ? 'Access denied' : 'Invalid path' }));
707
+ return true;
708
+ }
709
+ } else {
710
+ baseDir = join(homedir(), '.claude', 'skills');
711
+ }
536
712
 
537
- // Security check: ensure path is within skill folder
538
- if (!dirPath.startsWith(join(baseDir, skillName))) {
539
- res.writeHead(403, { 'Content-Type': 'application/json' });
540
- res.end(JSON.stringify({ error: 'Access denied' }));
713
+ const skillRoot = join(baseDir, skillName);
714
+ const requestedDir = subPath ? join(skillRoot, subPath) : skillRoot;
715
+
716
+ let dirPath: string;
717
+ try {
718
+ dirPath = await validateAllowedPath(requestedDir, { mustExist: true, allowedDirectories: [skillRoot] });
719
+ } catch (err) {
720
+ const message = err instanceof Error ? err.message : String(err);
721
+ if (message.includes('File not found')) {
722
+ res.writeHead(404, { 'Content-Type': 'application/json' });
723
+ res.end(JSON.stringify({ error: 'Directory not found' }));
724
+ return true;
725
+ }
726
+ const status = message.includes('Access denied') ? 403 : 400;
727
+ console.error(`[Skills] Path validation failed: ${message}`);
728
+ res.writeHead(status, { 'Content-Type': 'application/json' });
729
+ res.end(JSON.stringify({ error: status === 403 ? 'Access denied' : 'Invalid path' }));
541
730
  return true;
542
731
  }
543
732
 
@@ -585,16 +774,46 @@ export async function handleSkillsRoutes(ctx: RouteContext): Promise<boolean> {
585
774
  return true;
586
775
  }
587
776
 
588
- const baseDir = location === 'project'
589
- ? join(projectPathParam, '.claude', 'skills')
590
- : join(homedir(), '.claude', 'skills');
777
+ if (skillName.includes('/') || skillName.includes('\\') || skillName.includes('..')) {
778
+ res.writeHead(400, { 'Content-Type': 'application/json' });
779
+ res.end(JSON.stringify({ error: 'Invalid skill name' }));
780
+ return true;
781
+ }
591
782
 
592
- const filePath = join(baseDir, skillName, fileName);
783
+ let baseDir: string;
784
+ if (location === 'project') {
785
+ try {
786
+ const validatedProjectPath = await validateAllowedPath(projectPathParam, { mustExist: true, allowedDirectories: [initialPath] });
787
+ baseDir = join(validatedProjectPath, '.claude', 'skills');
788
+ } catch (err) {
789
+ const message = err instanceof Error ? err.message : String(err);
790
+ const status = message.includes('Access denied') ? 403 : 400;
791
+ console.error(`[Skills] Project path validation failed: ${message}`);
792
+ res.writeHead(status, { 'Content-Type': 'application/json' });
793
+ res.end(JSON.stringify({ error: status === 403 ? 'Access denied' : 'Invalid path' }));
794
+ return true;
795
+ }
796
+ } else {
797
+ baseDir = join(homedir(), '.claude', 'skills');
798
+ }
593
799
 
594
- // Security check: ensure file is within skill folder
595
- if (!filePath.startsWith(join(baseDir, skillName))) {
596
- res.writeHead(403, { 'Content-Type': 'application/json' });
597
- res.end(JSON.stringify({ error: 'Access denied' }));
800
+ const skillRoot = join(baseDir, skillName);
801
+ const requestedFile = join(skillRoot, fileName);
802
+
803
+ let filePath: string;
804
+ try {
805
+ filePath = await validateAllowedPath(requestedFile, { mustExist: true, allowedDirectories: [skillRoot] });
806
+ } catch (err) {
807
+ const message = err instanceof Error ? err.message : String(err);
808
+ if (message.includes('File not found')) {
809
+ res.writeHead(404, { 'Content-Type': 'application/json' });
810
+ res.end(JSON.stringify({ error: 'File not found' }));
811
+ return true;
812
+ }
813
+ const status = message.includes('Access denied') ? 403 : 400;
814
+ console.error(`[Skills] Path validation failed: ${message}`);
815
+ res.writeHead(status, { 'Content-Type': 'application/json' });
816
+ res.end(JSON.stringify({ error: status === 403 ? 'Access denied' : 'Invalid path' }));
598
817
  return true;
599
818
  }
600
819
 
@@ -621,25 +840,54 @@ export async function handleSkillsRoutes(ctx: RouteContext): Promise<boolean> {
621
840
  const skillName = decodeURIComponent(pathParts[3]);
622
841
 
623
842
  handlePostRequest(req, res, async (body) => {
624
- const { fileName, content, location, projectPath: projectPathParam } = body;
843
+ if (!isRecord(body)) {
844
+ return { error: 'Invalid request body', status: 400 };
845
+ }
625
846
 
626
- if (!fileName) {
847
+ const fileName = body.fileName;
848
+ const content = body.content;
849
+ const location: SkillLocation = body.location === 'project' ? 'project' : 'user';
850
+ const projectPathParam = typeof body.projectPath === 'string' ? body.projectPath : undefined;
851
+
852
+ if (typeof fileName !== 'string' || !fileName) {
627
853
  return { error: 'fileName is required' };
628
854
  }
629
855
 
630
- if (content === undefined) {
856
+ if (typeof content !== 'string') {
631
857
  return { error: 'content is required' };
632
858
  }
633
859
 
634
- const baseDir = location === 'project'
635
- ? join(projectPathParam || initialPath, '.claude', 'skills')
636
- : join(homedir(), '.claude', 'skills');
860
+ if (skillName.includes('/') || skillName.includes('\\') || skillName.includes('..')) {
861
+ return { error: 'Invalid skill name', status: 400 };
862
+ }
863
+
864
+ let baseDir: string;
865
+ if (location === 'project') {
866
+ try {
867
+ const projectRoot = projectPathParam || initialPath;
868
+ const validatedProjectPath = await validateAllowedPath(projectRoot, { mustExist: true, allowedDirectories: [initialPath] });
869
+ baseDir = join(validatedProjectPath, '.claude', 'skills');
870
+ } catch (err) {
871
+ const message = err instanceof Error ? err.message : String(err);
872
+ const status = message.includes('Access denied') ? 403 : 400;
873
+ console.error(`[Skills] Project path validation failed: ${message}`);
874
+ return { error: status === 403 ? 'Access denied' : 'Invalid path', status };
875
+ }
876
+ } else {
877
+ baseDir = join(homedir(), '.claude', 'skills');
878
+ }
637
879
 
638
- const filePath = join(baseDir, skillName, fileName);
880
+ const skillRoot = join(baseDir, skillName);
881
+ const requestedFile = join(skillRoot, fileName);
639
882
 
640
- // Security check: ensure file is within skill folder
641
- if (!filePath.startsWith(join(baseDir, skillName))) {
642
- return { error: 'Access denied' };
883
+ let filePath: string;
884
+ try {
885
+ filePath = await validateAllowedPath(requestedFile, { allowedDirectories: [skillRoot] });
886
+ } catch (err) {
887
+ const message = err instanceof Error ? err.message : String(err);
888
+ const status = message.includes('Access denied') ? 403 : 400;
889
+ console.error(`[Skills] Path validation failed: ${message}`);
890
+ return { error: status === 403 ? 'Access denied' : 'Invalid path', status };
643
891
  }
644
892
 
645
893
  try {
@@ -656,25 +904,43 @@ export async function handleSkillsRoutes(ctx: RouteContext): Promise<boolean> {
656
904
  if (pathname.startsWith('/api/skills/') && req.method === 'GET' &&
657
905
  !pathname.endsWith('/skills/') && !pathname.endsWith('/dir') && !pathname.endsWith('/file')) {
658
906
  const skillName = decodeURIComponent(pathname.replace('/api/skills/', ''));
659
- const location = url.searchParams.get('location') || 'project';
907
+ const locationParam = url.searchParams.get('location');
908
+ const location: SkillLocation = locationParam === 'user' ? 'user' : 'project';
660
909
  const projectPathParam = url.searchParams.get('path') || initialPath;
661
- const skillDetail = getSkillDetail(skillName, location, projectPathParam);
910
+ const skillDetail = await getSkillDetail(skillName, location, projectPathParam, initialPath);
662
911
  if (skillDetail.error) {
663
- res.writeHead(404, { 'Content-Type': 'application/json' });
664
- res.end(JSON.stringify(skillDetail));
665
- } else {
666
- res.writeHead(200, { 'Content-Type': 'application/json' });
667
- res.end(JSON.stringify(skillDetail));
912
+ res.writeHead(skillDetail.status || 404, { 'Content-Type': 'application/json' });
913
+ res.end(JSON.stringify({ error: skillDetail.error }));
914
+ return true;
668
915
  }
916
+
917
+ res.writeHead(200, { 'Content-Type': 'application/json' });
918
+ res.end(JSON.stringify(skillDetail));
669
919
  return true;
670
920
  }
671
921
 
672
922
  // API: Delete skill
673
923
  if (pathname.startsWith('/api/skills/') && req.method === 'DELETE') {
674
924
  const skillName = decodeURIComponent(pathname.replace('/api/skills/', ''));
925
+ if (skillName.includes('/') || skillName.includes('\\')) {
926
+ res.writeHead(403, { 'Content-Type': 'application/json' });
927
+ res.end(JSON.stringify({ error: 'Access denied' }));
928
+ return true;
929
+ }
930
+ if (skillName.includes('..')) {
931
+ res.writeHead(400, { 'Content-Type': 'application/json' });
932
+ res.end(JSON.stringify({ error: 'Invalid skill name' }));
933
+ return true;
934
+ }
675
935
  handlePostRequest(req, res, async (body) => {
676
- const { location, projectPath: projectPathParam } = body;
677
- return deleteSkill(skillName, location, projectPathParam || initialPath);
936
+ if (!isRecord(body)) {
937
+ return { error: 'Invalid request body', status: 400 };
938
+ }
939
+
940
+ const location: SkillLocation = body.location === 'project' ? 'project' : 'user';
941
+ const projectPathParam = typeof body.projectPath === 'string' ? body.projectPath : undefined;
942
+
943
+ return deleteSkill(skillName, location, projectPathParam || initialPath, initialPath);
678
944
  });
679
945
  return true;
680
946
  }
@@ -682,11 +948,24 @@ export async function handleSkillsRoutes(ctx: RouteContext): Promise<boolean> {
682
948
  // API: Validate skill import
683
949
  if (pathname === '/api/skills/validate-import' && req.method === 'POST') {
684
950
  handlePostRequest(req, res, async (body) => {
685
- const { sourcePath } = body;
686
- if (!sourcePath) {
951
+ if (!isRecord(body)) {
687
952
  return { valid: false, errors: ['Source path is required'], skillInfo: null };
688
953
  }
689
- return validateSkillFolder(sourcePath);
954
+
955
+ const sourcePath = body.sourcePath;
956
+ if (typeof sourcePath !== 'string' || !sourcePath.trim()) {
957
+ return { valid: false, errors: ['Source path is required'], skillInfo: null };
958
+ }
959
+
960
+ try {
961
+ const validatedSourcePath = await validateAllowedPath(sourcePath, { mustExist: true });
962
+ return validateSkillFolder(validatedSourcePath);
963
+ } catch (err) {
964
+ const message = err instanceof Error ? err.message : String(err);
965
+ const status = message.includes('Access denied') ? 403 : 400;
966
+ console.error(`[Skills] Path validation failed: ${message}`);
967
+ return { error: status === 403 ? 'Access denied' : 'Invalid path', status };
968
+ }
690
969
  });
691
970
  return true;
692
971
  }
@@ -694,37 +973,78 @@ export async function handleSkillsRoutes(ctx: RouteContext): Promise<boolean> {
694
973
  // API: Create/Import skill
695
974
  if (pathname === '/api/skills/create' && req.method === 'POST') {
696
975
  handlePostRequest(req, res, async (body) => {
697
- const { mode, location, sourcePath, skillName, description, generationType, projectPath: projectPathParam } = body;
976
+ if (!isRecord(body)) {
977
+ return { error: 'Invalid request body', status: 400 };
978
+ }
979
+
980
+ const mode = body.mode;
981
+ const locationValue = body.location;
982
+ const sourcePath = typeof body.sourcePath === 'string' ? body.sourcePath : undefined;
983
+ const skillName = typeof body.skillName === 'string' ? body.skillName : undefined;
984
+ const description = typeof body.description === 'string' ? body.description : undefined;
985
+ const generationType = typeof body.generationType === 'string' ? body.generationType : undefined;
986
+ const projectPathParam = typeof body.projectPath === 'string' ? body.projectPath : undefined;
698
987
 
699
- if (!mode) {
988
+ if (typeof mode !== 'string' || !mode) {
700
989
  return { error: 'Mode is required (import or cli-generate)' };
701
990
  }
702
991
 
703
- if (!location) {
992
+ if (locationValue !== 'project' && locationValue !== 'user') {
704
993
  return { error: 'Location is required (project or user)' };
705
994
  }
706
995
 
996
+ const location: SkillLocation = locationValue;
707
997
  const projectPath = projectPathParam || initialPath;
708
998
 
999
+ let validatedProjectPath = projectPath;
1000
+ if (location === 'project') {
1001
+ try {
1002
+ validatedProjectPath = await validateAllowedPath(projectPath, { mustExist: true, allowedDirectories: [initialPath] });
1003
+ } catch (err) {
1004
+ const message = err instanceof Error ? err.message : String(err);
1005
+ const status = message.includes('Access denied') ? 403 : 400;
1006
+ console.error(`[Skills] Project path validation failed: ${message}`);
1007
+ return { error: status === 403 ? 'Access denied' : 'Invalid path', status };
1008
+ }
1009
+ }
1010
+
709
1011
  if (mode === 'import') {
710
1012
  // Import mode: copy existing skill folder
711
1013
  if (!sourcePath) {
712
1014
  return { error: 'Source path is required for import mode' };
713
1015
  }
714
1016
 
715
- return await importSkill(sourcePath, location, projectPath, skillName);
1017
+ if (skillName && (skillName.includes('/') || skillName.includes('\\') || skillName.includes('..'))) {
1018
+ return { error: 'Invalid skill name', status: 400 };
1019
+ }
1020
+
1021
+ let validatedSourcePath;
1022
+ try {
1023
+ validatedSourcePath = await validateAllowedPath(sourcePath, { mustExist: true });
1024
+ } catch (err) {
1025
+ const message = err instanceof Error ? err.message : String(err);
1026
+ const status = message.includes('Access denied') ? 403 : 400;
1027
+ console.error(`[Skills] Path validation failed: ${message}`);
1028
+ return { error: status === 403 ? 'Access denied' : 'Invalid path', status };
1029
+ }
1030
+
1031
+ return await importSkill(validatedSourcePath, location, validatedProjectPath, skillName);
716
1032
  } else if (mode === 'cli-generate') {
717
1033
  // CLI generate mode: use Claude to generate skill
718
1034
  if (!skillName) {
719
1035
  return { error: 'Skill name is required for CLI generation mode' };
720
1036
  }
1037
+ if (skillName.includes('/') || skillName.includes('\\') || skillName.includes('..')) {
1038
+ return { error: 'Invalid skill name', status: 400 };
1039
+ }
721
1040
 
722
1041
  return await generateSkillViaCLI({
723
- generationType: generationType || 'description',
1042
+ generationType: generationType === 'template' ? 'template' : 'description',
724
1043
  description,
725
1044
  skillName,
726
1045
  location,
727
- projectPath
1046
+ projectPath: validatedProjectPath,
1047
+ broadcastToClients
728
1048
  });
729
1049
  } else {
730
1050
  return { error: 'Invalid mode. Must be "import" or "cli-generate"' };