ccjk 12.0.7 → 12.0.8

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 (299) hide show
  1. package/package.json +1 -1
  2. package/dist/chunks/agent-teams.mjs +0 -136
  3. package/dist/chunks/agent.mjs +0 -1439
  4. package/dist/chunks/agents.mjs +0 -3778
  5. package/dist/chunks/api-cli.mjs +0 -132
  6. package/dist/chunks/api-providers.mjs +0 -129
  7. package/dist/chunks/api.mjs +0 -112
  8. package/dist/chunks/auto-bootstrap.mjs +0 -358
  9. package/dist/chunks/auto-init.mjs +0 -7584
  10. package/dist/chunks/auto-updater.mjs +0 -410
  11. package/dist/chunks/banner.mjs +0 -188
  12. package/dist/chunks/bash.mjs +0 -187
  13. package/dist/chunks/boost.mjs +0 -397
  14. package/dist/chunks/ccjk-agents.mjs +0 -414
  15. package/dist/chunks/ccjk-all.mjs +0 -1028
  16. package/dist/chunks/ccjk-config.mjs +0 -261
  17. package/dist/chunks/ccjk-hooks.mjs +0 -1074
  18. package/dist/chunks/ccjk-mcp.mjs +0 -761
  19. package/dist/chunks/ccjk-setup.mjs +0 -763
  20. package/dist/chunks/ccjk-skills.mjs +0 -514
  21. package/dist/chunks/ccr.mjs +0 -98
  22. package/dist/chunks/ccu.mjs +0 -40
  23. package/dist/chunks/check-updates.mjs +0 -108
  24. package/dist/chunks/claude-code-config-manager.mjs +0 -750
  25. package/dist/chunks/claude-code-incremental-manager.mjs +0 -623
  26. package/dist/chunks/claude-config.mjs +0 -236
  27. package/dist/chunks/claude-wrapper.mjs +0 -85
  28. package/dist/chunks/cleanup-migration.mjs +0 -20
  29. package/dist/chunks/cli-hook.mjs +0 -2285
  30. package/dist/chunks/cloud-sync.mjs +0 -29
  31. package/dist/chunks/codex-config-switch.mjs +0 -451
  32. package/dist/chunks/codex-provider-manager.mjs +0 -236
  33. package/dist/chunks/codex-uninstaller.mjs +0 -404
  34. package/dist/chunks/codex.mjs +0 -2077
  35. package/dist/chunks/commands.mjs +0 -108
  36. package/dist/chunks/commands2.mjs +0 -413
  37. package/dist/chunks/commit.mjs +0 -138
  38. package/dist/chunks/completion.mjs +0 -515
  39. package/dist/chunks/config-consolidator.mjs +0 -172
  40. package/dist/chunks/config-switch.mjs +0 -317
  41. package/dist/chunks/config.mjs +0 -379
  42. package/dist/chunks/config2.mjs +0 -477
  43. package/dist/chunks/config3.mjs +0 -470
  44. package/dist/chunks/constants.mjs +0 -133
  45. package/dist/chunks/context-loader.mjs +0 -343
  46. package/dist/chunks/context.mjs +0 -372
  47. package/dist/chunks/convoy-manager.mjs +0 -880
  48. package/dist/chunks/dashboard.mjs +0 -476
  49. package/dist/chunks/doctor.mjs +0 -964
  50. package/dist/chunks/evolution.mjs +0 -382
  51. package/dist/chunks/features.mjs +0 -698
  52. package/dist/chunks/fish.mjs +0 -181
  53. package/dist/chunks/fs-operations.mjs +0 -192
  54. package/dist/chunks/health-alerts.mjs +0 -304
  55. package/dist/chunks/health-check.mjs +0 -532
  56. package/dist/chunks/help.mjs +0 -340
  57. package/dist/chunks/hook-installer.mjs +0 -45
  58. package/dist/chunks/index.mjs +0 -24
  59. package/dist/chunks/index10.mjs +0 -1171
  60. package/dist/chunks/index11.mjs +0 -1008
  61. package/dist/chunks/index12.mjs +0 -193
  62. package/dist/chunks/index13.mjs +0 -218
  63. package/dist/chunks/index14.mjs +0 -663
  64. package/dist/chunks/index2.mjs +0 -19
  65. package/dist/chunks/index3.mjs +0 -19092
  66. package/dist/chunks/index4.mjs +0 -8
  67. package/dist/chunks/index5.mjs +0 -7600
  68. package/dist/chunks/index6.mjs +0 -171
  69. package/dist/chunks/index7.mjs +0 -3583
  70. package/dist/chunks/index8.mjs +0 -19
  71. package/dist/chunks/index9.mjs +0 -616
  72. package/dist/chunks/init.mjs +0 -1606
  73. package/dist/chunks/installer.mjs +0 -690
  74. package/dist/chunks/installer2.mjs +0 -179
  75. package/dist/chunks/interview.mjs +0 -2927
  76. package/dist/chunks/json-config.mjs +0 -60
  77. package/dist/chunks/linux.mjs +0 -3863
  78. package/dist/chunks/macos.mjs +0 -69
  79. package/dist/chunks/main.mjs +0 -635
  80. package/dist/chunks/manager.mjs +0 -1048
  81. package/dist/chunks/marketplace.mjs +0 -949
  82. package/dist/chunks/mcp-cli.mjs +0 -204
  83. package/dist/chunks/mcp-performance.mjs +0 -187
  84. package/dist/chunks/mcp.mjs +0 -1231
  85. package/dist/chunks/menu.mjs +0 -652
  86. package/dist/chunks/metrics-display.mjs +0 -153
  87. package/dist/chunks/migrator.mjs +0 -178
  88. package/dist/chunks/monitor.mjs +0 -1856
  89. package/dist/chunks/notification.mjs +0 -1864
  90. package/dist/chunks/onboarding.mjs +0 -385
  91. package/dist/chunks/package.mjs +0 -3
  92. package/dist/chunks/paradigm.mjs +0 -74
  93. package/dist/chunks/permission-manager.mjs +0 -132
  94. package/dist/chunks/permissions.mjs +0 -265
  95. package/dist/chunks/persistence-manager.mjs +0 -794
  96. package/dist/chunks/persistence.mjs +0 -667
  97. package/dist/chunks/platform.mjs +0 -391
  98. package/dist/chunks/plugin.mjs +0 -1936
  99. package/dist/chunks/powershell.mjs +0 -213
  100. package/dist/chunks/prompts.mjs +0 -241
  101. package/dist/chunks/providers.mjs +0 -260
  102. package/dist/chunks/quick-actions.mjs +0 -320
  103. package/dist/chunks/quick-provider.mjs +0 -682
  104. package/dist/chunks/quick-setup.mjs +0 -412
  105. package/dist/chunks/remote.mjs +0 -497
  106. package/dist/chunks/session.mjs +0 -878
  107. package/dist/chunks/sessions.mjs +0 -106
  108. package/dist/chunks/silent-updater.mjs +0 -396
  109. package/dist/chunks/simple-config.mjs +0 -98
  110. package/dist/chunks/skill.mjs +0 -117
  111. package/dist/chunks/skill2.mjs +0 -9003
  112. package/dist/chunks/skills-sync.mjs +0 -6460
  113. package/dist/chunks/skills.mjs +0 -567
  114. package/dist/chunks/slash-commands.mjs +0 -207
  115. package/dist/chunks/smart-defaults.mjs +0 -412
  116. package/dist/chunks/smart-guide.mjs +0 -194
  117. package/dist/chunks/startup.mjs +0 -487
  118. package/dist/chunks/stats.mjs +0 -410
  119. package/dist/chunks/status.mjs +0 -289
  120. package/dist/chunks/team.mjs +0 -63
  121. package/dist/chunks/thinking.mjs +0 -626
  122. package/dist/chunks/trace.mjs +0 -57
  123. package/dist/chunks/uninstall.mjs +0 -849
  124. package/dist/chunks/update.mjs +0 -167
  125. package/dist/chunks/upgrade-manager.mjs +0 -204
  126. package/dist/chunks/version-checker.mjs +0 -881
  127. package/dist/chunks/vim.mjs +0 -903
  128. package/dist/chunks/windows.mjs +0 -14
  129. package/dist/chunks/workflows.mjs +0 -633
  130. package/dist/chunks/wsl.mjs +0 -129
  131. package/dist/chunks/zero-config.mjs +0 -374
  132. package/dist/chunks/zsh.mjs +0 -182
  133. package/dist/cli.d.mts +0 -1
  134. package/dist/cli.d.ts +0 -1
  135. package/dist/cli.mjs +0 -2199
  136. package/dist/i18n/locales/en/agent-teams.json +0 -18
  137. package/dist/i18n/locales/en/agentBrowser.json +0 -79
  138. package/dist/i18n/locales/en/agents.json +0 -135
  139. package/dist/i18n/locales/en/api.json +0 -63
  140. package/dist/i18n/locales/en/ccjk-agents.json +0 -33
  141. package/dist/i18n/locales/en/ccjk-all.json +0 -23
  142. package/dist/i18n/locales/en/ccjk-skills.json +0 -22
  143. package/dist/i18n/locales/en/ccjk.json +0 -276
  144. package/dist/i18n/locales/en/ccr.json +0 -65
  145. package/dist/i18n/locales/en/claude-md.json +0 -73
  146. package/dist/i18n/locales/en/cli.json +0 -152
  147. package/dist/i18n/locales/en/cloud-setup.json +0 -31
  148. package/dist/i18n/locales/en/cloud-sync.json +0 -147
  149. package/dist/i18n/locales/en/cloud.json +0 -40
  150. package/dist/i18n/locales/en/cloudPlugins.json +0 -118
  151. package/dist/i18n/locales/en/codex.json +0 -127
  152. package/dist/i18n/locales/en/cometix.json +0 -29
  153. package/dist/i18n/locales/en/common.json +0 -68
  154. package/dist/i18n/locales/en/config.json +0 -108
  155. package/dist/i18n/locales/en/configuration.json +0 -226
  156. package/dist/i18n/locales/en/context.json +0 -85
  157. package/dist/i18n/locales/en/dashboard.json +0 -78
  158. package/dist/i18n/locales/en/errors.json +0 -26
  159. package/dist/i18n/locales/en/evolution.json +0 -54
  160. package/dist/i18n/locales/en/hooks.json +0 -74
  161. package/dist/i18n/locales/en/hooksSync.json +0 -133
  162. package/dist/i18n/locales/en/installation.json +0 -83
  163. package/dist/i18n/locales/en/interview.json +0 -104
  164. package/dist/i18n/locales/en/language.json +0 -19
  165. package/dist/i18n/locales/en/lsp.json +0 -78
  166. package/dist/i18n/locales/en/marketplace.json +0 -116
  167. package/dist/i18n/locales/en/mcp.json +0 -178
  168. package/dist/i18n/locales/en/memory.json +0 -92
  169. package/dist/i18n/locales/en/menu.json +0 -143
  170. package/dist/i18n/locales/en/multi-config.json +0 -79
  171. package/dist/i18n/locales/en/notification.json +0 -307
  172. package/dist/i18n/locales/en/permissions.json +0 -95
  173. package/dist/i18n/locales/en/persistence.json +0 -127
  174. package/dist/i18n/locales/en/plugins.json +0 -146
  175. package/dist/i18n/locales/en/quick-actions.json +0 -78
  176. package/dist/i18n/locales/en/registry.json +0 -54
  177. package/dist/i18n/locales/en/remote.json +0 -93
  178. package/dist/i18n/locales/en/sandbox.json +0 -44
  179. package/dist/i18n/locales/en/setup.json +0 -44
  180. package/dist/i18n/locales/en/shencha.json +0 -14
  181. package/dist/i18n/locales/en/skills.json +0 -100
  182. package/dist/i18n/locales/en/skillsSync.json +0 -74
  183. package/dist/i18n/locales/en/smartGuide.json +0 -49
  184. package/dist/i18n/locales/en/stats.json +0 -20
  185. package/dist/i18n/locales/en/subagent.json +0 -69
  186. package/dist/i18n/locales/en/superpowers.json +0 -117
  187. package/dist/i18n/locales/en/team.json +0 -7
  188. package/dist/i18n/locales/en/thinking.json +0 -65
  189. package/dist/i18n/locales/en/tools.json +0 -42
  190. package/dist/i18n/locales/en/uninstall.json +0 -56
  191. package/dist/i18n/locales/en/updater.json +0 -29
  192. package/dist/i18n/locales/en/vim.json +0 -169
  193. package/dist/i18n/locales/en/workflow.json +0 -55
  194. package/dist/i18n/locales/en/workspace.json +0 -108
  195. package/dist/i18n/locales/zh-CN/agent-teams.json +0 -18
  196. package/dist/i18n/locales/zh-CN/agentBrowser.json +0 -79
  197. package/dist/i18n/locales/zh-CN/agents.json +0 -135
  198. package/dist/i18n/locales/zh-CN/api.json +0 -63
  199. package/dist/i18n/locales/zh-CN/ccjk-agents.json +0 -33
  200. package/dist/i18n/locales/zh-CN/ccjk-all.json +0 -23
  201. package/dist/i18n/locales/zh-CN/ccjk-skills.json +0 -22
  202. package/dist/i18n/locales/zh-CN/ccjk.json +0 -276
  203. package/dist/i18n/locales/zh-CN/ccr.json +0 -65
  204. package/dist/i18n/locales/zh-CN/claude-md.json +0 -73
  205. package/dist/i18n/locales/zh-CN/cli.json +0 -152
  206. package/dist/i18n/locales/zh-CN/cloud-setup.json +0 -31
  207. package/dist/i18n/locales/zh-CN/cloud-sync.json +0 -147
  208. package/dist/i18n/locales/zh-CN/cloud.json +0 -40
  209. package/dist/i18n/locales/zh-CN/cloudPlugins.json +0 -118
  210. package/dist/i18n/locales/zh-CN/codex.json +0 -127
  211. package/dist/i18n/locales/zh-CN/cometix.json +0 -29
  212. package/dist/i18n/locales/zh-CN/common.json +0 -68
  213. package/dist/i18n/locales/zh-CN/config.json +0 -108
  214. package/dist/i18n/locales/zh-CN/configuration.json +0 -224
  215. package/dist/i18n/locales/zh-CN/context.json +0 -85
  216. package/dist/i18n/locales/zh-CN/dashboard.json +0 -78
  217. package/dist/i18n/locales/zh-CN/errors.json +0 -26
  218. package/dist/i18n/locales/zh-CN/evolution.json +0 -54
  219. package/dist/i18n/locales/zh-CN/hooks.json +0 -74
  220. package/dist/i18n/locales/zh-CN/hooksSync.json +0 -133
  221. package/dist/i18n/locales/zh-CN/installation.json +0 -83
  222. package/dist/i18n/locales/zh-CN/interview.json +0 -104
  223. package/dist/i18n/locales/zh-CN/language.json +0 -19
  224. package/dist/i18n/locales/zh-CN/lsp.json +0 -78
  225. package/dist/i18n/locales/zh-CN/marketplace.json +0 -116
  226. package/dist/i18n/locales/zh-CN/mcp.json +0 -178
  227. package/dist/i18n/locales/zh-CN/memory.json +0 -92
  228. package/dist/i18n/locales/zh-CN/menu.json +0 -143
  229. package/dist/i18n/locales/zh-CN/multi-config.json +0 -79
  230. package/dist/i18n/locales/zh-CN/notification.json +0 -307
  231. package/dist/i18n/locales/zh-CN/permissions.json +0 -95
  232. package/dist/i18n/locales/zh-CN/persistence.json +0 -127
  233. package/dist/i18n/locales/zh-CN/plugins.json +0 -146
  234. package/dist/i18n/locales/zh-CN/quick-actions.json +0 -78
  235. package/dist/i18n/locales/zh-CN/registry.json +0 -54
  236. package/dist/i18n/locales/zh-CN/remote.json +0 -93
  237. package/dist/i18n/locales/zh-CN/sandbox.json +0 -44
  238. package/dist/i18n/locales/zh-CN/setup.json +0 -44
  239. package/dist/i18n/locales/zh-CN/shencha.json +0 -14
  240. package/dist/i18n/locales/zh-CN/skills.json +0 -100
  241. package/dist/i18n/locales/zh-CN/skillsSync.json +0 -74
  242. package/dist/i18n/locales/zh-CN/smartGuide.json +0 -49
  243. package/dist/i18n/locales/zh-CN/stats.json +0 -20
  244. package/dist/i18n/locales/zh-CN/subagent.json +0 -69
  245. package/dist/i18n/locales/zh-CN/superpowers.json +0 -117
  246. package/dist/i18n/locales/zh-CN/team.json +0 -7
  247. package/dist/i18n/locales/zh-CN/thinking.json +0 -65
  248. package/dist/i18n/locales/zh-CN/tools.json +0 -42
  249. package/dist/i18n/locales/zh-CN/uninstall.json +0 -56
  250. package/dist/i18n/locales/zh-CN/updater.json +0 -29
  251. package/dist/i18n/locales/zh-CN/vim.json +0 -169
  252. package/dist/i18n/locales/zh-CN/workflow.json +0 -55
  253. package/dist/i18n/locales/zh-CN/workspace.json +0 -108
  254. package/dist/index.d.mts +0 -5295
  255. package/dist/index.d.ts +0 -5295
  256. package/dist/index.mjs +0 -4941
  257. package/dist/shared/ccjk.B364Fu0N.mjs +0 -1819
  258. package/dist/shared/ccjk.BAGoDD49.mjs +0 -36
  259. package/dist/shared/ccjk.BBtCGd_g.mjs +0 -899
  260. package/dist/shared/ccjk.BFQ7yr5S.mjs +0 -16
  261. package/dist/shared/ccjk.BFxsJM0k.mjs +0 -599
  262. package/dist/shared/ccjk.BIxuVL3_.mjs +0 -25
  263. package/dist/shared/ccjk.BRZ9ww8S.mjs +0 -142
  264. package/dist/shared/ccjk.BoApaI4j.mjs +0 -28
  265. package/dist/shared/ccjk.BrPUmTqm.mjs +0 -266
  266. package/dist/shared/ccjk.BtB1e5jm.mjs +0 -171
  267. package/dist/shared/ccjk.BwfbSKN2.mjs +0 -1051
  268. package/dist/shared/ccjk.BxSmJ8B7.mjs +0 -243
  269. package/dist/shared/ccjk.Bx_rmYfN.mjs +0 -69
  270. package/dist/shared/ccjk.C2jHOZVP.mjs +0 -52
  271. package/dist/shared/ccjk.CL4Yat0G.mjs +0 -303
  272. package/dist/shared/ccjk.COweQ1RR.mjs +0 -5
  273. package/dist/shared/ccjk.CePkJq2S.mjs +0 -223
  274. package/dist/shared/ccjk.CfKKcvWy.mjs +0 -126
  275. package/dist/shared/ccjk.Cjgrln_h.mjs +0 -297
  276. package/dist/shared/ccjk.Cjj8SVrn.mjs +0 -54
  277. package/dist/shared/ccjk.CxpGa6MC.mjs +0 -2724
  278. package/dist/shared/ccjk.D5MFQT7w.mjs +0 -400
  279. package/dist/shared/ccjk.D6ycHbak.mjs +0 -270
  280. package/dist/shared/ccjk.D8ZLYSZZ.mjs +0 -299
  281. package/dist/shared/ccjk.DG_o24cZ.mjs +0 -88
  282. package/dist/shared/ccjk.DLLw-h4Y.mjs +0 -460
  283. package/dist/shared/ccjk.DOwtZMk8.mjs +0 -4019
  284. package/dist/shared/ccjk.DS7UESmF.mjs +0 -2451
  285. package/dist/shared/ccjk.DTdjs-qK.mjs +0 -1447
  286. package/dist/shared/ccjk.DXRAZcix.mjs +0 -66
  287. package/dist/shared/ccjk.DsYaCCx4.mjs +0 -317
  288. package/dist/shared/ccjk.J8YiPsOw.mjs +0 -259
  289. package/dist/shared/ccjk.KfSWcGlE.mjs +0 -38
  290. package/dist/shared/ccjk.RyizuzOI.mjs +0 -21
  291. package/dist/shared/ccjk.SPoXMvZD.mjs +0 -1242
  292. package/dist/shared/ccjk.T_cX87dY.mjs +0 -15
  293. package/dist/shared/ccjk.UIvifqNE.mjs +0 -1486
  294. package/dist/shared/ccjk._dESH4Rk.mjs +0 -111
  295. package/dist/shared/ccjk.bQ7Dh1g4.mjs +0 -249
  296. package/dist/shared/ccjk.c-ETfBZ_.mjs +0 -617
  297. package/dist/shared/ccjk.gDEDGD_t.mjs +0 -38
  298. package/dist/shared/ccjk.hoqrwWdN.mjs +0 -333
  299. package/dist/shared/ccjk.waa2ikKJ.mjs +0 -351
package/dist/index.mjs DELETED
@@ -1,4941 +0,0 @@
1
- import { a as createCloudClient } from './shared/ccjk.B364Fu0N.mjs';
2
- export { C as CachedCloudClient, b as CloudCache, d as CloudClient, F as FallbackCloudClient, R as RetryableCloudClient, T as TelemetryReporter, c as createCompleteCloudClient, g as getTelemetry, i as initializeTelemetry, r as retryUtils, s as stopTelemetry, t as telemetryUtils, e as trackEvent, w as withRetry } from './shared/ccjk.B364Fu0N.mjs';
3
- export { C as CloudError, a as CloudErrorCode, b as CloudErrorFactory, f as formatErrorForLogging, g as getRetryDelay, h as handleCloudError, i as isAuthError, c as isRateLimitError, d as isRetryableError, e as isRetryableErrorCode } from './shared/ccjk.D8ZLYSZZ.mjs';
4
- export { T as TemplatesClient, a as createTemplatesClient, g as getTemplatesClient } from './shared/ccjk.UIvifqNE.mjs';
5
- import { e as extractString } from './shared/ccjk.C2jHOZVP.mjs';
6
- export { a as extractDisplayName, i as i18nHelpers, n as normalizeRecommendation, b as normalizeRecommendations } from './shared/ccjk.C2jHOZVP.mjs';
7
- import { exec, execSync, spawn } from 'node:child_process';
8
- import { promises, existsSync, readdirSync, readFileSync, statSync, createReadStream } from 'node:fs';
9
- import * as os from 'node:os';
10
- import { homedir } from 'node:os';
11
- import * as path from 'node:path';
12
- import { promisify } from 'node:util';
13
- import a from './chunks/index2.mjs';
14
- import { g as getRuntimeVersion } from './shared/ccjk.gDEDGD_t.mjs';
15
- import { j as join$1 } from './shared/ccjk.bQ7Dh1g4.mjs';
16
- export { j as config } from './chunks/config.mjs';
17
- export { a as loggerUtils } from './shared/ccjk.DG_o24cZ.mjs';
18
- export { p as platform } from './chunks/platform.mjs';
19
- import { Transform } from 'node:stream';
20
- import { pipeline } from 'node:stream/promises';
21
- import 'node:url';
22
- import 'node:crypto';
23
- import './chunks/index5.mjs';
24
- import 'node:process';
25
- import './shared/ccjk.BAGoDD49.mjs';
26
- import './shared/ccjk.RyizuzOI.mjs';
27
- import './chunks/index3.mjs';
28
- import 'node:readline';
29
- import 'stream';
30
- import 'node:tty';
31
- import 'node:async_hooks';
32
- import './shared/ccjk.Cjgrln_h.mjs';
33
- import 'tty';
34
- import 'fs';
35
- import 'child_process';
36
- import 'buffer';
37
- import 'string_decoder';
38
- import './chunks/constants.mjs';
39
- import './chunks/claude-config.mjs';
40
- import './chunks/json-config.mjs';
41
- import './chunks/fs-operations.mjs';
42
- import 'node:fs/promises';
43
- import './shared/ccjk.DXRAZcix.mjs';
44
- import './chunks/main.mjs';
45
- import 'module';
46
-
47
- const execAsync$1 = promisify(exec);
48
- class BaseCodeTool {
49
- config;
50
- configPath;
51
- constructor(initialConfig) {
52
- this.config = {
53
- name: this.getMetadata().name,
54
- ...initialConfig
55
- };
56
- this.configPath = this.getDefaultConfigPath();
57
- }
58
- /**
59
- * Get the default configuration path for this tool
60
- */
61
- getDefaultConfigPath() {
62
- const homeDir = os.homedir();
63
- const configDir = path.join(homeDir, ".ccjk", "tools");
64
- return path.join(configDir, `${this.getMetadata().name}.json`);
65
- }
66
- /**
67
- * Check if the tool is installed
68
- */
69
- async isInstalled() {
70
- try {
71
- const command = this.getInstallCheckCommand();
72
- const { stdout, stderr } = await execAsync$1(command);
73
- const version = this.parseVersion(stdout || stderr);
74
- return {
75
- installed: true,
76
- version,
77
- path: await this.findToolPath()
78
- };
79
- } catch (error) {
80
- return {
81
- installed: false,
82
- error: error instanceof Error ? error.message : "Unknown error"
83
- };
84
- }
85
- }
86
- /**
87
- * Install the tool
88
- */
89
- async install() {
90
- try {
91
- const command = this.getInstallCommand();
92
- const { stdout, stderr } = await execAsync$1(command);
93
- return {
94
- success: true,
95
- output: stdout || stderr,
96
- exitCode: 0
97
- };
98
- } catch (error) {
99
- return {
100
- success: false,
101
- error: error instanceof Error ? error.message : "Installation failed",
102
- exitCode: 1
103
- };
104
- }
105
- }
106
- /**
107
- * Uninstall the tool
108
- */
109
- async uninstall() {
110
- try {
111
- const command = this.getUninstallCommand();
112
- const { stdout, stderr } = await execAsync$1(command);
113
- await this.removeConfigFile();
114
- return {
115
- success: true,
116
- output: stdout || stderr,
117
- exitCode: 0
118
- };
119
- } catch (error) {
120
- return {
121
- success: false,
122
- error: error instanceof Error ? error.message : "Uninstallation failed",
123
- exitCode: 1
124
- };
125
- }
126
- }
127
- /**
128
- * Get current configuration
129
- */
130
- async getConfig() {
131
- try {
132
- await this.loadConfig();
133
- return { ...this.config };
134
- } catch (_error) {
135
- return { ...this.config };
136
- }
137
- }
138
- /**
139
- * Update configuration
140
- */
141
- async updateConfig(updates) {
142
- this.config = {
143
- ...this.config,
144
- ...updates
145
- };
146
- await this.saveConfig();
147
- }
148
- /**
149
- * Configure the tool with full config
150
- */
151
- async configure(config) {
152
- const isValid = await this.validateConfig(config);
153
- if (!isValid) {
154
- throw new Error("Invalid configuration");
155
- }
156
- this.config = { ...config };
157
- await this.saveConfig();
158
- }
159
- /**
160
- * Validate configuration
161
- */
162
- async validateConfig(config) {
163
- if (!config.name) {
164
- return false;
165
- }
166
- return true;
167
- }
168
- /**
169
- * Execute a command with the tool
170
- */
171
- async execute(command, args = []) {
172
- try {
173
- const fullCommand = this.buildCommand(command, args);
174
- const { stdout, stderr } = await execAsync$1(fullCommand, {
175
- env: { ...process.env, ...this.config.env }
176
- });
177
- return {
178
- success: true,
179
- output: stdout || stderr,
180
- exitCode: 0
181
- };
182
- } catch (error) {
183
- return {
184
- success: false,
185
- error: error.message || "Execution failed",
186
- exitCode: error.code || 1
187
- };
188
- }
189
- }
190
- /**
191
- * Get tool version
192
- */
193
- async getVersion() {
194
- const status = await this.isInstalled();
195
- return status.version;
196
- }
197
- /**
198
- * Reset tool to default configuration
199
- */
200
- async reset() {
201
- this.config = {
202
- name: this.getMetadata().name
203
- };
204
- await this.removeConfigFile();
205
- }
206
- /**
207
- * Load configuration from file
208
- */
209
- async loadConfig() {
210
- try {
211
- const data = await promises.readFile(this.configPath, "utf-8");
212
- const loadedConfig = JSON.parse(data);
213
- this.config = { ...this.config, ...loadedConfig };
214
- } catch (_error) {
215
- }
216
- }
217
- /**
218
- * Save configuration to file
219
- */
220
- async saveConfig() {
221
- try {
222
- const configDir = path.dirname(this.configPath);
223
- await promises.mkdir(configDir, { recursive: true });
224
- await promises.writeFile(this.configPath, JSON.stringify(this.config, null, 2));
225
- } catch (error) {
226
- throw new Error(`Failed to save configuration: ${error}`);
227
- }
228
- }
229
- /**
230
- * Remove configuration file
231
- */
232
- async removeConfigFile() {
233
- try {
234
- await promises.unlink(this.configPath);
235
- } catch (_error) {
236
- }
237
- }
238
- /**
239
- * Build command string from command and arguments
240
- */
241
- buildCommand(command, args) {
242
- const escapedArgs = args.map((arg) => {
243
- return arg.includes(" ") ? `"${arg}"` : arg;
244
- });
245
- return [command, ...escapedArgs].join(" ");
246
- }
247
- /**
248
- * Parse version from command output
249
- */
250
- parseVersion(output) {
251
- const patterns = [
252
- /version\s+(\d+\.\d+\.\d+)/i,
253
- /v?(\d+\.\d+\.\d+)/,
254
- /(\d+\.\d+\.\d+)/
255
- ];
256
- for (const pattern of patterns) {
257
- const match = output.match(pattern);
258
- if (match) {
259
- return match[1];
260
- }
261
- }
262
- return void 0;
263
- }
264
- /**
265
- * Find the tool's installation path
266
- */
267
- async findToolPath() {
268
- try {
269
- const { stdout } = await execAsync$1(`which ${this.getMetadata().name}`);
270
- return stdout.trim();
271
- } catch (_error) {
272
- return void 0;
273
- }
274
- }
275
- /**
276
- * Create default capabilities object
277
- */
278
- createDefaultCapabilities() {
279
- return {
280
- supportsChat: false,
281
- supportsFileEdit: false,
282
- supportsCodeGen: false,
283
- supportsReview: false,
284
- supportsTesting: false,
285
- supportsDebugging: false
286
- };
287
- }
288
- }
289
-
290
- class AiderTool extends BaseCodeTool {
291
- getMetadata() {
292
- return {
293
- name: "aider",
294
- displayName: "Aider",
295
- description: "AI pair programming in your terminal",
296
- version: "1.0.0",
297
- homepage: "https://aider.chat",
298
- documentation: "https://aider.chat/docs",
299
- capabilities: {
300
- supportsChat: true,
301
- supportsFileEdit: true,
302
- supportsCodeGen: true,
303
- supportsReview: true,
304
- supportsTesting: false,
305
- supportsDebugging: true
306
- }
307
- };
308
- }
309
- getInstallCheckCommand() {
310
- return "aider --version";
311
- }
312
- getInstallCommand() {
313
- return "pip install aider-chat";
314
- }
315
- getUninstallCommand() {
316
- return "pip uninstall -y aider-chat";
317
- }
318
- /**
319
- * Start a chat session
320
- */
321
- async chat(prompt) {
322
- return this.execute("aider", ["--message", prompt]);
323
- }
324
- /**
325
- * Continue a chat session
326
- */
327
- async continueChat(message) {
328
- return this.execute("aider", ["--message", message]);
329
- }
330
- /**
331
- * End chat session
332
- */
333
- async endChat() {
334
- await this.execute("aider", ["--exit"]);
335
- }
336
- /**
337
- * Edit a file
338
- */
339
- async editFile(filePath, instructions) {
340
- return this.execute("aider", [filePath, "--message", instructions]);
341
- }
342
- /**
343
- * Edit multiple files
344
- */
345
- async editFiles(files, instructions) {
346
- return this.execute("aider", [...files, "--message", instructions]);
347
- }
348
- }
349
-
350
- class ClaudeCodeTool extends BaseCodeTool {
351
- getMetadata() {
352
- return {
353
- name: "claude-code",
354
- displayName: "Claude Code",
355
- description: "Anthropic's official CLI tool for Claude AI",
356
- version: "1.0.0",
357
- homepage: "https://claude.ai",
358
- documentation: "https://docs.anthropic.com/claude/docs",
359
- capabilities: {
360
- supportsChat: true,
361
- supportsFileEdit: true,
362
- supportsCodeGen: true,
363
- supportsReview: true,
364
- supportsTesting: true,
365
- supportsDebugging: true
366
- }
367
- };
368
- }
369
- getInstallCheckCommand() {
370
- return "claude --version";
371
- }
372
- getInstallCommand() {
373
- return "npm install -g @anthropic-ai/claude-code";
374
- }
375
- getUninstallCommand() {
376
- return "npm uninstall -g @anthropic-ai/claude-code";
377
- }
378
- /**
379
- * Start a chat session
380
- */
381
- async chat(prompt) {
382
- return this.execute("claude", ["chat", prompt]);
383
- }
384
- /**
385
- * Continue a chat session
386
- */
387
- async continueChat(message) {
388
- return this.execute("claude", ["continue", message]);
389
- }
390
- /**
391
- * End chat session
392
- */
393
- async endChat() {
394
- await this.execute("claude", ["exit"]);
395
- }
396
- /**
397
- * Edit a file
398
- */
399
- async editFile(filePath, instructions) {
400
- return this.execute("claude", ["edit", filePath, "--instructions", instructions]);
401
- }
402
- /**
403
- * Edit multiple files
404
- */
405
- async editFiles(files, instructions) {
406
- const fileArgs = files.flatMap((f) => ["--file", f]);
407
- return this.execute("claude", ["edit", ...fileArgs, "--instructions", instructions]);
408
- }
409
- /**
410
- * Generate code
411
- */
412
- async generateCode(prompt, outputPath) {
413
- const args = ["generate", prompt];
414
- if (outputPath) {
415
- args.push("--output", outputPath);
416
- }
417
- return this.execute("claude", args);
418
- }
419
- }
420
-
421
- class ClineTool extends BaseCodeTool {
422
- getMetadata() {
423
- return {
424
- name: "cline",
425
- displayName: "Cline",
426
- description: "Autonomous coding agent for VS Code",
427
- version: "1.0.0",
428
- homepage: "https://github.com/cline/cline",
429
- documentation: "https://github.com/cline/cline/wiki",
430
- capabilities: {
431
- supportsChat: true,
432
- supportsFileEdit: true,
433
- supportsCodeGen: true,
434
- supportsReview: true,
435
- supportsTesting: true,
436
- supportsDebugging: true
437
- }
438
- };
439
- }
440
- getInstallCheckCommand() {
441
- return "cline --version";
442
- }
443
- getInstallCommand() {
444
- return "npm install -g cline";
445
- }
446
- getUninstallCommand() {
447
- return "npm uninstall -g cline";
448
- }
449
- /**
450
- * Start a chat session
451
- */
452
- async chat(prompt) {
453
- return this.execute("cline", ["chat", prompt]);
454
- }
455
- /**
456
- * Continue a chat session
457
- */
458
- async continueChat(message) {
459
- return this.execute("cline", ["continue", message]);
460
- }
461
- /**
462
- * End chat session
463
- */
464
- async endChat() {
465
- await this.execute("cline", ["exit"]);
466
- }
467
- /**
468
- * Edit a file
469
- */
470
- async editFile(filePath, instructions) {
471
- return this.execute("cline", ["edit", filePath, "--instructions", instructions]);
472
- }
473
- /**
474
- * Edit multiple files
475
- */
476
- async editFiles(files, instructions) {
477
- const fileArgs = files.flatMap((f) => ["--file", f]);
478
- return this.execute("cline", ["edit", ...fileArgs, "--instructions", instructions]);
479
- }
480
- /**
481
- * Generate code
482
- */
483
- async generateCode(prompt, outputPath) {
484
- const args = ["generate", prompt];
485
- if (outputPath) {
486
- args.push("--output", outputPath);
487
- }
488
- return this.execute("cline", args);
489
- }
490
- }
491
-
492
- class CodexTool extends BaseCodeTool {
493
- getMetadata() {
494
- return {
495
- name: "codex",
496
- displayName: "OpenAI Codex",
497
- description: "OpenAI's code generation model",
498
- version: "1.0.0",
499
- homepage: "https://openai.com/codex",
500
- documentation: "https://platform.openai.com/docs",
501
- capabilities: {
502
- supportsChat: true,
503
- supportsFileEdit: false,
504
- supportsCodeGen: true,
505
- supportsReview: false,
506
- supportsTesting: false,
507
- supportsDebugging: false
508
- }
509
- };
510
- }
511
- getInstallCheckCommand() {
512
- return "codex --version";
513
- }
514
- getInstallCommand() {
515
- return "pip install openai-codex";
516
- }
517
- getUninstallCommand() {
518
- return "pip uninstall -y openai-codex";
519
- }
520
- /**
521
- * Generate code
522
- */
523
- async generateCode(prompt, outputPath) {
524
- const args = ["generate", prompt];
525
- if (outputPath) {
526
- args.push("--output", outputPath);
527
- }
528
- return this.execute("codex", args);
529
- }
530
- }
531
-
532
- class ContinueTool extends BaseCodeTool {
533
- getMetadata() {
534
- return {
535
- name: "continue",
536
- displayName: "Continue",
537
- description: "Open-source autopilot for software development",
538
- version: "1.0.0",
539
- homepage: "https://continue.dev",
540
- documentation: "https://continue.dev/docs",
541
- capabilities: {
542
- supportsChat: true,
543
- supportsFileEdit: true,
544
- supportsCodeGen: true,
545
- supportsReview: true,
546
- supportsTesting: true,
547
- supportsDebugging: true
548
- }
549
- };
550
- }
551
- getInstallCheckCommand() {
552
- return "continue --version";
553
- }
554
- getInstallCommand() {
555
- return "npm install -g continue";
556
- }
557
- getUninstallCommand() {
558
- return "npm uninstall -g continue";
559
- }
560
- /**
561
- * Start a chat session
562
- */
563
- async chat(prompt) {
564
- return this.execute("continue", ["chat", prompt]);
565
- }
566
- /**
567
- * Continue a chat session
568
- */
569
- async continueChat(message) {
570
- return this.execute("continue", ["chat", message]);
571
- }
572
- /**
573
- * End chat session
574
- */
575
- async endChat() {
576
- await this.execute("continue", ["exit"]);
577
- }
578
- /**
579
- * Generate code
580
- */
581
- async generateCode(prompt, outputPath) {
582
- const args = ["generate", prompt];
583
- if (outputPath) {
584
- args.push("--output", outputPath);
585
- }
586
- return this.execute("continue", args);
587
- }
588
- }
589
-
590
- class CursorTool extends BaseCodeTool {
591
- getMetadata() {
592
- return {
593
- name: "cursor",
594
- displayName: "Cursor",
595
- description: "AI-first code editor",
596
- version: "1.0.0",
597
- homepage: "https://cursor.sh",
598
- documentation: "https://cursor.sh/docs",
599
- capabilities: {
600
- supportsChat: true,
601
- supportsFileEdit: true,
602
- supportsCodeGen: true,
603
- supportsReview: true,
604
- supportsTesting: true,
605
- supportsDebugging: true
606
- }
607
- };
608
- }
609
- getInstallCheckCommand() {
610
- return "cursor --version";
611
- }
612
- getInstallCommand() {
613
- return 'echo "Please download Cursor from https://cursor.sh"';
614
- }
615
- getUninstallCommand() {
616
- return 'echo "Please uninstall Cursor manually"';
617
- }
618
- /**
619
- * Start a chat session
620
- */
621
- async chat(prompt) {
622
- return this.execute("cursor", ["chat", prompt]);
623
- }
624
- /**
625
- * Continue a chat session
626
- */
627
- async continueChat(message) {
628
- return this.execute("cursor", ["chat", message]);
629
- }
630
- /**
631
- * End chat session
632
- */
633
- async endChat() {
634
- await this.execute("cursor", ["exit"]);
635
- }
636
- /**
637
- * Edit a file
638
- */
639
- async editFile(filePath, instructions) {
640
- return this.execute("cursor", ["edit", filePath, "--instructions", instructions]);
641
- }
642
- /**
643
- * Edit multiple files
644
- */
645
- async editFiles(files, instructions) {
646
- const fileArgs = files.flatMap((f) => ["--file", f]);
647
- return this.execute("cursor", ["edit", ...fileArgs, "--instructions", instructions]);
648
- }
649
- /**
650
- * Generate code
651
- */
652
- async generateCode(prompt, outputPath) {
653
- const args = ["generate", prompt];
654
- if (outputPath) {
655
- args.push("--output", outputPath);
656
- }
657
- return this.execute("cursor", args);
658
- }
659
- }
660
-
661
- class ToolRegistry {
662
- static instance;
663
- tools;
664
- toolClasses;
665
- constructor() {
666
- this.tools = /* @__PURE__ */ new Map();
667
- this.toolClasses = /* @__PURE__ */ new Map();
668
- }
669
- /**
670
- * Get singleton instance
671
- */
672
- static getInstance() {
673
- if (!ToolRegistry.instance) {
674
- ToolRegistry.instance = new ToolRegistry();
675
- }
676
- return ToolRegistry.instance;
677
- }
678
- /**
679
- * Register a tool class
680
- */
681
- registerToolClass(name, toolClass) {
682
- this.toolClasses.set(name.toLowerCase(), toolClass);
683
- }
684
- /**
685
- * Register a tool instance
686
- */
687
- registerTool(tool) {
688
- const metadata = tool.getMetadata();
689
- this.tools.set(metadata.name.toLowerCase(), tool);
690
- }
691
- /**
692
- * Get a tool instance by name
693
- */
694
- getTool(name) {
695
- const normalizedName = name.toLowerCase();
696
- if (this.tools.has(normalizedName)) {
697
- return this.tools.get(normalizedName);
698
- }
699
- const ToolClass = this.toolClasses.get(normalizedName);
700
- if (ToolClass) {
701
- const tool = new ToolClass();
702
- this.tools.set(normalizedName, tool);
703
- return tool;
704
- }
705
- return void 0;
706
- }
707
- /**
708
- * Get all registered tool names
709
- */
710
- getToolNames() {
711
- return Array.from(this.toolClasses.keys());
712
- }
713
- /**
714
- * Get all tool instances
715
- */
716
- getAllTools() {
717
- return Array.from(this.tools.values());
718
- }
719
- /**
720
- * Check if a tool is registered
721
- */
722
- hasTool(name) {
723
- return this.toolClasses.has(name.toLowerCase());
724
- }
725
- /**
726
- * Unregister a tool
727
- */
728
- unregisterTool(name) {
729
- const normalizedName = name.toLowerCase();
730
- this.tools.delete(normalizedName);
731
- this.toolClasses.delete(normalizedName);
732
- }
733
- /**
734
- * Clear all registered tools
735
- */
736
- clear() {
737
- this.tools.clear();
738
- this.toolClasses.clear();
739
- }
740
- /**
741
- * Get metadata for all registered tools
742
- */
743
- async getAllMetadata() {
744
- const metadata = [];
745
- for (const name of this.toolClasses.keys()) {
746
- const tool = this.getTool(name);
747
- if (tool) {
748
- metadata.push(tool.getMetadata());
749
- }
750
- }
751
- return metadata;
752
- }
753
- }
754
- function getRegistry() {
755
- return ToolRegistry.getInstance();
756
- }
757
-
758
- class ToolFactory {
759
- registry;
760
- constructor(registry) {
761
- this.registry = registry || ToolRegistry.getInstance();
762
- }
763
- /**
764
- * Create a tool instance by name
765
- */
766
- createTool(name, config) {
767
- const tool = this.registry.getTool(name);
768
- if (!tool) {
769
- throw new Error(`Tool '${name}' not found in registry. Available tools: ${this.registry.getToolNames().join(", ")}`);
770
- }
771
- if (config) {
772
- tool.configure({ name, ...config }).catch((err) => {
773
- console.warn(`Failed to configure tool '${name}':`, err);
774
- });
775
- }
776
- return tool;
777
- }
778
- /**
779
- * Create multiple tool instances
780
- */
781
- createTools(names) {
782
- return names.map((name) => this.createTool(name));
783
- }
784
- /**
785
- * Create all registered tools
786
- */
787
- createAllTools() {
788
- const names = this.registry.getToolNames();
789
- return this.createTools(names);
790
- }
791
- /**
792
- * Check if a tool can be created
793
- */
794
- canCreateTool(name) {
795
- return this.registry.hasTool(name);
796
- }
797
- /**
798
- * Get available tool names
799
- */
800
- getAvailableTools() {
801
- return this.registry.getToolNames();
802
- }
803
- }
804
- function createTool(name, config) {
805
- const factory = new ToolFactory();
806
- return factory.createTool(name, config);
807
- }
808
-
809
- function unique(arr) {
810
- return [...new Set(arr)];
811
- }
812
- function uniqueBy(arr, key) {
813
- const seen = /* @__PURE__ */ new Set();
814
- return arr.filter((item) => {
815
- const value = typeof key === "function" ? key(item) : item[key];
816
- if (seen.has(value)) {
817
- return false;
818
- }
819
- seen.add(value);
820
- return true;
821
- });
822
- }
823
- function flatten$1(arr, depth = Infinity) {
824
- if (depth === 0)
825
- return arr;
826
- return arr.reduce((acc, val) => {
827
- if (Array.isArray(val)) {
828
- acc.push(...flatten$1(val, depth - 1));
829
- } else {
830
- acc.push(val);
831
- }
832
- return acc;
833
- }, []);
834
- }
835
- function chunk(arr, size) {
836
- const chunks = [];
837
- for (let i = 0; i < arr.length; i += size) {
838
- chunks.push(arr.slice(i, i + size));
839
- }
840
- return chunks;
841
- }
842
- function shuffle(arr) {
843
- const result = [...arr];
844
- for (let i = result.length - 1; i > 0; i--) {
845
- const j = Math.floor(Math.random() * (i + 1));
846
- [result[i], result[j]] = [result[j], result[i]];
847
- }
848
- return result;
849
- }
850
- function sample(arr) {
851
- return arr[Math.floor(Math.random() * arr.length)];
852
- }
853
- function sampleSize(arr, size) {
854
- const shuffled = shuffle(arr);
855
- return shuffled.slice(0, Math.min(size, arr.length));
856
- }
857
- function partition(arr, predicate) {
858
- const truthy = [];
859
- const falsy = [];
860
- for (const item of arr) {
861
- if (predicate(item)) {
862
- truthy.push(item);
863
- } else {
864
- falsy.push(item);
865
- }
866
- }
867
- return [truthy, falsy];
868
- }
869
- function intersection(...arrays) {
870
- if (arrays.length === 0)
871
- return [];
872
- if (arrays.length === 1)
873
- return arrays[0];
874
- const [first, ...rest] = arrays;
875
- return first.filter((item) => rest.every((arr) => arr.includes(item)));
876
- }
877
- function union(...arrays) {
878
- return unique(flatten$1(arrays, 1));
879
- }
880
- function difference(arr, ...others) {
881
- const otherItems = new Set(flatten$1(others, 1));
882
- return arr.filter((item) => !otherItems.has(item));
883
- }
884
- function zip(...arrays) {
885
- const maxLength = Math.max(...arrays.map((arr) => arr.length));
886
- const result = [];
887
- for (let i = 0; i < maxLength; i++) {
888
- result.push(arrays.map((arr) => arr[i]));
889
- }
890
- return result;
891
- }
892
- function unzip(arr) {
893
- return zip(...arr);
894
- }
895
- function groupConsecutive(arr, predicate) {
896
- if (arr.length === 0)
897
- return [];
898
- const groups = [[arr[0]]];
899
- for (let i = 1; i < arr.length; i++) {
900
- const lastGroup = groups[groups.length - 1];
901
- const lastItem = lastGroup[lastGroup.length - 1];
902
- if (predicate(lastItem, arr[i])) {
903
- lastGroup.push(arr[i]);
904
- } else {
905
- groups.push([arr[i]]);
906
- }
907
- }
908
- return groups;
909
- }
910
- function take(arr, n) {
911
- return arr.slice(0, n);
912
- }
913
- function takeLast(arr, n) {
914
- return arr.slice(-n);
915
- }
916
- function drop(arr, n) {
917
- return arr.slice(n);
918
- }
919
- function dropLast(arr, n) {
920
- return arr.slice(0, -n);
921
- }
922
- function takeWhile(arr, predicate) {
923
- const result = [];
924
- for (const item of arr) {
925
- if (!predicate(item))
926
- break;
927
- result.push(item);
928
- }
929
- return result;
930
- }
931
- function dropWhile(arr, predicate) {
932
- let dropping = true;
933
- return arr.filter((item) => {
934
- if (dropping && predicate(item)) {
935
- return false;
936
- }
937
- dropping = false;
938
- return true;
939
- });
940
- }
941
- function findIndex(arr, predicate) {
942
- return arr.findIndex(predicate);
943
- }
944
- function findLastIndex(arr, predicate) {
945
- for (let i = arr.length - 1; i >= 0; i--) {
946
- if (predicate(arr[i])) {
947
- return i;
948
- }
949
- }
950
- return -1;
951
- }
952
- function count(arr, item) {
953
- return arr.filter((x) => x === item).length;
954
- }
955
- function countBy(arr, predicate) {
956
- return arr.filter(predicate).length;
957
- }
958
- function sum(arr) {
959
- return arr.reduce((acc, val) => acc + val, 0);
960
- }
961
- function sumBy(arr, selector) {
962
- return arr.reduce((acc, item) => {
963
- const value = typeof selector === "function" ? selector(item) : item[selector];
964
- return acc + (typeof value === "number" ? value : 0);
965
- }, 0);
966
- }
967
- function average(arr) {
968
- return arr.length === 0 ? 0 : sum(arr) / arr.length;
969
- }
970
- function min(arr) {
971
- return arr.length === 0 ? void 0 : Math.min(...arr);
972
- }
973
- function max(arr) {
974
- return arr.length === 0 ? void 0 : Math.max(...arr);
975
- }
976
- function minBy(arr, selector) {
977
- if (arr.length === 0)
978
- return void 0;
979
- return arr.reduce((min2, item) => {
980
- const minValue = typeof selector === "function" ? selector(min2) : min2[selector];
981
- const itemValue = typeof selector === "function" ? selector(item) : item[selector];
982
- return itemValue < minValue ? item : min2;
983
- });
984
- }
985
- function maxBy(arr, selector) {
986
- if (arr.length === 0)
987
- return void 0;
988
- return arr.reduce((max2, item) => {
989
- const maxValue = typeof selector === "function" ? selector(max2) : max2[selector];
990
- const itemValue = typeof selector === "function" ? selector(item) : item[selector];
991
- return itemValue > maxValue ? item : max2;
992
- });
993
- }
994
- function sortBy(arr, selector, order = "asc") {
995
- const sorted = [...arr].sort((a, b) => {
996
- const aValue = typeof selector === "function" ? selector(a) : a[selector];
997
- const bValue = typeof selector === "function" ? selector(b) : b[selector];
998
- if (aValue < bValue)
999
- return order === "asc" ? -1 : 1;
1000
- if (aValue > bValue)
1001
- return order === "asc" ? 1 : -1;
1002
- return 0;
1003
- });
1004
- return sorted;
1005
- }
1006
- function isEmpty$1(arr) {
1007
- return arr.length === 0;
1008
- }
1009
- function compact$1(arr) {
1010
- return arr.filter((item) => !!item);
1011
- }
1012
- function range(start, end, step = 1) {
1013
- if (end === void 0) {
1014
- end = start;
1015
- start = 0;
1016
- }
1017
- const result = [];
1018
- for (let i = start; i < end; i += step) {
1019
- result.push(i);
1020
- }
1021
- return result;
1022
- }
1023
- function rotate(arr, n) {
1024
- const len = arr.length;
1025
- if (len === 0)
1026
- return arr;
1027
- n = (n % len + len) % len;
1028
- return [...arr.slice(n), ...arr.slice(0, n)];
1029
- }
1030
- function isEqual$1(arr1, arr2) {
1031
- if (arr1.length !== arr2.length)
1032
- return false;
1033
- return arr1.every((item, index) => item === arr2[index]);
1034
- }
1035
-
1036
- const index$6 = {
1037
- __proto__: null,
1038
- average: average,
1039
- chunk: chunk,
1040
- compact: compact$1,
1041
- count: count,
1042
- countBy: countBy,
1043
- difference: difference,
1044
- drop: drop,
1045
- dropLast: dropLast,
1046
- dropWhile: dropWhile,
1047
- findIndex: findIndex,
1048
- findLastIndex: findLastIndex,
1049
- flatten: flatten$1,
1050
- groupConsecutive: groupConsecutive,
1051
- intersection: intersection,
1052
- isEmpty: isEmpty$1,
1053
- isEqual: isEqual$1,
1054
- max: max,
1055
- maxBy: maxBy,
1056
- min: min,
1057
- minBy: minBy,
1058
- partition: partition,
1059
- range: range,
1060
- rotate: rotate,
1061
- sample: sample,
1062
- sampleSize: sampleSize,
1063
- shuffle: shuffle,
1064
- sortBy: sortBy,
1065
- sum: sum,
1066
- sumBy: sumBy,
1067
- take: take,
1068
- takeLast: takeLast,
1069
- takeWhile: takeWhile,
1070
- union: union,
1071
- unique: unique,
1072
- uniqueBy: uniqueBy,
1073
- unzip: unzip,
1074
- zip: zip
1075
- };
1076
-
1077
- function sleep(ms) {
1078
- return new Promise((resolve) => setTimeout(resolve, ms));
1079
- }
1080
- async function retry(fn, options = {}) {
1081
- const {
1082
- maxAttempts = 3,
1083
- delay = 1e3,
1084
- backoff = 2,
1085
- onRetry
1086
- } = options;
1087
- let lastError;
1088
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
1089
- try {
1090
- return await fn();
1091
- } catch (error) {
1092
- lastError = error;
1093
- if (attempt < maxAttempts) {
1094
- if (onRetry) {
1095
- onRetry(lastError, attempt);
1096
- }
1097
- const waitTime = delay * backoff ** (attempt - 1);
1098
- await sleep(waitTime);
1099
- }
1100
- }
1101
- }
1102
- throw lastError;
1103
- }
1104
- async function timeout(promise, ms, errorMessage = "Operation timed out") {
1105
- let timeoutId;
1106
- const timeoutPromise = new Promise((_, reject) => {
1107
- timeoutId = setTimeout(() => reject(new Error(errorMessage)), ms);
1108
- });
1109
- try {
1110
- return await Promise.race([promise, timeoutPromise]);
1111
- } finally {
1112
- clearTimeout(timeoutId);
1113
- }
1114
- }
1115
- function debounce(fn, delay) {
1116
- let timeoutId = null;
1117
- let pendingPromise = null;
1118
- return (...args) => {
1119
- if (timeoutId) {
1120
- clearTimeout(timeoutId);
1121
- }
1122
- if (!pendingPromise) {
1123
- pendingPromise = new Promise((resolve, reject) => {
1124
- timeoutId = setTimeout(async () => {
1125
- try {
1126
- const result = await fn(...args);
1127
- resolve(result);
1128
- } catch (error) {
1129
- reject(error);
1130
- } finally {
1131
- pendingPromise = null;
1132
- timeoutId = null;
1133
- }
1134
- }, delay);
1135
- });
1136
- }
1137
- return pendingPromise;
1138
- };
1139
- }
1140
- function throttle(fn, delay) {
1141
- let lastCall = 0;
1142
- let pendingPromise = null;
1143
- return (...args) => {
1144
- const now = Date.now();
1145
- if (now - lastCall >= delay) {
1146
- lastCall = now;
1147
- pendingPromise = fn(...args);
1148
- return pendingPromise;
1149
- }
1150
- if (!pendingPromise) {
1151
- pendingPromise = new Promise((resolve, reject) => {
1152
- setTimeout(async () => {
1153
- lastCall = Date.now();
1154
- try {
1155
- const result = await fn(...args);
1156
- resolve(result);
1157
- } catch (error) {
1158
- reject(error);
1159
- } finally {
1160
- pendingPromise = null;
1161
- }
1162
- }, delay - (now - lastCall));
1163
- });
1164
- }
1165
- return pendingPromise;
1166
- };
1167
- }
1168
- async function parallelLimit(tasks, limit) {
1169
- const results = [];
1170
- const executing = [];
1171
- for (const [index, task] of tasks.entries()) {
1172
- const promise = task().then((result) => {
1173
- results[index] = result;
1174
- });
1175
- executing.push(promise);
1176
- if (executing.length >= limit) {
1177
- await Promise.race(executing);
1178
- executing.splice(
1179
- executing.findIndex((p) => p === promise),
1180
- 1
1181
- );
1182
- }
1183
- }
1184
- await Promise.all(executing);
1185
- return results;
1186
- }
1187
- async function sequence(tasks) {
1188
- const results = [];
1189
- for (const task of tasks) {
1190
- results.push(await task());
1191
- }
1192
- return results;
1193
- }
1194
- async function allSettled(promises) {
1195
- return Promise.allSettled(promises);
1196
- }
1197
- async function raceWithTimeout(promises, ms) {
1198
- return timeout(Promise.race(promises), ms);
1199
- }
1200
- function memoize(fn, options = {}) {
1201
- const cache = /* @__PURE__ */ new Map();
1202
- const { keyGenerator = (...args) => JSON.stringify(args), ttl } = options;
1203
- return (async (...args) => {
1204
- const key = keyGenerator(...args);
1205
- const cached = cache.get(key);
1206
- if (cached) {
1207
- if (!ttl || Date.now() - cached.timestamp < ttl) {
1208
- return cached.value;
1209
- }
1210
- cache.delete(key);
1211
- }
1212
- const value = await fn(...args);
1213
- cache.set(key, { value, timestamp: Date.now() });
1214
- return value;
1215
- });
1216
- }
1217
- function defer() {
1218
- let resolve;
1219
- let reject;
1220
- const promise = new Promise((res, rej) => {
1221
- resolve = res;
1222
- reject = rej;
1223
- });
1224
- return { promise, resolve, reject };
1225
- }
1226
- async function waitFor(condition, options = {}) {
1227
- const {
1228
- timeout: timeoutMs = 5e3,
1229
- interval = 100,
1230
- timeoutMessage = "Condition not met within timeout"
1231
- } = options;
1232
- const startTime = Date.now();
1233
- while (true) {
1234
- const result = await condition();
1235
- if (result)
1236
- return;
1237
- if (Date.now() - startTime >= timeoutMs) {
1238
- throw new Error(timeoutMessage);
1239
- }
1240
- await sleep(interval);
1241
- }
1242
- }
1243
- class Mutex {
1244
- locked = false;
1245
- queue = [];
1246
- async acquire() {
1247
- if (!this.locked) {
1248
- this.locked = true;
1249
- return;
1250
- }
1251
- return new Promise((resolve) => {
1252
- this.queue.push(resolve);
1253
- });
1254
- }
1255
- release() {
1256
- if (this.queue.length > 0) {
1257
- const resolve = this.queue.shift();
1258
- resolve();
1259
- } else {
1260
- this.locked = false;
1261
- }
1262
- }
1263
- async runExclusive(fn) {
1264
- await this.acquire();
1265
- try {
1266
- return await fn();
1267
- } finally {
1268
- this.release();
1269
- }
1270
- }
1271
- }
1272
- class Semaphore {
1273
- permits;
1274
- queue = [];
1275
- constructor(permits) {
1276
- this.permits = permits;
1277
- }
1278
- async acquire() {
1279
- if (this.permits > 0) {
1280
- this.permits--;
1281
- return;
1282
- }
1283
- return new Promise((resolve) => {
1284
- this.queue.push(resolve);
1285
- });
1286
- }
1287
- release() {
1288
- if (this.queue.length > 0) {
1289
- const resolve = this.queue.shift();
1290
- resolve();
1291
- } else {
1292
- this.permits++;
1293
- }
1294
- }
1295
- async runExclusive(fn) {
1296
- await this.acquire();
1297
- try {
1298
- return await fn();
1299
- } finally {
1300
- this.release();
1301
- }
1302
- }
1303
- }
1304
- async function batch(items, batchSize, processor) {
1305
- const results = [];
1306
- for (let i = 0; i < items.length; i += batchSize) {
1307
- const batch2 = items.slice(i, i + batchSize);
1308
- const batchResults = await processor(batch2);
1309
- results.push(...batchResults);
1310
- }
1311
- return results;
1312
- }
1313
- async function poll(fn, options = {}) {
1314
- const { interval = 1e3, timeout: timeoutMs = 3e4, validate } = options;
1315
- const startTime = Date.now();
1316
- while (true) {
1317
- const result = await fn();
1318
- if (!validate || validate(result)) {
1319
- return result;
1320
- }
1321
- if (Date.now() - startTime >= timeoutMs) {
1322
- throw new Error("Polling timeout exceeded");
1323
- }
1324
- await sleep(interval);
1325
- }
1326
- }
1327
-
1328
- const index$5 = {
1329
- __proto__: null,
1330
- Mutex: Mutex,
1331
- Semaphore: Semaphore,
1332
- allSettled: allSettled,
1333
- batch: batch,
1334
- debounce: debounce,
1335
- defer: defer,
1336
- memoize: memoize,
1337
- parallelLimit: parallelLimit,
1338
- poll: poll,
1339
- raceWithTimeout: raceWithTimeout,
1340
- retry: retry,
1341
- sequence: sequence,
1342
- sleep: sleep,
1343
- throttle: throttle,
1344
- timeout: timeout,
1345
- waitFor: waitFor
1346
- };
1347
-
1348
- const CLAUDE_DIR = join$1(homedir(), ".claude");
1349
- const COMMANDS_DIR = join$1(CLAUDE_DIR, "commands", "ccjk");
1350
- const SKILLS_DIR = join$1(CLAUDE_DIR, "skills");
1351
- const SUPERPOWERS_DIR = join$1(CLAUDE_DIR, "superpowers");
1352
- function scanCommands() {
1353
- const capabilities = [];
1354
- if (!existsSync(COMMANDS_DIR)) {
1355
- return capabilities;
1356
- }
1357
- try {
1358
- const files = readdirSync(COMMANDS_DIR);
1359
- for (const file of files) {
1360
- if (!file.endsWith(".md"))
1361
- continue;
1362
- const filePath = join$1(COMMANDS_DIR, file);
1363
- const commandId = file.replace(".md", "");
1364
- try {
1365
- const content = readFileSync(filePath, "utf-8");
1366
- const nameMatch = content.match(/^#\s([^\n]+)$/m);
1367
- const descMatch = content.match(/^>\s([^\n]+)$/m);
1368
- capabilities.push({
1369
- id: commandId,
1370
- name: nameMatch?.[1] || commandId,
1371
- type: "command",
1372
- status: "active",
1373
- priority: 10,
1374
- description: descMatch?.[1] || "CCJK command",
1375
- triggers: [`/ccjk:${commandId}`],
1376
- path: filePath
1377
- });
1378
- } catch (error) {
1379
- capabilities.push({
1380
- id: commandId,
1381
- name: commandId,
1382
- type: "command",
1383
- status: "error",
1384
- priority: 0,
1385
- description: "Failed to load command",
1386
- error: error instanceof Error ? error.message : "Unknown error",
1387
- path: filePath
1388
- });
1389
- }
1390
- }
1391
- } catch {
1392
- }
1393
- return capabilities;
1394
- }
1395
- function scanSkills() {
1396
- const capabilities = [];
1397
- if (!existsSync(SKILLS_DIR)) {
1398
- return capabilities;
1399
- }
1400
- try {
1401
- const files = readdirSync(SKILLS_DIR);
1402
- for (const file of files) {
1403
- if (!file.endsWith(".md"))
1404
- continue;
1405
- const filePath = join$1(SKILLS_DIR, file);
1406
- const skillId = file.replace(".md", "");
1407
- try {
1408
- const content = readFileSync(filePath, "utf-8");
1409
- const nameMatch = content.match(/^#\s([^\n]+)$/m);
1410
- const descMatch = content.match(/^>\s([^\n]+)$/m);
1411
- capabilities.push({
1412
- id: skillId,
1413
- name: nameMatch?.[1] || skillId,
1414
- type: "skill",
1415
- status: "active",
1416
- priority: 8,
1417
- description: descMatch?.[1] || "Custom skill",
1418
- triggers: [`/${skillId}`],
1419
- path: filePath
1420
- });
1421
- } catch (error) {
1422
- capabilities.push({
1423
- id: skillId,
1424
- name: skillId,
1425
- type: "skill",
1426
- status: "error",
1427
- priority: 0,
1428
- description: "Failed to load skill",
1429
- error: error instanceof Error ? error.message : "Unknown error",
1430
- path: filePath
1431
- });
1432
- }
1433
- }
1434
- } catch {
1435
- }
1436
- return capabilities;
1437
- }
1438
- function scanSuperpowers() {
1439
- const capabilities = [];
1440
- if (!existsSync(SUPERPOWERS_DIR)) {
1441
- return capabilities;
1442
- }
1443
- try {
1444
- const entries = readdirSync(SUPERPOWERS_DIR);
1445
- for (const entry of entries) {
1446
- const entryPath = join$1(SUPERPOWERS_DIR, entry);
1447
- try {
1448
- const stat = statSync(entryPath);
1449
- if (!stat.isDirectory())
1450
- continue;
1451
- const files = readdirSync(entryPath);
1452
- const mdFiles = files.filter((f) => f.endsWith(".md"));
1453
- if (mdFiles.length === 0)
1454
- continue;
1455
- const status = mdFiles.length > 0 ? "active" : "inactive";
1456
- capabilities.push({
1457
- id: entry,
1458
- name: entry,
1459
- type: "superpower",
1460
- status,
1461
- priority: 9,
1462
- description: `Superpower with ${mdFiles.length} skill(s)`,
1463
- path: entryPath
1464
- });
1465
- } catch (error) {
1466
- capabilities.push({
1467
- id: entry,
1468
- name: entry,
1469
- type: "superpower",
1470
- status: "error",
1471
- priority: 0,
1472
- description: "Failed to load superpower",
1473
- error: error instanceof Error ? error.message : "Unknown error",
1474
- path: entryPath
1475
- });
1476
- }
1477
- }
1478
- } catch {
1479
- }
1480
- return capabilities;
1481
- }
1482
- function scanMCPServices() {
1483
- const capabilities = [];
1484
- const configPath = join$1(CLAUDE_DIR, "claude_desktop_config.json");
1485
- if (!existsSync(configPath)) {
1486
- return capabilities;
1487
- }
1488
- try {
1489
- const content = readFileSync(configPath, "utf-8");
1490
- const config = JSON.parse(content);
1491
- if (config.mcpServers && typeof config.mcpServers === "object") {
1492
- for (const [serviceName, serviceConfig] of Object.entries(config.mcpServers)) {
1493
- const status = serviceConfig && typeof serviceConfig === "object" ? "active" : "inactive";
1494
- capabilities.push({
1495
- id: serviceName,
1496
- name: serviceName,
1497
- type: "mcp",
1498
- status,
1499
- priority: 7,
1500
- description: "MCP service",
1501
- path: configPath
1502
- });
1503
- }
1504
- }
1505
- } catch {
1506
- }
1507
- return capabilities;
1508
- }
1509
- function scanAgents() {
1510
- const capabilities = [];
1511
- try {
1512
- execSync("which agent-browser", { stdio: "ignore" });
1513
- capabilities.push({
1514
- id: "agent-browser",
1515
- name: "Agent Browser",
1516
- type: "agent",
1517
- status: "active",
1518
- priority: 10,
1519
- description: "Zero-config browser automation",
1520
- triggers: ["agent-browser"]
1521
- });
1522
- } catch {
1523
- }
1524
- return capabilities;
1525
- }
1526
- function scanCapabilities() {
1527
- const commands = scanCommands();
1528
- const skills = scanSkills();
1529
- const agents = scanAgents();
1530
- const mcpServices = scanMCPServices();
1531
- const superpowers = scanSuperpowers();
1532
- const allCapabilities = [
1533
- ...commands,
1534
- ...skills,
1535
- ...agents,
1536
- ...mcpServices,
1537
- ...superpowers
1538
- ];
1539
- const activeCount = allCapabilities.filter((c) => c.status === "active").length;
1540
- const errorCount = allCapabilities.filter((c) => c.status === "error").length;
1541
- return {
1542
- commands,
1543
- skills,
1544
- agents,
1545
- mcpServices,
1546
- superpowers,
1547
- total: allCapabilities.length,
1548
- activeCount,
1549
- errorCount
1550
- };
1551
- }
1552
- function getCapability(id) {
1553
- const result = scanCapabilities();
1554
- const allCapabilities = [
1555
- ...result.commands,
1556
- ...result.skills,
1557
- ...result.agents,
1558
- ...result.mcpServices,
1559
- ...result.superpowers
1560
- ];
1561
- return allCapabilities.find((c) => c.id === id);
1562
- }
1563
- function getCapabilitiesByType(type) {
1564
- const result = scanCapabilities();
1565
- switch (type) {
1566
- case "command":
1567
- return result.commands;
1568
- case "skill":
1569
- return result.skills;
1570
- case "agent":
1571
- return result.agents;
1572
- case "mcp":
1573
- return result.mcpServices;
1574
- case "superpower":
1575
- return result.superpowers;
1576
- default:
1577
- return [];
1578
- }
1579
- }
1580
-
1581
- const BOX_CHARS = {
1582
- topLeft: "\u256D",
1583
- topRight: "\u256E",
1584
- bottomLeft: "\u2570",
1585
- bottomRight: "\u256F",
1586
- horizontal: "\u2500",
1587
- vertical: "\u2502"
1588
- };
1589
- function createBorderLine(width, type) {
1590
- const left = type === "top" ? BOX_CHARS.topLeft : type === "bottom" ? BOX_CHARS.bottomLeft : BOX_CHARS.vertical;
1591
- const right = type === "top" ? BOX_CHARS.topRight : type === "bottom" ? BOX_CHARS.bottomRight : BOX_CHARS.vertical;
1592
- const fill = type === "middle" ? " " : BOX_CHARS.horizontal;
1593
- return `${left}${fill.repeat(width - 2)}${right}`;
1594
- }
1595
- function centerText(text, width) {
1596
- const plainText = text.replace(/\x1B\[[0-9;]*m/g, "");
1597
- const padding = Math.max(0, width - plainText.length - 2);
1598
- const leftPad = Math.floor(padding / 2);
1599
- const rightPad = padding - leftPad;
1600
- return `${BOX_CHARS.vertical}${" ".repeat(leftPad)}${text}${" ".repeat(rightPad)}${BOX_CHARS.vertical}`;
1601
- }
1602
- function leftText(text, width) {
1603
- const plainText = text.replace(/\x1B\[[0-9;]*m/g, "");
1604
- const padding = Math.max(0, width - plainText.length - 2);
1605
- return `${BOX_CHARS.vertical} ${text}${" ".repeat(padding - 1)}${BOX_CHARS.vertical}`;
1606
- }
1607
- function getVersion() {
1608
- return getRuntimeVersion();
1609
- }
1610
- function generateWelcome(scanResult, options = {}) {
1611
- const {
1612
- showVersion = true,
1613
- showStats = true,
1614
- showRecommendations = true,
1615
- compact = false
1616
- } = options;
1617
- const lines = [];
1618
- const width = compact ? 50 : 70;
1619
- lines.push(createBorderLine(width, "top"));
1620
- if (showVersion) {
1621
- const version = getVersion();
1622
- const title = a.bold.cyan(`\u{1F389} CCJK v${version} - Claude Code JinKu`);
1623
- lines.push(centerText(title, width));
1624
- } else {
1625
- const title = a.bold.cyan("\u{1F389} CCJK - Claude Code JinKu");
1626
- lines.push(centerText(title, width));
1627
- }
1628
- if (showStats && scanResult.total > 0) {
1629
- lines.push(leftText("", width));
1630
- lines.push(leftText(a.bold("\u2728 Available Capabilities:"), width));
1631
- if (scanResult.skills.length > 0) {
1632
- const activeSkills = scanResult.skills.filter((c) => c.status === "active");
1633
- if (activeSkills.length > 0) {
1634
- lines.push(leftText("", width));
1635
- lines.push(leftText(a.bold.green(" \u{1F4DA} Skills:"), width));
1636
- activeSkills.slice(0, 5).forEach((skill) => {
1637
- const trigger = skill.triggers?.[0] || `/${skill.id}`;
1638
- lines.push(leftText(` ${a.cyan(trigger.padEnd(20))} ${a.dim(skill.description)}`, width));
1639
- });
1640
- if (activeSkills.length > 5) {
1641
- lines.push(leftText(` ${a.dim(`... and ${activeSkills.length - 5} more`)}`, width));
1642
- }
1643
- }
1644
- }
1645
- if (scanResult.mcpServices.length > 0) {
1646
- const activeMcp = scanResult.mcpServices.filter((c) => c.status === "active");
1647
- if (activeMcp.length > 0) {
1648
- lines.push(leftText("", width));
1649
- lines.push(leftText(a.bold.green(" \u{1F50C} MCP Services:"), width));
1650
- activeMcp.slice(0, 5).forEach((mcp) => {
1651
- lines.push(leftText(` ${a.cyan(mcp.name.padEnd(20))} ${a.dim(mcp.description)}`, width));
1652
- });
1653
- if (activeMcp.length > 5) {
1654
- lines.push(leftText(` ${a.dim(`... and ${activeMcp.length - 5} more`)}`, width));
1655
- }
1656
- }
1657
- }
1658
- if (scanResult.agents.length > 0) {
1659
- const activeAgents = scanResult.agents.filter((c) => c.status === "active");
1660
- if (activeAgents.length > 0) {
1661
- lines.push(leftText("", width));
1662
- lines.push(leftText(a.bold.green(" \u{1F916} Agents:"), width));
1663
- activeAgents.forEach((agent) => {
1664
- const trigger = agent.triggers?.[0] || agent.id;
1665
- lines.push(leftText(` ${a.cyan(trigger.padEnd(20))} ${a.dim(agent.description)}`, width));
1666
- });
1667
- }
1668
- }
1669
- if (scanResult.superpowers.length > 0) {
1670
- const activeSuperpowers = scanResult.superpowers.filter((c) => c.status === "active");
1671
- if (activeSuperpowers.length > 0) {
1672
- lines.push(leftText("", width));
1673
- lines.push(leftText(a.bold.green(" \u26A1 Superpowers:"), width));
1674
- activeSuperpowers.slice(0, 3).forEach((sp) => {
1675
- lines.push(leftText(` ${a.cyan(sp.name.padEnd(20))} ${a.dim(sp.description)}`, width));
1676
- });
1677
- if (activeSuperpowers.length > 3) {
1678
- lines.push(leftText(` ${a.dim(`... and ${activeSuperpowers.length - 3} more`)}`, width));
1679
- }
1680
- }
1681
- }
1682
- if (scanResult.commands.length > 0) {
1683
- const activeCommands = scanResult.commands.filter((c) => c.status === "active").length;
1684
- lines.push(leftText("", width));
1685
- lines.push(leftText(` ${a.green("\u2022")} ${activeCommands} CCJK Command(s) available`, width));
1686
- }
1687
- if (scanResult.errorCount > 0) {
1688
- lines.push(leftText("", width));
1689
- lines.push(leftText(` ${a.red("\u26A0")} ${scanResult.errorCount} capability error(s) detected`, width));
1690
- }
1691
- }
1692
- if (showRecommendations && !compact) {
1693
- lines.push(leftText("", width));
1694
- lines.push(leftText(a.bold("\u{1F4A1} Quick Tips:"), width));
1695
- lines.push(leftText(` ${a.green("/ccjk:status")} - View detailed capability status`, width));
1696
- lines.push(leftText(` ${a.green("/ccjk:help")} - Get help and documentation`, width));
1697
- const activeSkills = scanResult.skills.filter((c) => c.status === "active");
1698
- if (activeSkills.length > 0 && activeSkills[0].triggers?.[0]) {
1699
- lines.push(leftText(` ${a.green(activeSkills[0].triggers[0])} - Try this skill`, width));
1700
- }
1701
- }
1702
- lines.push(createBorderLine(width, "bottom"));
1703
- return lines.join("\n");
1704
- }
1705
- function generateCompactWelcome(scanResult) {
1706
- const parts = [];
1707
- if (scanResult.commands.length > 0) {
1708
- parts.push(`${scanResult.commands.filter((c) => c.status === "active").length} commands`);
1709
- }
1710
- if (scanResult.skills.length > 0) {
1711
- parts.push(`${scanResult.skills.filter((c) => c.status === "active").length} skills`);
1712
- }
1713
- if (scanResult.superpowers.length > 0) {
1714
- parts.push(`${scanResult.superpowers.filter((c) => c.status === "active").length} superpowers`);
1715
- }
1716
- const summary = parts.join(", ");
1717
- return a.dim(`CCJK loaded: ${summary || "no capabilities"}`);
1718
- }
1719
- function generateRecommendations(scanResult) {
1720
- const recommendations = [];
1721
- if (scanResult.total === 0) {
1722
- recommendations.push("Run `npx ccjk` to install CCJK capabilities");
1723
- return recommendations;
1724
- }
1725
- if (scanResult.agents.length === 0) {
1726
- recommendations.push("Install Agent Browser for zero-config browser automation");
1727
- }
1728
- if (scanResult.superpowers.length === 0) {
1729
- recommendations.push("Install Superpowers for advanced AI workflows");
1730
- }
1731
- if (scanResult.errorCount > 0) {
1732
- recommendations.push(`Fix ${scanResult.errorCount} capability error(s) - run /ccjk:status for details`);
1733
- }
1734
- return recommendations;
1735
- }
1736
-
1737
- const execAsync = promisify(exec);
1738
- async function executeCommand(command, args = [], options = {}) {
1739
- try {
1740
- const fullCommand = buildCommand(command, args);
1741
- const execOptions = {
1742
- cwd: options.cwd,
1743
- env: { ...process.env, ...options.env },
1744
- timeout: options.timeout,
1745
- shell: typeof options.shell === "string" ? options.shell : options.shell ? "/bin/sh" : void 0,
1746
- encoding: options.encoding || "utf8",
1747
- maxBuffer: options.maxBuffer || 1024 * 1024 * 10
1748
- // 10MB default
1749
- };
1750
- const { stdout, stderr } = await execAsync(fullCommand, execOptions);
1751
- return {
1752
- success: true,
1753
- stdout: stdout.toString().trim(),
1754
- stderr: stderr.toString().trim(),
1755
- exitCode: 0
1756
- };
1757
- } catch (error) {
1758
- return {
1759
- success: false,
1760
- stdout: error.stdout?.toString().trim() || "",
1761
- stderr: error.stderr?.toString().trim() || "",
1762
- exitCode: error.code || 1,
1763
- error: error.message
1764
- };
1765
- }
1766
- }
1767
- function executeCommandStream(command, args = [], options = {}) {
1768
- return new Promise((resolve) => {
1769
- const spawnOptions = {
1770
- cwd: options.cwd,
1771
- env: { ...process.env, ...options.env },
1772
- shell: options.shell !== false
1773
- };
1774
- const child = spawn(command, args, spawnOptions);
1775
- let stdout = "";
1776
- let stderr = "";
1777
- child.stdout?.on("data", (data) => {
1778
- const text = data.toString();
1779
- stdout += text;
1780
- if (options.onStdout) {
1781
- options.onStdout(text);
1782
- }
1783
- });
1784
- child.stderr?.on("data", (data) => {
1785
- const text = data.toString();
1786
- stderr += text;
1787
- if (options.onStderr) {
1788
- options.onStderr(text);
1789
- }
1790
- });
1791
- child.on("close", (code) => {
1792
- resolve({
1793
- success: code === 0,
1794
- stdout: stdout.trim(),
1795
- stderr: stderr.trim(),
1796
- exitCode: code || 0,
1797
- error: code !== 0 ? `Command exited with code ${code}` : void 0
1798
- });
1799
- });
1800
- child.on("error", (error) => {
1801
- resolve({
1802
- success: false,
1803
- stdout: stdout.trim(),
1804
- stderr: stderr.trim(),
1805
- exitCode: 1,
1806
- error: error.message
1807
- });
1808
- });
1809
- if (options.timeout) {
1810
- setTimeout(() => {
1811
- child.kill();
1812
- resolve({
1813
- success: false,
1814
- stdout: stdout.trim(),
1815
- stderr: stderr.trim(),
1816
- exitCode: 1,
1817
- error: `Command timed out after ${options.timeout}ms`
1818
- });
1819
- }, options.timeout);
1820
- }
1821
- });
1822
- }
1823
- function buildCommand(command, args) {
1824
- const escapedArgs = args.map(escapeArgument);
1825
- return [command, ...escapedArgs].join(" ");
1826
- }
1827
- function escapeArgument(arg) {
1828
- if (/[\s"'`$&|;<>(){}[\]\\]/.test(arg)) {
1829
- const escaped = arg.replace(/"/g, '\\"');
1830
- return `"${escaped}"`;
1831
- }
1832
- return arg;
1833
- }
1834
- async function commandExists(command) {
1835
- const isWindows = process.platform === "win32";
1836
- const checkCommand = isWindows ? "where" : "which";
1837
- try {
1838
- const result = await executeCommand(checkCommand, [command]);
1839
- return result.success;
1840
- } catch {
1841
- return false;
1842
- }
1843
- }
1844
- async function getCommandPath(command) {
1845
- const isWindows = process.platform === "win32";
1846
- const checkCommand = isWindows ? "where" : "which";
1847
- try {
1848
- const result = await executeCommand(checkCommand, [command]);
1849
- if (result.success) {
1850
- return result.stdout.split("\n")[0].trim();
1851
- }
1852
- return null;
1853
- } catch {
1854
- return null;
1855
- }
1856
- }
1857
- function parseVersion(output) {
1858
- const patterns = [
1859
- /version\s+v?(\d+\.\d+\.\d+)/i,
1860
- /v?(\d+\.\d+\.\d+)/,
1861
- /(\d+\.\d+\.\d+)/
1862
- ];
1863
- for (const pattern of patterns) {
1864
- const match = output.match(pattern);
1865
- if (match) {
1866
- return match[1];
1867
- }
1868
- }
1869
- return null;
1870
- }
1871
- async function getCommandVersion(command, versionFlag = "--version") {
1872
- try {
1873
- const result = await executeCommand(command, [versionFlag]);
1874
- if (result.success) {
1875
- return parseVersion(result.stdout || result.stderr);
1876
- }
1877
- return null;
1878
- } catch {
1879
- return null;
1880
- }
1881
- }
1882
- async function executeCommandSequence(commands) {
1883
- const results = [];
1884
- for (const cmd of commands) {
1885
- const result = await executeCommand(
1886
- cmd.command,
1887
- cmd.args || [],
1888
- cmd.options || {}
1889
- );
1890
- results.push(result);
1891
- if (!result.success) {
1892
- break;
1893
- }
1894
- }
1895
- return results;
1896
- }
1897
- async function executeCommandParallel(commands) {
1898
- const promises = commands.map(
1899
- (cmd) => executeCommand(cmd.command, cmd.args || [], cmd.options || {})
1900
- );
1901
- return Promise.all(promises);
1902
- }
1903
-
1904
- const index$4 = {
1905
- __proto__: null,
1906
- buildCommand: buildCommand,
1907
- commandExists: commandExists,
1908
- escapeArgument: escapeArgument,
1909
- executeCommand: executeCommand,
1910
- executeCommandParallel: executeCommandParallel,
1911
- executeCommandSequence: executeCommandSequence,
1912
- executeCommandStream: executeCommandStream,
1913
- getCommandPath: getCommandPath,
1914
- getCommandVersion: getCommandVersion,
1915
- parseVersion: parseVersion
1916
- };
1917
-
1918
- class ConfigManager {
1919
- constructor(namespace, options = {}) {
1920
- this.namespace = namespace;
1921
- this.options = {
1922
- configDir: options.configDir || this.getDefaultConfigDir(),
1923
- fileName: options.fileName || `${namespace}.json`,
1924
- createIfMissing: options.createIfMissing ?? true,
1925
- validate: options.validate || (() => true)
1926
- };
1927
- this.configPath = path.join(this.options.configDir, this.options.fileName);
1928
- }
1929
- configPath;
1930
- options;
1931
- cache;
1932
- /**
1933
- * Get the default configuration directory
1934
- */
1935
- getDefaultConfigDir() {
1936
- return path.join(os.homedir(), ".ccjk");
1937
- }
1938
- /**
1939
- * Load configuration from file
1940
- */
1941
- async load() {
1942
- try {
1943
- const data = await promises.readFile(this.configPath, "utf-8");
1944
- const config = JSON.parse(data);
1945
- if (!this.options.validate(config)) {
1946
- throw new Error("Configuration validation failed");
1947
- }
1948
- this.cache = config;
1949
- return config;
1950
- } catch (error) {
1951
- if (error.code === "ENOENT") {
1952
- return null;
1953
- }
1954
- throw error;
1955
- }
1956
- }
1957
- /**
1958
- * Save configuration to file
1959
- */
1960
- async save(config) {
1961
- if (!this.options.validate(config)) {
1962
- throw new Error("Configuration validation failed");
1963
- }
1964
- await promises.mkdir(this.options.configDir, { recursive: true });
1965
- await promises.writeFile(this.configPath, JSON.stringify(config, null, 2), "utf-8");
1966
- this.cache = config;
1967
- }
1968
- /**
1969
- * Update configuration (merge with existing)
1970
- */
1971
- async update(updates) {
1972
- const current = await this.load() || {};
1973
- const updated = { ...current, ...updates };
1974
- await this.save(updated);
1975
- return updated;
1976
- }
1977
- /**
1978
- * Delete configuration file
1979
- */
1980
- async delete() {
1981
- try {
1982
- await promises.unlink(this.configPath);
1983
- this.cache = void 0;
1984
- } catch (error) {
1985
- if (error.code !== "ENOENT") {
1986
- throw error;
1987
- }
1988
- }
1989
- }
1990
- /**
1991
- * Check if configuration file exists
1992
- */
1993
- async exists() {
1994
- try {
1995
- await promises.access(this.configPath);
1996
- return true;
1997
- } catch {
1998
- return false;
1999
- }
2000
- }
2001
- /**
2002
- * Get configuration path
2003
- */
2004
- getPath() {
2005
- return this.configPath;
2006
- }
2007
- /**
2008
- * Get cached configuration (without file I/O)
2009
- */
2010
- getCached() {
2011
- return this.cache;
2012
- }
2013
- /**
2014
- * Clear cache
2015
- */
2016
- clearCache() {
2017
- this.cache = void 0;
2018
- }
2019
- }
2020
- function createConfigManager(namespace, options) {
2021
- return new ConfigManager(namespace, options);
2022
- }
2023
-
2024
- class ConfigValidator {
2025
- constructor(rules) {
2026
- this.rules = rules;
2027
- }
2028
- /**
2029
- * Validate a configuration object
2030
- */
2031
- validate(config) {
2032
- const errors = [];
2033
- for (const rule of this.rules) {
2034
- const value = config[rule.field];
2035
- if (rule.required && (value === void 0 || value === null)) {
2036
- errors.push({
2037
- field: String(rule.field),
2038
- message: rule.message || `Field '${String(rule.field)}' is required`
2039
- });
2040
- continue;
2041
- }
2042
- if (value === void 0 || value === null) {
2043
- continue;
2044
- }
2045
- if (rule.type) {
2046
- const actualType = Array.isArray(value) ? "array" : typeof value;
2047
- if (actualType !== rule.type) {
2048
- errors.push({
2049
- field: String(rule.field),
2050
- message: rule.message || `Field '${String(rule.field)}' must be of type ${rule.type}`
2051
- });
2052
- continue;
2053
- }
2054
- }
2055
- if (rule.validator && !rule.validator(value)) {
2056
- errors.push({
2057
- field: String(rule.field),
2058
- message: rule.message || `Field '${String(rule.field)}' validation failed`
2059
- });
2060
- }
2061
- }
2062
- return {
2063
- valid: errors.length === 0,
2064
- errors
2065
- };
2066
- }
2067
- /**
2068
- * Validate and throw on error
2069
- */
2070
- validateOrThrow(config) {
2071
- const result = this.validate(config);
2072
- if (!result.valid) {
2073
- const errorMessages = result.errors.map((e) => `${e.field}: ${e.message}`).join(", ");
2074
- throw new Error(`Configuration validation failed: ${errorMessages}`);
2075
- }
2076
- }
2077
- }
2078
- function createValidator(rules) {
2079
- return new ConfigValidator(rules);
2080
- }
2081
- const validators = {
2082
- /**
2083
- * Validate string is not empty
2084
- */
2085
- notEmpty: (value) => {
2086
- return typeof value === "string" && value.trim().length > 0;
2087
- },
2088
- /**
2089
- * Validate string matches pattern
2090
- */
2091
- pattern: (regex) => (value) => {
2092
- return typeof value === "string" && regex.test(value);
2093
- },
2094
- /**
2095
- * Validate number is in range
2096
- */
2097
- range: (min, max) => (value) => {
2098
- return typeof value === "number" && value >= min && value <= max;
2099
- },
2100
- /**
2101
- * Validate string length
2102
- */
2103
- length: (min, max) => (value) => {
2104
- if (typeof value !== "string")
2105
- return false;
2106
- if (max !== void 0) {
2107
- return value.length >= min && value.length <= max;
2108
- }
2109
- return value.length >= min;
2110
- },
2111
- /**
2112
- * Validate value is one of allowed values
2113
- */
2114
- oneOf: (allowed) => (value) => {
2115
- return allowed.includes(value);
2116
- },
2117
- /**
2118
- * Validate email format
2119
- */
2120
- email: (value) => {
2121
- const emailRegex = /^[^\s@]+@[^\s@][^\s.@]*\.[^\s@]+$/;
2122
- return typeof value === "string" && emailRegex.test(value);
2123
- },
2124
- /**
2125
- * Validate URL format
2126
- */
2127
- url: (value) => {
2128
- try {
2129
- new URL(value);
2130
- return true;
2131
- } catch {
2132
- return false;
2133
- }
2134
- },
2135
- /**
2136
- * Validate object has required keys
2137
- */
2138
- hasKeys: (keys) => (value) => {
2139
- if (typeof value !== "object" || value === null)
2140
- return false;
2141
- return keys.every((key) => key in value);
2142
- },
2143
- /**
2144
- * Validate array is not empty
2145
- */
2146
- notEmptyArray: (value) => {
2147
- return Array.isArray(value) && value.length > 0;
2148
- }
2149
- };
2150
-
2151
- class BaseError extends Error {
2152
- constructor(message, code, statusCode, details) {
2153
- super(message);
2154
- this.code = code;
2155
- this.statusCode = statusCode;
2156
- this.details = details;
2157
- this.name = this.constructor.name;
2158
- Error.captureStackTrace(this, this.constructor);
2159
- }
2160
- toJSON() {
2161
- return {
2162
- name: this.name,
2163
- message: this.message,
2164
- code: this.code,
2165
- statusCode: this.statusCode,
2166
- details: this.details,
2167
- stack: this.stack
2168
- };
2169
- }
2170
- }
2171
- class ValidationError extends BaseError {
2172
- constructor(message, details) {
2173
- super(message, "VALIDATION_ERROR", 400, details);
2174
- }
2175
- }
2176
- class NotFoundError extends BaseError {
2177
- constructor(message, details) {
2178
- super(message, "NOT_FOUND", 404, details);
2179
- }
2180
- }
2181
- class UnauthorizedError extends BaseError {
2182
- constructor(message, details) {
2183
- super(message, "UNAUTHORIZED", 401, details);
2184
- }
2185
- }
2186
- class ForbiddenError extends BaseError {
2187
- constructor(message, details) {
2188
- super(message, "FORBIDDEN", 403, details);
2189
- }
2190
- }
2191
- class ConflictError extends BaseError {
2192
- constructor(message, details) {
2193
- super(message, "CONFLICT", 409, details);
2194
- }
2195
- }
2196
- class TimeoutError extends BaseError {
2197
- constructor(message, details) {
2198
- super(message, "TIMEOUT", 408, details);
2199
- }
2200
- }
2201
- class InternalError extends BaseError {
2202
- constructor(message, details) {
2203
- super(message, "INTERNAL_ERROR", 500, details);
2204
- }
2205
- }
2206
- class ConfigurationError extends BaseError {
2207
- constructor(message, details) {
2208
- super(message, "CONFIGURATION_ERROR", 500, details);
2209
- }
2210
- }
2211
- class NetworkError extends BaseError {
2212
- constructor(message, details) {
2213
- super(message, "NETWORK_ERROR", 503, details);
2214
- }
2215
- }
2216
- function isErrorType(error, errorClass) {
2217
- return error instanceof errorClass;
2218
- }
2219
- function getErrorMessage(error) {
2220
- if (error instanceof Error) {
2221
- return error.message;
2222
- }
2223
- if (typeof error === "string") {
2224
- return error;
2225
- }
2226
- return "An unknown error occurred";
2227
- }
2228
- function getErrorStack(error) {
2229
- if (error instanceof Error) {
2230
- return error.stack;
2231
- }
2232
- return void 0;
2233
- }
2234
- function formatError(error) {
2235
- if (error instanceof BaseError) {
2236
- return {
2237
- message: error.message,
2238
- name: error.name,
2239
- code: error.code,
2240
- statusCode: error.statusCode,
2241
- stack: error.stack,
2242
- details: error.details
2243
- };
2244
- }
2245
- if (error instanceof Error) {
2246
- return {
2247
- message: error.message,
2248
- name: error.name,
2249
- stack: error.stack
2250
- };
2251
- }
2252
- return {
2253
- message: String(error)
2254
- };
2255
- }
2256
- function wrapError(error, message, code) {
2257
- const originalMessage = getErrorMessage(error);
2258
- const fullMessage = `${message}: ${originalMessage}`;
2259
- if (error instanceof BaseError) {
2260
- return new BaseError(
2261
- fullMessage,
2262
- code || error.code,
2263
- error.statusCode,
2264
- error.details
2265
- );
2266
- }
2267
- return new BaseError(fullMessage, code);
2268
- }
2269
- function tryCatch(fn) {
2270
- try {
2271
- const data = fn();
2272
- return { success: true, data };
2273
- } catch (error) {
2274
- return {
2275
- success: false,
2276
- error: error instanceof Error ? error : new Error(String(error))
2277
- };
2278
- }
2279
- }
2280
- async function tryCatchAsync(fn) {
2281
- try {
2282
- const data = await fn();
2283
- return { success: true, data };
2284
- } catch (error) {
2285
- return {
2286
- success: false,
2287
- error: error instanceof Error ? error : new Error(String(error))
2288
- };
2289
- }
2290
- }
2291
- function assert$1(condition, message, ErrorClass = Error) {
2292
- if (!condition) {
2293
- throw new ErrorClass(message);
2294
- }
2295
- }
2296
- function createErrorHandler(handlers, defaultHandler) {
2297
- return (error) => {
2298
- if (error instanceof BaseError && error.code && handlers[error.code]) {
2299
- handlers[error.code](error);
2300
- } else if (error instanceof Error && handlers[error.name]) {
2301
- handlers[error.name](error);
2302
- } else if (defaultHandler) {
2303
- defaultHandler(error instanceof Error ? error : new Error(String(error)));
2304
- } else {
2305
- throw error;
2306
- }
2307
- };
2308
- }
2309
- class AggregateError extends BaseError {
2310
- constructor(errors, message = "Multiple errors occurred") {
2311
- super(message, "AGGREGATE_ERROR", 500, { errors });
2312
- this.errors = errors;
2313
- }
2314
- static fromErrors(errors) {
2315
- const message = `${errors.length} error(s) occurred: ${errors.map((e) => e.message).join(", ")}`;
2316
- return new AggregateError(errors, message);
2317
- }
2318
- }
2319
- async function retryWithErrorHandling(fn, options = {}) {
2320
- const {
2321
- maxAttempts = 3,
2322
- delay = 1e3,
2323
- shouldRetry = () => true,
2324
- onError
2325
- } = options;
2326
- let lastError;
2327
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
2328
- try {
2329
- return await fn();
2330
- } catch (error) {
2331
- lastError = error instanceof Error ? error : new Error(String(error));
2332
- if (onError) {
2333
- onError(lastError, attempt);
2334
- }
2335
- if (attempt < maxAttempts && shouldRetry(lastError)) {
2336
- await new Promise((resolve) => setTimeout(resolve, delay));
2337
- } else {
2338
- throw lastError;
2339
- }
2340
- }
2341
- }
2342
- throw lastError;
2343
- }
2344
-
2345
- const index$3 = {
2346
- __proto__: null,
2347
- AggregateError: AggregateError,
2348
- BaseError: BaseError,
2349
- ConfigurationError: ConfigurationError,
2350
- ConflictError: ConflictError,
2351
- ForbiddenError: ForbiddenError,
2352
- InternalError: InternalError,
2353
- NetworkError: NetworkError,
2354
- NotFoundError: NotFoundError,
2355
- TimeoutError: TimeoutError,
2356
- UnauthorizedError: UnauthorizedError,
2357
- ValidationError: ValidationError,
2358
- assert: assert$1,
2359
- createErrorHandler: createErrorHandler,
2360
- formatError: formatError,
2361
- getErrorMessage: getErrorMessage,
2362
- getErrorStack: getErrorStack,
2363
- isErrorType: isErrorType,
2364
- retryWithErrorHandling: retryWithErrorHandling,
2365
- tryCatch: tryCatch,
2366
- tryCatchAsync: tryCatchAsync,
2367
- wrapError: wrapError
2368
- };
2369
-
2370
- async function exists(filePath) {
2371
- try {
2372
- await promises.access(filePath);
2373
- return true;
2374
- } catch {
2375
- return false;
2376
- }
2377
- }
2378
- async function isFile(filePath) {
2379
- try {
2380
- const stats = await promises.stat(filePath);
2381
- return stats.isFile();
2382
- } catch {
2383
- return false;
2384
- }
2385
- }
2386
- async function isDirectory(filePath) {
2387
- try {
2388
- const stats = await promises.stat(filePath);
2389
- return stats.isDirectory();
2390
- } catch {
2391
- return false;
2392
- }
2393
- }
2394
- async function ensureDir(dirPath) {
2395
- await promises.mkdir(dirPath, { recursive: true });
2396
- }
2397
- async function readFile(filePath, encoding = "utf-8") {
2398
- return promises.readFile(filePath, encoding);
2399
- }
2400
- async function writeFile(filePath, content, encoding = "utf-8") {
2401
- await ensureDir(path.dirname(filePath));
2402
- await promises.writeFile(filePath, content, encoding);
2403
- }
2404
- async function appendFile(filePath, content, encoding = "utf-8") {
2405
- await ensureDir(path.dirname(filePath));
2406
- await promises.appendFile(filePath, content, encoding);
2407
- }
2408
- async function readJSON(filePath) {
2409
- const content = await readFile(filePath);
2410
- return JSON.parse(content);
2411
- }
2412
- async function writeJSON(filePath, data, pretty = true) {
2413
- const content = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
2414
- await writeFile(filePath, content);
2415
- }
2416
- async function copyFile(src, dest) {
2417
- await ensureDir(path.dirname(dest));
2418
- await promises.copyFile(src, dest);
2419
- }
2420
- async function moveFile(src, dest) {
2421
- await ensureDir(path.dirname(dest));
2422
- await promises.rename(src, dest);
2423
- }
2424
- async function deleteFile(filePath) {
2425
- try {
2426
- await promises.unlink(filePath);
2427
- } catch (error) {
2428
- if (error.code !== "ENOENT") {
2429
- throw error;
2430
- }
2431
- }
2432
- }
2433
- async function deleteDir(dirPath) {
2434
- try {
2435
- await promises.rm(dirPath, { recursive: true, force: true });
2436
- } catch (error) {
2437
- if (error.code !== "ENOENT") {
2438
- throw error;
2439
- }
2440
- }
2441
- }
2442
- async function listFiles(dirPath, recursive = false) {
2443
- const entries = await promises.readdir(dirPath, { withFileTypes: true });
2444
- const files = [];
2445
- for (const entry of entries) {
2446
- const fullPath = path.join(dirPath, entry.name);
2447
- if (entry.isFile()) {
2448
- files.push(fullPath);
2449
- } else if (entry.isDirectory() && recursive) {
2450
- const subFiles = await listFiles(fullPath, true);
2451
- files.push(...subFiles);
2452
- }
2453
- }
2454
- return files;
2455
- }
2456
- async function listDirs(dirPath) {
2457
- const entries = await promises.readdir(dirPath, { withFileTypes: true });
2458
- const dirs = [];
2459
- for (const entry of entries) {
2460
- if (entry.isDirectory()) {
2461
- dirs.push(path.join(dirPath, entry.name));
2462
- }
2463
- }
2464
- return dirs;
2465
- }
2466
- async function getFileSize$1(filePath) {
2467
- const stats = await promises.stat(filePath);
2468
- return stats.size;
2469
- }
2470
- async function getModifiedTime(filePath) {
2471
- const stats = await promises.stat(filePath);
2472
- return stats.mtime;
2473
- }
2474
- async function getCreatedTime(filePath) {
2475
- const stats = await promises.stat(filePath);
2476
- return stats.birthtime;
2477
- }
2478
- async function isReadable(filePath) {
2479
- try {
2480
- await promises.access(filePath, promises.constants.R_OK);
2481
- return true;
2482
- } catch {
2483
- return false;
2484
- }
2485
- }
2486
- async function isWritable(filePath) {
2487
- try {
2488
- await promises.access(filePath, promises.constants.W_OK);
2489
- return true;
2490
- } catch {
2491
- return false;
2492
- }
2493
- }
2494
- async function isExecutable(filePath) {
2495
- try {
2496
- await promises.access(filePath, promises.constants.X_OK);
2497
- return true;
2498
- } catch {
2499
- return false;
2500
- }
2501
- }
2502
- async function findFiles(dirPath, pattern, recursive = true) {
2503
- const allFiles = await listFiles(dirPath, recursive);
2504
- const regex = typeof pattern === "string" ? new RegExp(pattern) : pattern;
2505
- return allFiles.filter((file) => regex.test(file));
2506
- }
2507
- async function getDirSize(dirPath) {
2508
- const files = await listFiles(dirPath, true);
2509
- let totalSize = 0;
2510
- for (const file of files) {
2511
- try {
2512
- totalSize += await getFileSize$1(file);
2513
- } catch {
2514
- }
2515
- }
2516
- return totalSize;
2517
- }
2518
- async function copyDir(src, dest) {
2519
- await ensureDir(dest);
2520
- const entries = await promises.readdir(src, { withFileTypes: true });
2521
- for (const entry of entries) {
2522
- const srcPath = path.join(src, entry.name);
2523
- const destPath = path.join(dest, entry.name);
2524
- if (entry.isDirectory()) {
2525
- await copyDir(srcPath, destPath);
2526
- } else {
2527
- await copyFile(srcPath, destPath);
2528
- }
2529
- }
2530
- }
2531
- async function emptyDir(dirPath) {
2532
- if (!await exists(dirPath)) {
2533
- return;
2534
- }
2535
- const entries = await promises.readdir(dirPath);
2536
- for (const entry of entries) {
2537
- const fullPath = path.join(dirPath, entry);
2538
- const stat = await promises.stat(fullPath);
2539
- if (stat.isDirectory()) {
2540
- await deleteDir(fullPath);
2541
- } else {
2542
- await deleteFile(fullPath);
2543
- }
2544
- }
2545
- }
2546
-
2547
- const index$2 = {
2548
- __proto__: null,
2549
- appendFile: appendFile,
2550
- copyDir: copyDir,
2551
- copyFile: copyFile,
2552
- deleteDir: deleteDir,
2553
- deleteFile: deleteFile,
2554
- emptyDir: emptyDir,
2555
- ensureDir: ensureDir,
2556
- exists: exists,
2557
- findFiles: findFiles,
2558
- getCreatedTime: getCreatedTime,
2559
- getDirSize: getDirSize,
2560
- getFileSize: getFileSize$1,
2561
- getModifiedTime: getModifiedTime,
2562
- isDirectory: isDirectory,
2563
- isExecutable: isExecutable,
2564
- isFile: isFile,
2565
- isReadable: isReadable,
2566
- isWritable: isWritable,
2567
- listDirs: listDirs,
2568
- listFiles: listFiles,
2569
- moveFile: moveFile,
2570
- readFile: readFile,
2571
- readJSON: readJSON,
2572
- writeFile: writeFile,
2573
- writeJSON: writeJSON
2574
- };
2575
-
2576
- const LOG_LEVELS = {
2577
- debug: 0,
2578
- info: 1,
2579
- warn: 2,
2580
- error: 3
2581
- };
2582
- const COLORS = {
2583
- reset: "\x1B[0m",
2584
- debug: "\x1B[36m",
2585
- // Cyan
2586
- info: "\x1B[32m",
2587
- // Green
2588
- warn: "\x1B[33m",
2589
- // Yellow
2590
- error: "\x1B[31m"
2591
- // Red
2592
- };
2593
- class Logger {
2594
- level;
2595
- prefix;
2596
- timestamp;
2597
- colors;
2598
- constructor(options = {}) {
2599
- this.level = options.level || "info";
2600
- this.prefix = options.prefix || "";
2601
- this.timestamp = options.timestamp ?? true;
2602
- this.colors = options.colors ?? true;
2603
- }
2604
- shouldLog(level) {
2605
- return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
2606
- }
2607
- formatMessage(level, message, ...args) {
2608
- const parts = [];
2609
- if (this.timestamp) {
2610
- parts.push(`[${(/* @__PURE__ */ new Date()).toISOString()}]`);
2611
- }
2612
- if (this.prefix) {
2613
- parts.push(`[${this.prefix}]`);
2614
- }
2615
- parts.push(`[${level.toUpperCase()}]`);
2616
- parts.push(message);
2617
- let formatted = parts.join(" ");
2618
- if (args.length > 0) {
2619
- formatted += ` ${args.map((arg) => this.stringify(arg)).join(" ")}`;
2620
- }
2621
- if (this.colors && process.stdout.isTTY) {
2622
- return `${COLORS[level]}${formatted}${COLORS.reset}`;
2623
- }
2624
- return formatted;
2625
- }
2626
- stringify(value) {
2627
- if (typeof value === "string") {
2628
- return value;
2629
- }
2630
- if (value instanceof Error) {
2631
- return value.stack || value.message;
2632
- }
2633
- try {
2634
- return JSON.stringify(value, null, 2);
2635
- } catch {
2636
- return String(value);
2637
- }
2638
- }
2639
- debug(message, ...args) {
2640
- if (this.shouldLog("debug")) {
2641
- console.debug(this.formatMessage("debug", message, ...args));
2642
- }
2643
- }
2644
- info(message, ...args) {
2645
- if (this.shouldLog("info")) {
2646
- console.info(this.formatMessage("info", message, ...args));
2647
- }
2648
- }
2649
- warn(message, ...args) {
2650
- if (this.shouldLog("warn")) {
2651
- console.warn(this.formatMessage("warn", message, ...args));
2652
- }
2653
- }
2654
- error(message, ...args) {
2655
- if (this.shouldLog("error")) {
2656
- console.error(this.formatMessage("error", message, ...args));
2657
- }
2658
- }
2659
- setLevel(level) {
2660
- this.level = level;
2661
- }
2662
- getLevel() {
2663
- return this.level;
2664
- }
2665
- }
2666
- function createLogger(options) {
2667
- return new Logger(options);
2668
- }
2669
- const logger = createLogger();
2670
-
2671
- function deepClone(obj) {
2672
- if (obj === null || typeof obj !== "object") {
2673
- return obj;
2674
- }
2675
- if (obj instanceof Date) {
2676
- return new Date(obj.getTime());
2677
- }
2678
- if (Array.isArray(obj)) {
2679
- return obj.map((item) => deepClone(item));
2680
- }
2681
- if (obj instanceof Object) {
2682
- const clonedObj = {};
2683
- for (const key in obj) {
2684
- if (obj.hasOwnProperty(key)) {
2685
- clonedObj[key] = deepClone(obj[key]);
2686
- }
2687
- }
2688
- return clonedObj;
2689
- }
2690
- return obj;
2691
- }
2692
- function deepMerge(target, source) {
2693
- const output = { ...target };
2694
- for (const key in source) {
2695
- if (source.hasOwnProperty(key)) {
2696
- const sourceValue = source[key];
2697
- const targetValue = output[key];
2698
- if (isObject$1(sourceValue) && isObject$1(targetValue)) {
2699
- output[key] = deepMerge(targetValue, sourceValue);
2700
- } else {
2701
- output[key] = sourceValue;
2702
- }
2703
- }
2704
- }
2705
- return output;
2706
- }
2707
- function isObject$1(value) {
2708
- return value !== null && typeof value === "object" && !Array.isArray(value);
2709
- }
2710
- function get(obj, path, defaultValue) {
2711
- const keys2 = path.split(".");
2712
- let result = obj;
2713
- for (const key of keys2) {
2714
- if (result === null || result === void 0) {
2715
- return defaultValue;
2716
- }
2717
- result = result[key];
2718
- }
2719
- return result !== void 0 ? result : defaultValue;
2720
- }
2721
- function set(obj, path, value) {
2722
- const keys2 = path.split(".");
2723
- const lastKey = keys2.pop();
2724
- let current = obj;
2725
- for (const key of keys2) {
2726
- if (!(key in current) || typeof current[key] !== "object") {
2727
- current[key] = {};
2728
- }
2729
- current = current[key];
2730
- }
2731
- current[lastKey] = value;
2732
- }
2733
- function has(obj, path) {
2734
- const keys2 = path.split(".");
2735
- let current = obj;
2736
- for (const key of keys2) {
2737
- if (current === null || current === void 0 || !(key in current)) {
2738
- return false;
2739
- }
2740
- current = current[key];
2741
- }
2742
- return true;
2743
- }
2744
- function unset(obj, path) {
2745
- const keys2 = path.split(".");
2746
- const lastKey = keys2.pop();
2747
- let current = obj;
2748
- for (const key of keys2) {
2749
- if (current === null || current === void 0 || !(key in current)) {
2750
- return false;
2751
- }
2752
- current = current[key];
2753
- }
2754
- if (lastKey in current) {
2755
- delete current[lastKey];
2756
- return true;
2757
- }
2758
- return false;
2759
- }
2760
- function keys(obj, prefix = "") {
2761
- const result = [];
2762
- for (const key in obj) {
2763
- if (obj.hasOwnProperty(key)) {
2764
- const fullKey = prefix ? `${prefix}.${key}` : key;
2765
- result.push(fullKey);
2766
- if (isObject$1(obj[key])) {
2767
- result.push(...keys(obj[key], fullKey));
2768
- }
2769
- }
2770
- }
2771
- return result;
2772
- }
2773
- function values(obj) {
2774
- return Object.values(obj);
2775
- }
2776
- function entries(obj) {
2777
- return Object.entries(obj);
2778
- }
2779
- function pick(obj, keys2) {
2780
- const result = {};
2781
- for (const key of keys2) {
2782
- if (key in obj) {
2783
- result[key] = obj[key];
2784
- }
2785
- }
2786
- return result;
2787
- }
2788
- function omit(obj, keys2) {
2789
- const result = { ...obj };
2790
- for (const key of keys2) {
2791
- delete result[key];
2792
- }
2793
- return result;
2794
- }
2795
- function filter(obj, predicate) {
2796
- const result = {};
2797
- for (const [key, value] of entries(obj)) {
2798
- if (predicate(value, key)) {
2799
- result[key] = value;
2800
- }
2801
- }
2802
- return result;
2803
- }
2804
- function map(obj, mapper) {
2805
- const result = {};
2806
- for (const [key, value] of entries(obj)) {
2807
- result[key] = mapper(value, key);
2808
- }
2809
- return result;
2810
- }
2811
- function isEmpty(obj) {
2812
- return Object.keys(obj).length === 0;
2813
- }
2814
- function flatten(obj, prefix = "", separator = ".") {
2815
- const result = {};
2816
- for (const key in obj) {
2817
- if (obj.hasOwnProperty(key)) {
2818
- const fullKey = prefix ? `${prefix}${separator}${key}` : key;
2819
- if (isObject$1(obj[key]) && !Array.isArray(obj[key])) {
2820
- Object.assign(result, flatten(obj[key], fullKey, separator));
2821
- } else {
2822
- result[fullKey] = obj[key];
2823
- }
2824
- }
2825
- }
2826
- return result;
2827
- }
2828
- function unflatten(obj, separator = ".") {
2829
- const result = {};
2830
- for (const [key, value] of entries(obj)) {
2831
- set(result, key.replace(new RegExp(separator, "g"), "."), value);
2832
- }
2833
- return result;
2834
- }
2835
- function invert(obj) {
2836
- const result = {};
2837
- for (const [key, value] of entries(obj)) {
2838
- result[value] = key;
2839
- }
2840
- return result;
2841
- }
2842
- function groupBy(arr, key) {
2843
- const result = {};
2844
- for (const item of arr) {
2845
- const groupKey = typeof key === "function" ? key(item) : String(item[key]);
2846
- if (!result[groupKey]) {
2847
- result[groupKey] = [];
2848
- }
2849
- result[groupKey].push(item);
2850
- }
2851
- return result;
2852
- }
2853
- function keyBy(arr, key) {
2854
- const result = {};
2855
- for (const item of arr) {
2856
- const itemKey = typeof key === "function" ? key(item) : String(item[key]);
2857
- result[itemKey] = item;
2858
- }
2859
- return result;
2860
- }
2861
- function isEqual(obj1, obj2) {
2862
- if (obj1 === obj2)
2863
- return true;
2864
- if (typeof obj1 !== "object" || typeof obj2 !== "object" || obj1 === null || obj2 === null) {
2865
- return false;
2866
- }
2867
- const keys1 = Object.keys(obj1);
2868
- const keys2 = Object.keys(obj2);
2869
- if (keys1.length !== keys2.length)
2870
- return false;
2871
- for (const key of keys1) {
2872
- if (!keys2.includes(key) || !isEqual(obj1[key], obj2[key])) {
2873
- return false;
2874
- }
2875
- }
2876
- return true;
2877
- }
2878
- function compact(obj) {
2879
- const result = {};
2880
- for (const [key, value] of entries(obj)) {
2881
- if (value !== null && value !== void 0) {
2882
- result[key] = value;
2883
- }
2884
- }
2885
- return result;
2886
- }
2887
- function deepFreeze(obj) {
2888
- Object.freeze(obj);
2889
- for (const key in obj) {
2890
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
2891
- const value = obj[key];
2892
- if (typeof value === "object" && value !== null) {
2893
- deepFreeze(value);
2894
- }
2895
- }
2896
- }
2897
- return obj;
2898
- }
2899
- function merge(...objects) {
2900
- return objects.reduce((acc, obj) => ({ ...acc, ...obj }), {});
2901
- }
2902
- function size(obj) {
2903
- return Object.keys(obj).length;
2904
- }
2905
-
2906
- const index$1 = {
2907
- __proto__: null,
2908
- compact: compact,
2909
- deepClone: deepClone,
2910
- deepFreeze: deepFreeze,
2911
- deepMerge: deepMerge,
2912
- entries: entries,
2913
- filter: filter,
2914
- flatten: flatten,
2915
- get: get,
2916
- groupBy: groupBy,
2917
- has: has,
2918
- invert: invert,
2919
- isEmpty: isEmpty,
2920
- isEqual: isEqual,
2921
- keyBy: keyBy,
2922
- keys: keys,
2923
- map: map,
2924
- merge: merge,
2925
- omit: omit,
2926
- pick: pick,
2927
- set: set,
2928
- size: size,
2929
- unflatten: unflatten,
2930
- unset: unset,
2931
- values: values
2932
- };
2933
-
2934
- function getPlatform() {
2935
- const platform = os.platform();
2936
- if (platform === "darwin" || platform === "linux" || platform === "win32") {
2937
- return platform;
2938
- }
2939
- return "unknown";
2940
- }
2941
- function getArchitecture() {
2942
- const arch = os.arch();
2943
- if (arch === "x64" || arch === "arm64" || arch === "ia32") {
2944
- return arch;
2945
- }
2946
- return "unknown";
2947
- }
2948
- function isMacOS() {
2949
- return getPlatform() === "darwin";
2950
- }
2951
- function isLinux() {
2952
- return getPlatform() === "linux";
2953
- }
2954
- function isWindows() {
2955
- return getPlatform() === "win32";
2956
- }
2957
- function isUnix() {
2958
- return isMacOS() || isLinux();
2959
- }
2960
- function getPlatformInfo() {
2961
- return {
2962
- platform: getPlatform(),
2963
- architecture: getArchitecture(),
2964
- release: os.release(),
2965
- hostname: os.hostname(),
2966
- homedir: os.homedir(),
2967
- tmpdir: os.tmpdir(),
2968
- cpus: os.cpus().length,
2969
- totalMemory: os.totalmem(),
2970
- freeMemory: os.freemem()
2971
- };
2972
- }
2973
-
2974
- function getHomeDir() {
2975
- return os.homedir();
2976
- }
2977
- function getConfigDir(appName) {
2978
- const home = getHomeDir();
2979
- if (isWindows()) {
2980
- const appData = process.env.APPDATA || path.join(home, "AppData", "Roaming");
2981
- return appName ? path.join(appData, appName) : appData;
2982
- }
2983
- if (isMacOS()) {
2984
- const configDir2 = path.join(home, "Library", "Application Support");
2985
- return appName ? path.join(configDir2, appName) : configDir2;
2986
- }
2987
- const configDir = process.env.XDG_CONFIG_HOME || path.join(home, ".config");
2988
- return appName ? path.join(configDir, appName) : configDir;
2989
- }
2990
- function getDataDir(appName) {
2991
- const home = getHomeDir();
2992
- if (isWindows()) {
2993
- const localAppData = process.env.LOCALAPPDATA || path.join(home, "AppData", "Local");
2994
- return appName ? path.join(localAppData, appName) : localAppData;
2995
- }
2996
- if (isMacOS()) {
2997
- const dataDir2 = path.join(home, "Library", "Application Support");
2998
- return appName ? path.join(dataDir2, appName) : dataDir2;
2999
- }
3000
- const dataDir = process.env.XDG_DATA_HOME || path.join(home, ".local", "share");
3001
- return appName ? path.join(dataDir, appName) : dataDir;
3002
- }
3003
- function getCacheDir(appName) {
3004
- const home = getHomeDir();
3005
- if (isWindows()) {
3006
- const temp = os.tmpdir();
3007
- return appName ? path.join(temp, appName) : temp;
3008
- }
3009
- if (isMacOS()) {
3010
- const cacheDir2 = path.join(home, "Library", "Caches");
3011
- return appName ? path.join(cacheDir2, appName) : cacheDir2;
3012
- }
3013
- const cacheDir = process.env.XDG_CACHE_HOME || path.join(home, ".cache");
3014
- return appName ? path.join(cacheDir, appName) : cacheDir;
3015
- }
3016
- function getTempDir(appName) {
3017
- const temp = os.tmpdir();
3018
- return appName ? path.join(temp, appName) : temp;
3019
- }
3020
-
3021
- const DEFAULT_CHUNK_SIZE = 1024 * 1024;
3022
- async function processLargeFile(filePath, processor, options = {}) {
3023
- const { chunkSize = DEFAULT_CHUNK_SIZE, encoding = "utf8" } = options;
3024
- return new Promise((resolve, reject) => {
3025
- const stream = createReadStream(filePath, { encoding });
3026
- const chunks = [];
3027
- let chunkIndex = 0;
3028
- stream.on("data", (chunk) => {
3029
- const buffer = typeof chunk === "string" ? Buffer.from(chunk, encoding) : chunk;
3030
- chunks.push(buffer);
3031
- if (chunks.length * chunkSize >= chunkSize) {
3032
- const combined = Buffer.concat(chunks);
3033
- processor(combined, chunkIndex++);
3034
- chunks.length = 0;
3035
- }
3036
- });
3037
- stream.on("end", () => {
3038
- if (chunks.length > 0) {
3039
- const combined = Buffer.concat(chunks);
3040
- processor(combined, chunkIndex);
3041
- }
3042
- resolve();
3043
- });
3044
- stream.on("error", reject);
3045
- });
3046
- }
3047
- async function streamJSON(filePath, _options = {}) {
3048
- const chunks = [];
3049
- await pipeline(
3050
- createReadStream(filePath, { encoding: "utf8" }),
3051
- new Transform({
3052
- transform(chunk, _, callback) {
3053
- chunks.push(chunk);
3054
- callback();
3055
- }
3056
- })
3057
- );
3058
- const content = Buffer.concat(chunks).toString("utf8");
3059
- return JSON.parse(content);
3060
- }
3061
- async function streamWriteJSON(filePath, data, _options = {}) {
3062
- await promises.writeFile(filePath, JSON.stringify(data, null, 2), "utf8");
3063
- }
3064
- async function processLineByLine(filePath, processor) {
3065
- const readline = await import('node:readline');
3066
- const rl = readline.createInterface({
3067
- input: createReadStream(filePath, { encoding: "utf8" }),
3068
- crlfDelay: Number.MAX_VALUE
3069
- // Treat \r\n as single character
3070
- });
3071
- let index = 0;
3072
- for await (const line of rl) {
3073
- await Promise.resolve(processor(line, index++));
3074
- }
3075
- rl.close();
3076
- }
3077
- async function getFileSize(filePath) {
3078
- try {
3079
- const stats = await promises.stat(filePath);
3080
- return stats.size;
3081
- } catch {
3082
- return 0;
3083
- }
3084
- }
3085
- async function countLines(filePath) {
3086
- let count = 0;
3087
- await processLineByLine(filePath, () => {
3088
- count++;
3089
- });
3090
- return count;
3091
- }
3092
- async function batchProcessFiles(filePaths, processor, concurrency = 3) {
3093
- const results = /* @__PURE__ */ new Map();
3094
- const queue = [...filePaths];
3095
- const processing = /* @__PURE__ */ new Set();
3096
- const processNext = async () => {
3097
- while (queue.length > 0 && processing.size < concurrency) {
3098
- const file = queue.shift();
3099
- processing.add(file);
3100
- try {
3101
- const result = await processor(file);
3102
- results.set(file, result);
3103
- } catch (_error) {
3104
- results.set(file, null);
3105
- } finally {
3106
- processing.delete(file);
3107
- }
3108
- }
3109
- };
3110
- const workers = Array.from({ length: Math.min(concurrency, queue.length) });
3111
- for (let i = 0; i < workers.length; i++) {
3112
- processNext().then(() => {
3113
- });
3114
- }
3115
- await Promise.all(workers);
3116
- return results;
3117
- }
3118
- async function isLargeFile(filePath, threshold = 1024 * 1024) {
3119
- return await getFileSize(filePath) > threshold;
3120
- }
3121
- async function getFileInfo(filePath, options = {}) {
3122
- const size = await getFileSize(filePath);
3123
- const isLarge = size > (options.chunkSize || DEFAULT_CHUNK_SIZE);
3124
- const lines = isLarge ? await countLines(filePath) : 0;
3125
- return {
3126
- path: filePath,
3127
- size,
3128
- lines,
3129
- isLarge,
3130
- encoding: options.encoding || null
3131
- };
3132
- }
3133
-
3134
- function capitalize(str) {
3135
- if (!str)
3136
- return str;
3137
- return str.charAt(0).toUpperCase() + str.slice(1);
3138
- }
3139
- function camelCase(str) {
3140
- return str.replace(/^\w|[A-Z]|\b\w/g, (letter, index) => index === 0 ? letter.toLowerCase() : letter.toUpperCase()).replace(/\s+/g, "").replace(/[-_]/g, "");
3141
- }
3142
- function pascalCase(str) {
3143
- return str.replace(/^\w|[A-Z]|\b\w/g, (letter) => letter.toUpperCase()).replace(/\s+/g, "").replace(/[-_]/g, "");
3144
- }
3145
- function snakeCase(str) {
3146
- return str.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/\s+/g, "_").replace(/-/g, "_").replace(/^_/, "");
3147
- }
3148
- function kebabCase(str) {
3149
- return str.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/\s+/g, "-").replace(/_/g, "-").replace(/^-/, "");
3150
- }
3151
- function constantCase(str) {
3152
- return snakeCase(str).toUpperCase();
3153
- }
3154
- function truncate(str, length, suffix = "...") {
3155
- if (str.length <= length)
3156
- return str;
3157
- return str.slice(0, length - suffix.length) + suffix;
3158
- }
3159
- function pad(str, length, char = " ", direction = "right") {
3160
- if (str.length >= length)
3161
- return str;
3162
- const padLength = length - str.length;
3163
- if (direction === "left") {
3164
- return char.repeat(padLength) + str;
3165
- } else if (direction === "right") {
3166
- return str + char.repeat(padLength);
3167
- } else {
3168
- const leftPad = Math.floor(padLength / 2);
3169
- const rightPad = padLength - leftPad;
3170
- return char.repeat(leftPad) + str + char.repeat(rightPad);
3171
- }
3172
- }
3173
- function trim(str) {
3174
- return str.trim();
3175
- }
3176
- function trimStart(str) {
3177
- return str.trimStart();
3178
- }
3179
- function trimEnd(str) {
3180
- return str.trimEnd();
3181
- }
3182
- function split(str, delimiter) {
3183
- return str.split(delimiter);
3184
- }
3185
- function join(arr, separator = "") {
3186
- return arr.join(separator);
3187
- }
3188
- function replaceAll(str, search, replacement) {
3189
- if (typeof search === "string") {
3190
- return str.split(search).join(replacement);
3191
- }
3192
- return str.replace(new RegExp(search, "g"), replacement);
3193
- }
3194
- function startsWith(str, prefix) {
3195
- return str.startsWith(prefix);
3196
- }
3197
- function endsWith(str, suffix) {
3198
- return str.endsWith(suffix);
3199
- }
3200
- function contains(str, substring) {
3201
- return str.includes(substring);
3202
- }
3203
- function countOccurrences(str, substring) {
3204
- return str.split(substring).length - 1;
3205
- }
3206
- function reverse(str) {
3207
- return str.split("").reverse().join("");
3208
- }
3209
- function removeWhitespace(str) {
3210
- return str.replace(/\s+/g, "");
3211
- }
3212
- function normalizeWhitespace(str) {
3213
- return str.replace(/\s+/g, " ").trim();
3214
- }
3215
- function words(str) {
3216
- return str.match(/\b\w+\b/g) || [];
3217
- }
3218
- function wordCount(str) {
3219
- return words(str).length;
3220
- }
3221
- function titleCase(str) {
3222
- return str.toLowerCase().split(" ").map((word) => capitalize(word)).join(" ");
3223
- }
3224
- function sentenceCase(str) {
3225
- return capitalize(str.toLowerCase());
3226
- }
3227
- function escapeHTML(str) {
3228
- const htmlEscapes = {
3229
- "&": "&amp;",
3230
- "<": "&lt;",
3231
- ">": "&gt;",
3232
- '"': "&quot;",
3233
- "'": "&#39;"
3234
- };
3235
- return str.replace(/[&<>"']/g, (char) => htmlEscapes[char]);
3236
- }
3237
- function unescapeHTML(str) {
3238
- const htmlUnescapes = {
3239
- "&amp;": "&",
3240
- "&lt;": "<",
3241
- "&gt;": ">",
3242
- "&quot;": '"',
3243
- "&#39;": "'"
3244
- };
3245
- return str.replace(/&(?:amp|lt|gt|quot|#39);/g, (entity) => htmlUnescapes[entity]);
3246
- }
3247
- function escapeRegExp(str) {
3248
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3249
- }
3250
- function randomString(length, charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") {
3251
- let result = "";
3252
- for (let i = 0; i < length; i++) {
3253
- result += charset.charAt(Math.floor(Math.random() * charset.length));
3254
- }
3255
- return result;
3256
- }
3257
- function uuid() {
3258
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
3259
- const r = Math.random() * 16 | 0;
3260
- const v = c === "x" ? r : r & 3 | 8;
3261
- return v.toString(16);
3262
- });
3263
- }
3264
- function slugify(str) {
3265
- return str.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
3266
- }
3267
- function extractNumbers(str) {
3268
- const matches = str.match(/-?\d+\.?\d*/g);
3269
- return matches ? matches.map(Number) : [];
3270
- }
3271
- function template(str, values) {
3272
- return str.replace(/\{(\w+)\}/g, (match, key) => {
3273
- return values[key] !== void 0 ? String(values[key]) : match;
3274
- });
3275
- }
3276
- function repeat(str, count) {
3277
- return str.repeat(count);
3278
- }
3279
- function isBlank(str) {
3280
- return !str || str.trim().length === 0;
3281
- }
3282
- function ensureSuffix(str, suffix) {
3283
- return endsWith(str, suffix) ? str : str + suffix;
3284
- }
3285
- function ensurePrefix(str, prefix) {
3286
- return startsWith(str, prefix) ? str : prefix + str;
3287
- }
3288
- function removePrefix(str, prefix) {
3289
- return startsWith(str, prefix) ? str.slice(prefix.length) : str;
3290
- }
3291
- function removeSuffix(str, suffix) {
3292
- return endsWith(str, suffix) ? str.slice(0, -suffix.length) : str;
3293
- }
3294
-
3295
- const index = {
3296
- __proto__: null,
3297
- camelCase: camelCase,
3298
- capitalize: capitalize,
3299
- constantCase: constantCase,
3300
- contains: contains,
3301
- countOccurrences: countOccurrences,
3302
- endsWith: endsWith,
3303
- ensurePrefix: ensurePrefix,
3304
- ensureSuffix: ensureSuffix,
3305
- escapeHTML: escapeHTML,
3306
- escapeRegExp: escapeRegExp,
3307
- extractNumbers: extractNumbers,
3308
- isBlank: isBlank,
3309
- join: join,
3310
- kebabCase: kebabCase,
3311
- normalizeWhitespace: normalizeWhitespace,
3312
- pad: pad,
3313
- pascalCase: pascalCase,
3314
- randomString: randomString,
3315
- removePrefix: removePrefix,
3316
- removeSuffix: removeSuffix,
3317
- removeWhitespace: removeWhitespace,
3318
- repeat: repeat,
3319
- replaceAll: replaceAll,
3320
- reverse: reverse,
3321
- sentenceCase: sentenceCase,
3322
- slugify: slugify,
3323
- snakeCase: snakeCase,
3324
- split: split,
3325
- startsWith: startsWith,
3326
- template: template,
3327
- titleCase: titleCase,
3328
- trim: trim,
3329
- trimEnd: trimEnd,
3330
- trimStart: trimStart,
3331
- truncate: truncate,
3332
- unescapeHTML: unescapeHTML,
3333
- uuid: uuid,
3334
- wordCount: wordCount,
3335
- words: words
3336
- };
3337
-
3338
- function validateArrayAccess(array, index) {
3339
- if (!Array.isArray(array)) {
3340
- return { valid: false, error: "Input is not an array" };
3341
- }
3342
- if (index < 0 || index >= array.length) {
3343
- return { valid: false, error: `Index ${index} out of bounds for array of length ${array.length}` };
3344
- }
3345
- return { valid: true };
3346
- }
3347
- function safeArrayAccess(array, index, defaultValue) {
3348
- const validation = validateArrayAccess(array, index);
3349
- if (!validation.valid) {
3350
- return defaultValue;
3351
- }
3352
- return array[index];
3353
- }
3354
- function validateObjectKeyAccess(obj, key) {
3355
- if (!obj || typeof obj !== "object") {
3356
- return { valid: false, error: "Input is not an object" };
3357
- }
3358
- if (!(key in obj)) {
3359
- return { valid: false, error: `Key "${key}" not found in object` };
3360
- }
3361
- return { valid: true };
3362
- }
3363
- function safeObjectAccess(obj, key, defaultValue) {
3364
- if (!obj || typeof obj !== "object") {
3365
- return defaultValue;
3366
- }
3367
- return key in obj ? obj[key] : defaultValue;
3368
- }
3369
- function isValidEnvVarName(name) {
3370
- if (!name || typeof name !== "string") {
3371
- return { valid: false, error: "Environment variable name must be a non-empty string" };
3372
- }
3373
- if (!/^[A-Z_][A-Z0-9_]*$/.test(name)) {
3374
- return {
3375
- valid: false,
3376
- error: "Environment variable name must start with letter or underscore and contain only uppercase letters, numbers, and underscores"
3377
- };
3378
- }
3379
- return { valid: true };
3380
- }
3381
- function sanitizeEnvValue(value) {
3382
- if (!value || typeof value !== "string") {
3383
- return "";
3384
- }
3385
- return value.replace(/[\n\r\0]/g, "");
3386
- }
3387
- function isValidUrl(url) {
3388
- if (!url || typeof url !== "string") {
3389
- return { valid: false, error: "URL must be a non-empty string" };
3390
- }
3391
- if (url.length > 2048) {
3392
- return { valid: false, error: "URL is too long (max 2048 characters)" };
3393
- }
3394
- try {
3395
- const parsed = new URL(url);
3396
- if (!["http:", "https:"].includes(parsed.protocol)) {
3397
- return { valid: false, error: "URL must use http:// or https://" };
3398
- }
3399
- if (!parsed.hostname) {
3400
- return { valid: false, error: "URL must have a valid hostname" };
3401
- }
3402
- return { valid: true };
3403
- } catch {
3404
- return { valid: false, error: "Invalid URL format" };
3405
- }
3406
- }
3407
- function isValidFilePath(path) {
3408
- if (!path || typeof path !== "string") {
3409
- return { valid: false, error: "Path must be a non-empty string" };
3410
- }
3411
- if (path.includes("..")) {
3412
- return { valid: false, error: "Path contains directory traversal characters (..)" };
3413
- }
3414
- if (path.includes("\0")) {
3415
- return { valid: false, error: "Path contains null bytes" };
3416
- }
3417
- return { valid: true };
3418
- }
3419
- function isValidPathEntry(entry) {
3420
- if (!entry || typeof entry !== "string") {
3421
- return { valid: false, error: "Path entry must be a non-empty string" };
3422
- }
3423
- if (entry.includes("..") || entry.includes("/") || entry.includes("\\")) {
3424
- return { valid: false, error: "Path entry contains invalid characters" };
3425
- }
3426
- if (entry.includes("\0")) {
3427
- return { valid: false, error: "Path entry contains null bytes" };
3428
- }
3429
- return { valid: true };
3430
- }
3431
- function validateUserInput(input, options = {}) {
3432
- if (!input || typeof input !== "string") {
3433
- return { valid: false, error: "Input must be a non-empty string" };
3434
- }
3435
- const trimmed = input.trim();
3436
- if (trimmed.length === 0) {
3437
- return { valid: false, error: "Input cannot be empty" };
3438
- }
3439
- const { minLength = 1, maxLength = 1e3, pattern, allowedChars } = options;
3440
- if (trimmed.length < minLength) {
3441
- return { valid: false, error: `Input must be at least ${minLength} characters` };
3442
- }
3443
- if (trimmed.length > maxLength) {
3444
- return { valid: false, error: `Input must not exceed ${maxLength} characters` };
3445
- }
3446
- if (pattern && !pattern.test(trimmed)) {
3447
- return { valid: false, error: "Input contains invalid characters" };
3448
- }
3449
- if (allowedChars) {
3450
- const allowedSet = new Set(allowedChars);
3451
- for (const char of trimmed) {
3452
- if (!allowedSet.has(char)) {
3453
- return { valid: false, error: `Input contains disallowed character: ${char}` };
3454
- }
3455
- }
3456
- }
3457
- return { valid: true };
3458
- }
3459
- function sanitizeUserInput(input, maxLength = 1e3) {
3460
- if (!input || typeof input !== "string") {
3461
- return "";
3462
- }
3463
- return input.trim().slice(0, maxLength);
3464
- }
3465
- function isValidApiKey(apiKey) {
3466
- if (!apiKey || typeof apiKey !== "string") {
3467
- return { valid: false, error: "API key must be a non-empty string" };
3468
- }
3469
- if (apiKey.length < 10) {
3470
- return { valid: false, error: "API key is too short" };
3471
- }
3472
- if (apiKey.length > 500) {
3473
- return { valid: false, error: "API key is too long" };
3474
- }
3475
- if (/\s/.test(apiKey)) {
3476
- return { valid: false, error: "API key contains whitespace" };
3477
- }
3478
- return { valid: true };
3479
- }
3480
- function formatApiKeyDisplay(apiKey) {
3481
- if (!apiKey || typeof apiKey !== "string" || apiKey.length < 12) {
3482
- return "***";
3483
- }
3484
- return `${apiKey.substring(0, 8)}...${apiKey.substring(apiKey.length - 4)}`;
3485
- }
3486
- function validateConfigStructure(config, schema) {
3487
- if (!config || typeof config !== "object") {
3488
- return { valid: false, error: "Config must be an object" };
3489
- }
3490
- const configObj = config;
3491
- for (const [key, expectedType] of Object.entries(schema)) {
3492
- if (!(key in configObj)) {
3493
- return { valid: false, error: `Missing required field: ${key}` };
3494
- }
3495
- const value = configObj[key];
3496
- const actualType = Array.isArray(value) ? "array" : typeof value;
3497
- if (actualType !== expectedType) {
3498
- return {
3499
- valid: false,
3500
- error: `Field "${key}" has wrong type. Expected ${expectedType}, got ${actualType}`
3501
- };
3502
- }
3503
- }
3504
- return { valid: true };
3505
- }
3506
- function validateArray(array, validator) {
3507
- if (!Array.isArray(array)) {
3508
- return { valid: false, error: "Input is not an array" };
3509
- }
3510
- for (let i = 0; i < array.length; i++) {
3511
- const result = validator(array[i]);
3512
- if (!result.valid) {
3513
- return { valid: false, error: `Item at index ${i}: ${result.error}` };
3514
- }
3515
- }
3516
- return { valid: true };
3517
- }
3518
- function isValidEnumValue(value, allowedValues) {
3519
- if (!allowedValues.includes(value)) {
3520
- return {
3521
- valid: false,
3522
- error: `Invalid value. Must be one of: ${allowedValues.join(", ")}`
3523
- };
3524
- }
3525
- return { valid: true };
3526
- }
3527
- function isValidPort(port) {
3528
- if (typeof port !== "number" && typeof port !== "string") {
3529
- return { valid: false, error: "Port must be a number or string" };
3530
- }
3531
- const portNum = typeof port === "string" ? Number.parseInt(port, 10) : port;
3532
- if (!Number.isInteger(portNum) || portNum < 1 || portNum > 65535) {
3533
- return { valid: false, error: "Port must be between 1 and 65535" };
3534
- }
3535
- return { valid: true };
3536
- }
3537
- function isValidHostname(hostname) {
3538
- if (!hostname || typeof hostname !== "string") {
3539
- return { valid: false, error: "Hostname must be a non-empty string" };
3540
- }
3541
- if (hostname.length > 253) {
3542
- return { valid: false, error: "Hostname is too long (max 253 characters)" };
3543
- }
3544
- if (!/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)*[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/i.test(hostname)) {
3545
- return { valid: false, error: "Invalid hostname format" };
3546
- }
3547
- return { valid: true };
3548
- }
3549
-
3550
- const validation = {
3551
- __proto__: null,
3552
- formatApiKeyDisplay: formatApiKeyDisplay,
3553
- isValidApiKey: isValidApiKey,
3554
- isValidEnumValue: isValidEnumValue,
3555
- isValidEnvVarName: isValidEnvVarName,
3556
- isValidFilePath: isValidFilePath,
3557
- isValidHostname: isValidHostname,
3558
- isValidPathEntry: isValidPathEntry,
3559
- isValidPort: isValidPort,
3560
- isValidUrl: isValidUrl,
3561
- safeArrayAccess: safeArrayAccess,
3562
- safeObjectAccess: safeObjectAccess,
3563
- sanitizeEnvValue: sanitizeEnvValue,
3564
- sanitizeUserInput: sanitizeUserInput,
3565
- validateArray: validateArray,
3566
- validateArrayAccess: validateArrayAccess,
3567
- validateConfigStructure: validateConfigStructure,
3568
- validateObjectKeyAccess: validateObjectKeyAccess,
3569
- validateUserInput: validateUserInput
3570
- };
3571
-
3572
- function isDefined(value) {
3573
- return value !== null && value !== void 0;
3574
- }
3575
- function isString(value) {
3576
- return typeof value === "string";
3577
- }
3578
- function isNumber(value) {
3579
- return typeof value === "number" && !isNaN(value);
3580
- }
3581
- function isBoolean(value) {
3582
- return typeof value === "boolean";
3583
- }
3584
- function isObject(value) {
3585
- return typeof value === "object" && value !== null && !Array.isArray(value);
3586
- }
3587
- function isArray(value) {
3588
- return Array.isArray(value);
3589
- }
3590
- function isEmail(value) {
3591
- const emailRegex = /^[^\s@]+@[^\s@][^\s.@]*\.[^\s@]+$/;
3592
- return emailRegex.test(value);
3593
- }
3594
- function isURL(value) {
3595
- try {
3596
- new URL(value);
3597
- return true;
3598
- } catch {
3599
- return false;
3600
- }
3601
- }
3602
- function assertDefined(value, message) {
3603
- if (!isDefined(value)) {
3604
- throw new Error(message || "Value is null or undefined");
3605
- }
3606
- }
3607
- function assert(condition, message) {
3608
- if (!condition) {
3609
- throw new Error(message || "Assertion failed");
3610
- }
3611
- }
3612
-
3613
- async function getCloudRecommendedHooks(projectInfo, options = {}) {
3614
- const { includeCommunity = true, includePremium = false, limit = 10 } = options;
3615
- try {
3616
- const recommendations = await fetchCloudRecommendations(projectInfo, {
3617
- includeCommunity,
3618
- includePremium,
3619
- limit
3620
- });
3621
- return recommendations;
3622
- } catch (error) {
3623
- console.error("Failed to fetch cloud recommendations:", error);
3624
- return [];
3625
- }
3626
- }
3627
- async function fetchCloudRecommendations(projectInfo, options) {
3628
- const recommendations = [];
3629
- const baseRecommendations = getBaseRecommendations(projectInfo);
3630
- recommendations.push(...baseRecommendations);
3631
- if (projectInfo.frameworks?.length > 0) {
3632
- const frameworkRecs = getFrameworkRecommendations(projectInfo);
3633
- recommendations.push(...frameworkRecs);
3634
- }
3635
- if (projectInfo.configFiles?.length > 0) {
3636
- const toolRecs = getToolRecommendations(projectInfo);
3637
- recommendations.push(...toolRecs);
3638
- }
3639
- let filtered = recommendations;
3640
- if (!options.includeCommunity) {
3641
- filtered = filtered.filter((r) => r.metadata?.tags?.includes("official"));
3642
- }
3643
- if (!options.includePremium) {
3644
- filtered = filtered.filter((r) => !r.metadata?.tags?.includes("premium"));
3645
- }
3646
- if (options.limit > 0) {
3647
- filtered = filtered.slice(0, options.limit);
3648
- }
3649
- filtered.sort((a, b) => (b.priority || 0) - (a.priority || 0));
3650
- return filtered;
3651
- }
3652
- function getBaseRecommendations(projectInfo) {
3653
- const recommendations = [];
3654
- const projectType = projectInfo.projectType.toLowerCase();
3655
- if (projectType.includes("typescript") || projectType.includes("javascript")) {
3656
- recommendations.push(
3657
- {
3658
- name: "cloud-pre-commit-security",
3659
- description: "Advanced security scanning (Cloud)",
3660
- type: "pre-commit",
3661
- category: "pre-commit",
3662
- projectTypes: ["typescript", "javascript"],
3663
- trigger: {
3664
- matcher: "git:pre-commit"
3665
- },
3666
- action: {
3667
- command: "ccjk-cloud",
3668
- args: ["scan", "security", "--staged"],
3669
- timeout: 6e4
3670
- },
3671
- enabled: true,
3672
- priority: 200,
3673
- metadata: {
3674
- tags: ["official", "security", "cloud"],
3675
- version: "1.0.0"
3676
- }
3677
- },
3678
- {
3679
- name: "cloud-dependency-check",
3680
- description: "Check for vulnerable dependencies",
3681
- type: "pre-commit",
3682
- category: "pre-commit",
3683
- projectTypes: ["typescript", "javascript"],
3684
- trigger: {
3685
- matcher: "git:pre-commit",
3686
- condition: "package-lock.json || yarn.lock || pnpm-lock.yaml"
3687
- },
3688
- action: {
3689
- command: "ccjk-cloud",
3690
- args: ["audit", "dependencies"],
3691
- timeout: 3e4
3692
- },
3693
- enabled: true,
3694
- priority: 190,
3695
- metadata: {
3696
- tags: ["official", "security", "cloud"],
3697
- version: "1.0.0"
3698
- }
3699
- }
3700
- );
3701
- }
3702
- if (projectType.includes("python")) {
3703
- recommendations.push(
3704
- {
3705
- name: "cloud-python-security",
3706
- description: "Python security analysis",
3707
- type: "pre-commit",
3708
- category: "pre-commit",
3709
- projectTypes: ["python"],
3710
- trigger: {
3711
- matcher: "git:pre-commit"
3712
- },
3713
- action: {
3714
- command: "ccjk-cloud",
3715
- args: ["scan", "python-security"],
3716
- timeout: 45e3
3717
- },
3718
- enabled: true,
3719
- priority: 200,
3720
- metadata: {
3721
- tags: ["official", "security", "cloud"],
3722
- version: "1.0.0"
3723
- }
3724
- }
3725
- );
3726
- }
3727
- if (projectType.includes("rust")) {
3728
- recommendations.push(
3729
- {
3730
- name: "cloud-rust-audit",
3731
- description: "Audit Rust dependencies for vulnerabilities",
3732
- type: "pre-commit",
3733
- category: "pre-commit",
3734
- projectTypes: ["rust"],
3735
- trigger: {
3736
- matcher: "git:pre-commit",
3737
- condition: "Cargo.lock"
3738
- },
3739
- action: {
3740
- command: "ccjk-cloud",
3741
- args: ["audit", "cargo"],
3742
- timeout: 3e4
3743
- },
3744
- enabled: true,
3745
- priority: 200,
3746
- metadata: {
3747
- tags: ["official", "security", "cloud"],
3748
- version: "1.0.0"
3749
- }
3750
- }
3751
- );
3752
- }
3753
- return recommendations;
3754
- }
3755
- function getFrameworkRecommendations(projectInfo) {
3756
- const recommendations = [];
3757
- for (const framework of projectInfo.frameworks) {
3758
- const frameworkName = framework.name.toLowerCase();
3759
- if (frameworkName.includes("react")) {
3760
- recommendations.push(
3761
- {
3762
- name: "cloud-react-performance",
3763
- description: "Analyze React bundle performance",
3764
- type: "post-build",
3765
- category: "lifecycle",
3766
- projectTypes: ["typescript", "javascript"],
3767
- trigger: {
3768
- matcher: "command:*build*"
3769
- },
3770
- action: {
3771
- command: "ccjk-cloud",
3772
- args: ["analyze", "react-bundle"],
3773
- timeout: 3e4
3774
- },
3775
- enabled: true,
3776
- priority: 150,
3777
- metadata: {
3778
- tags: ["official", "react", "performance", "cloud"],
3779
- version: "1.0.0"
3780
- }
3781
- }
3782
- );
3783
- }
3784
- if (frameworkName.includes("vue")) {
3785
- recommendations.push(
3786
- {
3787
- name: "cloud-vue-analysis",
3788
- description: "Vue specific code analysis",
3789
- type: "pre-commit",
3790
- category: "pre-commit",
3791
- projectTypes: ["typescript", "javascript"],
3792
- trigger: {
3793
- matcher: "git:pre-commit"
3794
- },
3795
- action: {
3796
- command: "ccjk-cloud",
3797
- args: ["analyze", "vue"],
3798
- timeout: 2e4
3799
- },
3800
- enabled: true,
3801
- priority: 150,
3802
- metadata: {
3803
- tags: ["official", "vue", "cloud"],
3804
- version: "1.0.0"
3805
- }
3806
- }
3807
- );
3808
- }
3809
- if (frameworkName.includes("django")) {
3810
- recommendations.push(
3811
- {
3812
- name: "cloud-django-checks",
3813
- description: "Run Django system checks",
3814
- type: "pre-commit",
3815
- category: "pre-commit",
3816
- projectTypes: ["python"],
3817
- trigger: {
3818
- matcher: "git:pre-commit",
3819
- condition: "*.py"
3820
- },
3821
- action: {
3822
- command: "ccjk-cloud",
3823
- args: ["django", "checks"],
3824
- timeout: 15e3
3825
- },
3826
- enabled: true,
3827
- priority: 150,
3828
- metadata: {
3829
- tags: ["official", "django", "cloud"],
3830
- version: "1.0.0"
3831
- }
3832
- }
3833
- );
3834
- }
3835
- }
3836
- return recommendations;
3837
- }
3838
- function getToolRecommendations(projectInfo) {
3839
- const recommendations = [];
3840
- const configFiles = projectInfo.configFiles || [];
3841
- if (configFiles.some((f) => f.includes("eslint"))) {
3842
- recommendations.push({
3843
- name: "cloud-eslint-advanced",
3844
- description: "Advanced ESLint analysis with custom rules",
3845
- type: "pre-commit",
3846
- category: "pre-commit",
3847
- projectTypes: ["typescript", "javascript"],
3848
- trigger: {
3849
- matcher: "git:pre-commit"
3850
- },
3851
- action: {
3852
- command: "ccjk-cloud",
3853
- args: ["lint", "eslint", "--advanced"],
3854
- timeout: 25e3
3855
- },
3856
- enabled: true,
3857
- priority: 140,
3858
- metadata: {
3859
- tags: ["official", "eslint", "cloud"],
3860
- version: "1.0.0"
3861
- }
3862
- });
3863
- }
3864
- if (configFiles.some((f) => f.includes("jest") || f.includes("vitest") || f.includes("mocha"))) {
3865
- recommendations.push({
3866
- name: "cloud-test-intelligence",
3867
- description: "Smart test execution based on changes",
3868
- type: "pre-commit",
3869
- category: "pre-commit",
3870
- projectTypes: ["typescript", "javascript"],
3871
- trigger: {
3872
- matcher: "git:pre-commit"
3873
- },
3874
- action: {
3875
- command: "ccjk-cloud",
3876
- args: ["test", "intelligent"],
3877
- timeout: 12e4
3878
- },
3879
- enabled: true,
3880
- priority: 160,
3881
- metadata: {
3882
- tags: ["official", "testing", "cloud", "intelligent"],
3883
- version: "1.0.0"
3884
- }
3885
- });
3886
- }
3887
- return recommendations;
3888
- }
3889
- async function submitHookAnalytics(hookName, projectInfo, result) {
3890
- try {
3891
- console.log(`Analytics: Hook ${hookName} ${result} for ${projectInfo.projectType} project`);
3892
- } catch (_error) {
3893
- }
3894
- }
3895
- async function getCommunityHooks(limit = 10, category) {
3896
- const communityHooks = [
3897
- {
3898
- name: "community-commit-emoji",
3899
- description: "Add emoji to commit messages based on changes",
3900
- type: "post-commit",
3901
- category: "lifecycle",
3902
- projectTypes: ["typescript", "javascript", "python"],
3903
- trigger: {
3904
- matcher: "git:post-commit"
3905
- },
3906
- action: {
3907
- command: "ccjk-community",
3908
- args: ["commit-emoji"],
3909
- timeout: 5e3
3910
- },
3911
- enabled: true,
3912
- priority: 100,
3913
- metadata: {
3914
- tags: ["community", "git", "fun"],
3915
- author: "ccjk-user-123",
3916
- version: "1.0.0"
3917
- }
3918
- },
3919
- {
3920
- name: "community-code-poetry",
3921
- description: "Generate poetry from your code",
3922
- type: "post-commit",
3923
- category: "lifecycle",
3924
- projectTypes: ["typescript", "javascript", "python"],
3925
- trigger: {
3926
- matcher: "git:post-commit"
3927
- },
3928
- action: {
3929
- command: "ccjk-community",
3930
- args: ["code-poetry"],
3931
- timeout: 1e4
3932
- },
3933
- enabled: false,
3934
- priority: 50,
3935
- metadata: {
3936
- tags: ["community", "fun", "ai"],
3937
- author: "poet-coder",
3938
- version: "1.0.0"
3939
- }
3940
- }
3941
- ];
3942
- let filtered = communityHooks;
3943
- if (category) {
3944
- filtered = filtered.filter((h) => h.category === category);
3945
- }
3946
- return filtered.slice(0, limit);
3947
- }
3948
-
3949
- async function getCloudRecommendations(analysis) {
3950
- try {
3951
- const client = createCloudClient();
3952
- const response = await client.analyzeProject({
3953
- projectRoot: analysis.rootPath || process.cwd(),
3954
- dependencies: analysis.dependencies?.direct.reduce((acc, d) => {
3955
- acc[d.name] = d.version || "*";
3956
- return acc;
3957
- }, {})
3958
- });
3959
- return (response.recommendations || []).map((rec) => {
3960
- const config = rec.config;
3961
- return {
3962
- name: extractString(rec.name, rec.id || "Unknown Agent"),
3963
- description: extractString(rec.description, "No description available"),
3964
- skills: config?.skills || [],
3965
- mcpServers: config?.mcpServers || [],
3966
- persona: config?.persona,
3967
- capabilities: config?.capabilities || [],
3968
- confidence: rec.relevanceScore || 0.8,
3969
- reason: "Recommended by CCJK Cloud"
3970
- };
3971
- });
3972
- } catch (error) {
3973
- console.warn("Failed to get cloud recommendations:", error);
3974
- return [];
3975
- }
3976
- }
3977
- async function getCloudSkillRecommendations(analysis) {
3978
- try {
3979
- const client = createCloudClient();
3980
- const _response = await client.analyzeProject({
3981
- projectRoot: analysis.rootPath || process.cwd(),
3982
- dependencies: analysis.dependencies?.direct.reduce((acc, d) => {
3983
- acc[d.name] = d.version || "*";
3984
- return acc;
3985
- }, {})
3986
- });
3987
- return [];
3988
- } catch (error) {
3989
- console.warn("Failed to get cloud skill recommendations:", error);
3990
- return [];
3991
- }
3992
- }
3993
- async function getCloudMcpRecommendations(analysis) {
3994
- try {
3995
- const client = createCloudClient();
3996
- const _response = await client.analyzeProject({
3997
- projectRoot: analysis.rootPath || process.cwd(),
3998
- dependencies: analysis.dependencies?.direct.reduce((acc, d) => {
3999
- acc[d.name] = d.version || "*";
4000
- return acc;
4001
- }, {})
4002
- });
4003
- return [];
4004
- } catch (error) {
4005
- console.warn("Failed to get cloud MCP recommendations:", error);
4006
- return [];
4007
- }
4008
- }
4009
-
4010
- const API_BASE_URL$2 = "https://api.claudehome.cn/api/v1";
4011
- var RatingsApiErrorCode = /* @__PURE__ */ ((RatingsApiErrorCode2) => {
4012
- RatingsApiErrorCode2["DUPLICATE_RATING"] = "DUPLICATE_RATING";
4013
- RatingsApiErrorCode2["INVALID_RATING_VALUE"] = "INVALID_RATING_VALUE";
4014
- RatingsApiErrorCode2["SKILL_NOT_FOUND"] = "SKILL_NOT_FOUND";
4015
- RatingsApiErrorCode2["UNAUTHORIZED"] = "UNAUTHORIZED";
4016
- RatingsApiErrorCode2["NETWORK_ERROR"] = "NETWORK_ERROR";
4017
- RatingsApiErrorCode2["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
4018
- return RatingsApiErrorCode2;
4019
- })(RatingsApiErrorCode || {});
4020
- class RatingsApiError extends Error {
4021
- constructor(message, code, statusCode, details) {
4022
- super(message);
4023
- this.code = code;
4024
- this.statusCode = statusCode;
4025
- this.details = details;
4026
- this.name = "RatingsApiError";
4027
- }
4028
- }
4029
- function validateRating(rating) {
4030
- if (!Number.isInteger(rating) || rating < 1 || rating > 5) {
4031
- throw new RatingsApiError(
4032
- `Invalid rating value: ${rating}. Rating must be an integer between 1 and 5.`,
4033
- "INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */
4034
- );
4035
- }
4036
- }
4037
- function buildQueryString(params) {
4038
- const searchParams = new URLSearchParams();
4039
- for (const [key, value] of Object.entries(params)) {
4040
- if (value !== void 0) {
4041
- searchParams.append(key, String(value));
4042
- }
4043
- }
4044
- const queryString = searchParams.toString();
4045
- return queryString ? `?${queryString}` : "";
4046
- }
4047
- async function handleResponse(response, context) {
4048
- if (!response.ok) {
4049
- let errorData = {};
4050
- try {
4051
- errorData = await response.json();
4052
- } catch {
4053
- }
4054
- const errorMessage = errorData.message || errorData.error || `${context} failed`;
4055
- const errorCode = mapHttpStatusToErrorCode(response.status, errorData.code);
4056
- throw new RatingsApiError(
4057
- errorMessage,
4058
- errorCode,
4059
- response.status,
4060
- errorData
4061
- );
4062
- }
4063
- try {
4064
- const data = await response.json();
4065
- if (data.success === false) {
4066
- throw new RatingsApiError(
4067
- data.error || `${context} failed`,
4068
- "UNKNOWN_ERROR" /* UNKNOWN_ERROR */,
4069
- response.status
4070
- );
4071
- }
4072
- return data.data;
4073
- } catch (error) {
4074
- if (error instanceof RatingsApiError) {
4075
- throw error;
4076
- }
4077
- throw new RatingsApiError(
4078
- `Failed to parse response for ${context}`,
4079
- "UNKNOWN_ERROR" /* UNKNOWN_ERROR */,
4080
- response.status
4081
- );
4082
- }
4083
- }
4084
- function mapHttpStatusToErrorCode(status, serverCode) {
4085
- if (serverCode === "DUPLICATE_RATING") {
4086
- return "DUPLICATE_RATING" /* DUPLICATE_RATING */;
4087
- }
4088
- switch (status) {
4089
- case 401:
4090
- return "UNAUTHORIZED" /* UNAUTHORIZED */;
4091
- case 404:
4092
- return "SKILL_NOT_FOUND" /* SKILL_NOT_FOUND */;
4093
- case 409:
4094
- return "DUPLICATE_RATING" /* DUPLICATE_RATING */;
4095
- case 422:
4096
- return "INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */;
4097
- default:
4098
- return "UNKNOWN_ERROR" /* UNKNOWN_ERROR */;
4099
- }
4100
- }
4101
- async function getSkillRatings(skillId, params = {}) {
4102
- if (!skillId || typeof skillId !== "string") {
4103
- throw new RatingsApiError(
4104
- "Skill ID is required and must be a string",
4105
- "INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */
4106
- );
4107
- }
4108
- const queryString = buildQueryString({
4109
- page: params.page,
4110
- limit: params.limit,
4111
- sort: params.sort
4112
- });
4113
- const url = `${API_BASE_URL$2}/skills/${encodeURIComponent(skillId)}/ratings${queryString}`;
4114
- try {
4115
- const response = await fetch(url, {
4116
- method: "GET",
4117
- headers: {
4118
- "Content-Type": "application/json",
4119
- "Accept": "application/json"
4120
- }
4121
- });
4122
- return await handleResponse(response, "Get skill ratings");
4123
- } catch (error) {
4124
- if (error instanceof RatingsApiError) {
4125
- throw error;
4126
- }
4127
- throw new RatingsApiError(
4128
- `Network error while fetching ratings: ${error instanceof Error ? error.message : "Unknown error"}`,
4129
- "NETWORK_ERROR" /* NETWORK_ERROR */
4130
- );
4131
- }
4132
- }
4133
- async function createRating(skillId, data, token) {
4134
- if (!skillId || typeof skillId !== "string") {
4135
- throw new RatingsApiError(
4136
- "Skill ID is required and must be a string",
4137
- "INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */
4138
- );
4139
- }
4140
- if (!token || typeof token !== "string") {
4141
- throw new RatingsApiError(
4142
- "Authentication token is required",
4143
- "UNAUTHORIZED" /* UNAUTHORIZED */
4144
- );
4145
- }
4146
- if (!data.userId || typeof data.userId !== "string") {
4147
- throw new RatingsApiError(
4148
- "User ID is required and must be a string",
4149
- "INVALID_RATING_VALUE" /* INVALID_RATING_VALUE */
4150
- );
4151
- }
4152
- validateRating(data.rating);
4153
- const url = `${API_BASE_URL$2}/skills/${encodeURIComponent(skillId)}/ratings`;
4154
- const requestBody = {
4155
- userId: data.userId,
4156
- rating: data.rating,
4157
- ...data.review !== void 0 && { review: data.review }
4158
- };
4159
- try {
4160
- const response = await fetch(url, {
4161
- method: "POST",
4162
- headers: {
4163
- "Content-Type": "application/json",
4164
- "Accept": "application/json",
4165
- "Authorization": `Bearer ${token}`
4166
- },
4167
- body: JSON.stringify(requestBody)
4168
- });
4169
- return await handleResponse(response, "Create rating");
4170
- } catch (error) {
4171
- if (error instanceof RatingsApiError) {
4172
- throw error;
4173
- }
4174
- throw new RatingsApiError(
4175
- `Network error while creating rating: ${error instanceof Error ? error.message : "Unknown error"}`,
4176
- "NETWORK_ERROR" /* NETWORK_ERROR */
4177
- );
4178
- }
4179
- }
4180
- function isDuplicateRatingError(error) {
4181
- return error instanceof RatingsApiError && error.code === "DUPLICATE_RATING" /* DUPLICATE_RATING */;
4182
- }
4183
- function isUnauthorizedError(error) {
4184
- return error instanceof RatingsApiError && error.code === "UNAUTHORIZED" /* UNAUTHORIZED */;
4185
- }
4186
- function isSkillNotFoundError(error) {
4187
- return error instanceof RatingsApiError && error.code === "SKILL_NOT_FOUND" /* SKILL_NOT_FOUND */;
4188
- }
4189
- const ratingsApi = {
4190
- getSkillRatings,
4191
- createRating,
4192
- isDuplicateRatingError,
4193
- isUnauthorizedError,
4194
- isSkillNotFoundError
4195
- };
4196
-
4197
- const API_BASE_URL$1 = "https://api.claudehome.cn/api/v1";
4198
- const DEFAULT_CACHE_TTL = 5 * 60 * 1e3;
4199
- class SkillsMarketplaceApiError extends Error {
4200
- /** HTTP status code */
4201
- status;
4202
- /** Error code from API response */
4203
- code;
4204
- /** Original response data */
4205
- data;
4206
- constructor(message, status, code, data) {
4207
- super(message);
4208
- this.name = "SkillsMarketplaceApiError";
4209
- this.status = status;
4210
- this.code = code;
4211
- this.data = data;
4212
- }
4213
- }
4214
- class ResponseCache {
4215
- cache = /* @__PURE__ */ new Map();
4216
- /**
4217
- * Get cached data if valid
4218
- * @param key - Cache key
4219
- * @returns Cached data or undefined if not found/expired
4220
- */
4221
- get(key) {
4222
- const entry = this.cache.get(key);
4223
- if (!entry) {
4224
- return void 0;
4225
- }
4226
- const now = Date.now();
4227
- if (now - entry.timestamp > entry.ttl) {
4228
- this.cache.delete(key);
4229
- return void 0;
4230
- }
4231
- return entry.data;
4232
- }
4233
- /**
4234
- * Set cache entry
4235
- * @param key - Cache key
4236
- * @param data - Data to cache
4237
- * @param ttl - Time to live in milliseconds
4238
- */
4239
- set(key, data, ttl) {
4240
- this.cache.set(key, {
4241
- data,
4242
- timestamp: Date.now(),
4243
- ttl
4244
- });
4245
- }
4246
- /**
4247
- * Clear all cache entries
4248
- */
4249
- clear() {
4250
- this.cache.clear();
4251
- }
4252
- /**
4253
- * Delete a specific cache entry
4254
- * @param key - Cache key to delete
4255
- */
4256
- delete(key) {
4257
- this.cache.delete(key);
4258
- }
4259
- /**
4260
- * Get cache size
4261
- * @returns Number of cached entries
4262
- */
4263
- get size() {
4264
- return this.cache.size;
4265
- }
4266
- }
4267
- const responseCache = new ResponseCache();
4268
- function generateCacheKey(endpoint, params) {
4269
- const sortedParams = params ? Object.keys(params).sort().reduce(
4270
- (acc, key) => {
4271
- if (params[key] !== void 0 && params[key] !== null) {
4272
- acc[key] = params[key];
4273
- }
4274
- return acc;
4275
- },
4276
- {}
4277
- ) : {};
4278
- return `${endpoint}:${JSON.stringify(sortedParams)}`;
4279
- }
4280
- function buildUrl$1(endpoint, params) {
4281
- const url = new URL(`${API_BASE_URL$1}${endpoint}`);
4282
- if (params) {
4283
- Object.entries(params).forEach(([key, value]) => {
4284
- if (value !== void 0 && value !== null) {
4285
- url.searchParams.append(key, String(value));
4286
- }
4287
- });
4288
- }
4289
- return url.toString();
4290
- }
4291
- async function fetchApi(endpoint, params, options = {}) {
4292
- const { signal, cacheTtl = DEFAULT_CACHE_TTL, forceRefresh = false } = options;
4293
- if (cacheTtl > 0 && !forceRefresh) {
4294
- const cacheKey = generateCacheKey(endpoint, params);
4295
- const cached = responseCache.get(cacheKey);
4296
- if (cached !== void 0) {
4297
- return cached;
4298
- }
4299
- }
4300
- const url = buildUrl$1(endpoint, params);
4301
- try {
4302
- const response = await fetch(url, {
4303
- method: "GET",
4304
- headers: {
4305
- "Accept": "application/json",
4306
- "Content-Type": "application/json"
4307
- },
4308
- signal
4309
- });
4310
- if (!response.ok) {
4311
- let errorData;
4312
- let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
4313
- let errorCode;
4314
- try {
4315
- errorData = await response.json();
4316
- if (typeof errorData === "object" && errorData !== null) {
4317
- const err = errorData;
4318
- if (typeof err.message === "string") {
4319
- errorMessage = err.message;
4320
- }
4321
- if (typeof err.code === "string") {
4322
- errorCode = err.code;
4323
- }
4324
- }
4325
- } catch {
4326
- }
4327
- throw new SkillsMarketplaceApiError(errorMessage, response.status, errorCode, errorData);
4328
- }
4329
- const data = await response.json();
4330
- if (cacheTtl > 0) {
4331
- const cacheKey = generateCacheKey(endpoint, params);
4332
- responseCache.set(cacheKey, data, cacheTtl);
4333
- }
4334
- return data;
4335
- } catch (error) {
4336
- if (error instanceof SkillsMarketplaceApiError) {
4337
- throw error;
4338
- }
4339
- if (error instanceof Error && error.name === "AbortError") {
4340
- throw new SkillsMarketplaceApiError("Request was cancelled", 0, "ABORT_ERROR");
4341
- }
4342
- if (error instanceof TypeError && error.message.includes("fetch")) {
4343
- throw new SkillsMarketplaceApiError(
4344
- "Network error: Unable to connect to the API",
4345
- 0,
4346
- "NETWORK_ERROR"
4347
- );
4348
- }
4349
- throw new SkillsMarketplaceApiError(
4350
- error instanceof Error ? error.message : "Unknown error occurred",
4351
- 0,
4352
- "UNKNOWN_ERROR"
4353
- );
4354
- }
4355
- }
4356
- async function getMarketplace(params = {}, options = {}) {
4357
- return fetchApi("/skills/marketplace", params, options);
4358
- }
4359
- async function searchSkills(params, options = {}) {
4360
- if (!params.q || params.q.trim() === "") {
4361
- throw new SkillsMarketplaceApiError(
4362
- "Search query (q) is required",
4363
- 400,
4364
- "INVALID_PARAMS"
4365
- );
4366
- }
4367
- return fetchApi("/skills/search", params, options);
4368
- }
4369
- async function getSearchSuggestions(params, options = {}) {
4370
- if (!params.q || params.q.trim() === "") {
4371
- throw new SkillsMarketplaceApiError(
4372
- "Search query (q) is required",
4373
- 400,
4374
- "INVALID_PARAMS"
4375
- );
4376
- }
4377
- const suggestionOptions = {
4378
- ...options,
4379
- cacheTtl: options.cacheTtl ?? 60 * 1e3
4380
- };
4381
- return fetchApi(
4382
- "/skills/search/suggestions",
4383
- params,
4384
- suggestionOptions
4385
- );
4386
- }
4387
- async function getTrendingKeywords(params = {}, options = {}) {
4388
- const trendingOptions = {
4389
- ...options,
4390
- cacheTtl: options.cacheTtl ?? 10 * 60 * 1e3
4391
- };
4392
- return fetchApi(
4393
- "/skills/search/trending",
4394
- params,
4395
- trendingOptions
4396
- );
4397
- }
4398
- function clearCache() {
4399
- responseCache.clear();
4400
- }
4401
- function getCacheSize() {
4402
- return responseCache.size;
4403
- }
4404
- function createAbortController() {
4405
- return new AbortController();
4406
- }
4407
- const skillsMarketplaceApi = {
4408
- getMarketplace,
4409
- searchSkills,
4410
- getSearchSuggestions,
4411
- getTrendingKeywords,
4412
- clearCache,
4413
- getCacheSize,
4414
- createAbortController
4415
- };
4416
-
4417
- function convertConfig(config) {
4418
- if (!config || typeof config !== "object")
4419
- return void 0;
4420
- const obj = config;
4421
- if ("command" in obj || "npmPackage" in obj) {
4422
- return {
4423
- type: typeof obj.type === "string" ? obj.type : void 0,
4424
- command: typeof obj.command === "string" ? obj.command : void 0,
4425
- args: Array.isArray(obj.args) ? obj.args.filter((a) => typeof a === "string") : void 0,
4426
- env: typeof obj.env === "object" && obj.env ? obj.env : void 0,
4427
- npmPackage: typeof obj.npmPackage === "string" ? obj.npmPackage : void 0,
4428
- installCommand: typeof obj.installCommand === "string" ? obj.installCommand : void 0
4429
- };
4430
- }
4431
- if ("enabled" in obj || "triggers" in obj) {
4432
- return {
4433
- enabled: typeof obj.enabled === "boolean" ? obj.enabled : void 0,
4434
- priority: typeof obj.priority === "number" ? obj.priority : void 0,
4435
- triggers: Array.isArray(obj.triggers) ? obj.triggers.filter((t) => typeof t === "string") : void 0,
4436
- parameters: typeof obj.parameters === "object" && obj.parameters ? obj.parameters : void 0
4437
- };
4438
- }
4439
- if ("persona" in obj || "capabilities" in obj) {
4440
- return {
4441
- persona: typeof obj.persona === "string" ? obj.persona : void 0,
4442
- capabilities: Array.isArray(obj.capabilities) ? obj.capabilities.filter((c) => typeof c === "string") : void 0,
4443
- skills: Array.isArray(obj.skills) ? obj.skills.filter((s) => typeof s === "string") : void 0,
4444
- mcpServers: Array.isArray(obj.mcpServers) ? obj.mcpServers.filter((m) => typeof m === "string") : void 0,
4445
- temperature: typeof obj.temperature === "number" ? obj.temperature : void 0,
4446
- maxTokens: typeof obj.maxTokens === "number" ? obj.maxTokens : void 0
4447
- };
4448
- }
4449
- if ("when" in obj) {
4450
- return {
4451
- command: typeof obj.command === "string" ? obj.command : void 0,
4452
- args: Array.isArray(obj.args) ? obj.args.filter((a) => typeof a === "string") : void 0,
4453
- when: typeof obj.when === "string" ? obj.when : void 0,
4454
- enabled: typeof obj.enabled === "boolean" ? obj.enabled : void 0
4455
- };
4456
- }
4457
- if ("steps" in obj) {
4458
- return {
4459
- steps: Array.isArray(obj.steps) ? obj.steps.filter((s) => typeof s === "string") : void 0,
4460
- triggers: Array.isArray(obj.triggers) ? obj.triggers.filter((t) => typeof t === "string") : void 0,
4461
- conditions: typeof obj.conditions === "object" && obj.conditions ? obj.conditions : void 0
4462
- };
4463
- }
4464
- return void 0;
4465
- }
4466
- function convertParameterDefault(value) {
4467
- if (value === null || value === void 0)
4468
- return null;
4469
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
4470
- return value;
4471
- if (Array.isArray(value)) {
4472
- if (value.every((v) => typeof v === "string"))
4473
- return value;
4474
- if (value.every((v) => typeof v === "number"))
4475
- return value;
4476
- return null;
4477
- }
4478
- if (typeof value === "object") {
4479
- const obj = value;
4480
- const converted = {};
4481
- for (const [k, v] of Object.entries(obj)) {
4482
- if (typeof v === "string" || typeof v === "number" || typeof v === "boolean")
4483
- converted[k] = v;
4484
- }
4485
- return converted;
4486
- }
4487
- return null;
4488
- }
4489
- function convertRecommendation(raw, preferredLang = "en") {
4490
- return {
4491
- id: raw.id,
4492
- name: typeof raw.name === "string" ? { en: raw.name } : raw.name,
4493
- description: typeof raw.description === "string" ? { en: raw.description } : raw.description,
4494
- category: raw.category,
4495
- relevanceScore: raw.relevanceScore,
4496
- installCommand: raw.installCommand,
4497
- config: convertConfig(raw.config),
4498
- tags: raw.tags,
4499
- dependencies: raw.dependencies
4500
- };
4501
- }
4502
- function convertTemplateParameter(raw) {
4503
- return {
4504
- name: raw.name,
4505
- type: raw.type,
4506
- required: raw.required,
4507
- default: convertParameterDefault(raw.default),
4508
- description: typeof raw.description === "string" ? { en: raw.description } : raw.description
4509
- };
4510
- }
4511
- function convertTemplate(raw, preferredLang = "en") {
4512
- return {
4513
- id: raw.id,
4514
- type: raw.type,
4515
- name: typeof raw.name === "string" ? { en: raw.name } : raw.name,
4516
- description: typeof raw.description === "string" ? { en: raw.description } : raw.description,
4517
- content: raw.content,
4518
- version: raw.version,
4519
- author: raw.author,
4520
- tags: raw.tags,
4521
- parameters: raw.parameters ? raw.parameters.map(convertTemplateParameter) : void 0,
4522
- createdAt: raw.createdAt,
4523
- updatedAt: raw.updatedAt
4524
- };
4525
- }
4526
- function convertProjectAnalysisResponse(raw, preferredLang = "en") {
4527
- return {
4528
- requestId: raw.requestId,
4529
- recommendations: raw.recommendations.map((r) => convertRecommendation(r, preferredLang)),
4530
- projectType: raw.projectType,
4531
- frameworks: raw.frameworks
4532
- };
4533
- }
4534
- function convertBatchTemplateResponse(raw, preferredLang = "en") {
4535
- const templates = {};
4536
- for (const [id, template] of Object.entries(raw.templates)) {
4537
- templates[id] = convertTemplate(template, preferredLang);
4538
- }
4539
- return {
4540
- requestId: raw.requestId,
4541
- templates,
4542
- notFound: raw.notFound
4543
- };
4544
- }
4545
- function validateProjectAnalysisRequest(request) {
4546
- const errors = [];
4547
- if (!request.projectRoot || typeof request.projectRoot !== "string")
4548
- errors.push("projectRoot is required and must be a string");
4549
- if (request.dependencies && typeof request.dependencies !== "object")
4550
- errors.push("dependencies must be an object");
4551
- if (request.devDependencies && typeof request.devDependencies !== "object")
4552
- errors.push("devDependencies must be an object");
4553
- if (request.language && !["en", "zh-CN"].includes(request.language))
4554
- errors.push('language must be "en" or "zh-CN"');
4555
- return {
4556
- valid: errors.length === 0,
4557
- errors
4558
- };
4559
- }
4560
- function validateBatchTemplateRequest(request) {
4561
- const errors = [];
4562
- if (!Array.isArray(request.ids))
4563
- errors.push("ids must be an array");
4564
- else if (request.ids.length === 0)
4565
- errors.push("ids array cannot be empty");
4566
- else if (!request.ids.every((id) => typeof id === "string"))
4567
- errors.push("all ids must be strings");
4568
- if (request.language && !["en", "zh-CN"].includes(request.language))
4569
- errors.push('language must be "en" or "zh-CN"');
4570
- return {
4571
- valid: errors.length === 0,
4572
- errors
4573
- };
4574
- }
4575
- function validateUsageReport(report) {
4576
- const errors = [];
4577
- if (!report.reportId || typeof report.reportId !== "string")
4578
- errors.push("reportId is required and must be a string");
4579
- const validMetricTypes = [
4580
- "template_download",
4581
- "recommendation_shown",
4582
- "recommendation_accepted",
4583
- "analysis_completed",
4584
- "error_occurred"
4585
- ];
4586
- if (!validMetricTypes.includes(report.metricType))
4587
- errors.push(`metricType must be one of: ${validMetricTypes.join(", ")}`);
4588
- if (!report.timestamp || typeof report.timestamp !== "string")
4589
- errors.push("timestamp is required and must be a string");
4590
- if (!report.ccjkVersion || typeof report.ccjkVersion !== "string")
4591
- errors.push("ccjkVersion is required and must be a string");
4592
- if (!report.nodeVersion || typeof report.nodeVersion !== "string")
4593
- errors.push("nodeVersion is required and must be a string");
4594
- if (!report.platform || typeof report.platform !== "string")
4595
- errors.push("platform is required and must be a string");
4596
- return {
4597
- valid: errors.length === 0,
4598
- errors
4599
- };
4600
- }
4601
- function isRecommendationConfig(value) {
4602
- return convertConfig(value) !== void 0;
4603
- }
4604
- function isTelemetryEventData(value) {
4605
- if (!value || typeof value !== "object")
4606
- return false;
4607
- const obj = value;
4608
- if (typeof obj.timestamp !== "number" && typeof obj.timestamp !== "string")
4609
- return false;
4610
- return true;
4611
- }
4612
- function isTemplateParameterValue(value) {
4613
- if (value === null || value === void 0)
4614
- return value === null;
4615
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
4616
- return true;
4617
- if (Array.isArray(value)) {
4618
- if (value.length === 0)
4619
- return true;
4620
- const allStrings = value.every((v) => typeof v === "string");
4621
- const allNumbers = value.every((v) => typeof v === "number");
4622
- return allStrings || allNumbers;
4623
- }
4624
- if (typeof value === "object") {
4625
- return Object.values(value).every(
4626
- (v) => typeof v === "string" || typeof v === "number" || typeof v === "boolean"
4627
- );
4628
- }
4629
- return false;
4630
- }
4631
-
4632
- const API_BASE_URL = "https://api.claudehome.cn/api/v1";
4633
- function buildUrl(endpoint, params) {
4634
- const url = new URL(`${API_BASE_URL}${endpoint}`);
4635
- if (params) {
4636
- Object.entries(params).forEach(([key, value]) => {
4637
- if (value !== void 0 && value !== null) {
4638
- url.searchParams.append(key, String(value));
4639
- }
4640
- });
4641
- }
4642
- return url.toString();
4643
- }
4644
- async function authenticatedRequest(method, endpoint, options, body) {
4645
- const { token, signal, timeout = 3e4 } = options;
4646
- const url = buildUrl(endpoint);
4647
- const controller = new AbortController();
4648
- const timeoutId = setTimeout(() => controller.abort(), timeout);
4649
- const requestSignal = signal || controller.signal;
4650
- try {
4651
- const response = await fetch(url, {
4652
- method,
4653
- headers: {
4654
- "Accept": "application/json",
4655
- "Content-Type": "application/json",
4656
- "Authorization": `Bearer ${token}`
4657
- },
4658
- body: body ? JSON.stringify(body) : void 0,
4659
- signal: requestSignal
4660
- });
4661
- clearTimeout(timeoutId);
4662
- if (!response.ok) {
4663
- let errorData;
4664
- let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
4665
- let errorCode;
4666
- try {
4667
- errorData = await response.json();
4668
- if (typeof errorData === "object" && errorData !== null) {
4669
- const err = errorData;
4670
- if (typeof err.error === "string") {
4671
- errorMessage = err.error;
4672
- }
4673
- if (typeof err.code === "string") {
4674
- errorCode = err.code;
4675
- }
4676
- }
4677
- } catch {
4678
- }
4679
- throw new SkillsMarketplaceApiError(errorMessage, response.status, errorCode, errorData);
4680
- }
4681
- const apiResponse = await response.json();
4682
- if (!apiResponse.success) {
4683
- throw new SkillsMarketplaceApiError(
4684
- apiResponse.error || "Request failed",
4685
- response.status,
4686
- apiResponse.code
4687
- );
4688
- }
4689
- if (!apiResponse.data) {
4690
- throw new SkillsMarketplaceApiError(
4691
- "No data in response",
4692
- response.status,
4693
- "NO_DATA"
4694
- );
4695
- }
4696
- return apiResponse.data;
4697
- } catch (error) {
4698
- clearTimeout(timeoutId);
4699
- if (error instanceof SkillsMarketplaceApiError) {
4700
- throw error;
4701
- }
4702
- if (error instanceof Error && error.name === "AbortError") {
4703
- throw new SkillsMarketplaceApiError("Request was cancelled", 0, "ABORT_ERROR");
4704
- }
4705
- if (error instanceof TypeError && error.message.includes("fetch")) {
4706
- throw new SkillsMarketplaceApiError(
4707
- "Network error: Unable to connect to the API",
4708
- 0,
4709
- "NETWORK_ERROR"
4710
- );
4711
- }
4712
- throw new SkillsMarketplaceApiError(
4713
- error instanceof Error ? error.message : "Unknown error occurred",
4714
- 0,
4715
- "UNKNOWN_ERROR"
4716
- );
4717
- }
4718
- }
4719
- async function getUserSkills(userId, options) {
4720
- if (!userId || userId.trim() === "") {
4721
- throw new SkillsMarketplaceApiError(
4722
- "User ID is required",
4723
- 400,
4724
- "INVALID_PARAMS"
4725
- );
4726
- }
4727
- return authenticatedRequest(
4728
- "GET",
4729
- `/users/${userId}/skills`,
4730
- options
4731
- );
4732
- }
4733
- async function installSkill(userId, request, options) {
4734
- if (!userId || userId.trim() === "") {
4735
- throw new SkillsMarketplaceApiError(
4736
- "User ID is required",
4737
- 400,
4738
- "INVALID_PARAMS"
4739
- );
4740
- }
4741
- if (!request.skillId || request.skillId.trim() === "") {
4742
- throw new SkillsMarketplaceApiError(
4743
- "Skill ID is required",
4744
- 400,
4745
- "INVALID_PARAMS"
4746
- );
4747
- }
4748
- return authenticatedRequest(
4749
- "POST",
4750
- `/users/${userId}/skills`,
4751
- options,
4752
- request
4753
- );
4754
- }
4755
- async function uninstallSkill(userId, skillId, options) {
4756
- if (!userId || userId.trim() === "") {
4757
- throw new SkillsMarketplaceApiError(
4758
- "User ID is required",
4759
- 400,
4760
- "INVALID_PARAMS"
4761
- );
4762
- }
4763
- if (!skillId || skillId.trim() === "") {
4764
- throw new SkillsMarketplaceApiError(
4765
- "Skill ID is required",
4766
- 400,
4767
- "INVALID_PARAMS"
4768
- );
4769
- }
4770
- return authenticatedRequest(
4771
- "DELETE",
4772
- `/users/${userId}/skills/${skillId}`,
4773
- options
4774
- );
4775
- }
4776
- async function updateSkill(userId, skillId, request, options) {
4777
- if (!userId || userId.trim() === "") {
4778
- throw new SkillsMarketplaceApiError(
4779
- "User ID is required",
4780
- 400,
4781
- "INVALID_PARAMS"
4782
- );
4783
- }
4784
- if (!skillId || skillId.trim() === "") {
4785
- throw new SkillsMarketplaceApiError(
4786
- "Skill ID is required",
4787
- 400,
4788
- "INVALID_PARAMS"
4789
- );
4790
- }
4791
- if (!request.isEnabled && !request.config) {
4792
- throw new SkillsMarketplaceApiError(
4793
- "At least one of isEnabled or config must be provided",
4794
- 400,
4795
- "INVALID_PARAMS"
4796
- );
4797
- }
4798
- return authenticatedRequest(
4799
- "PATCH",
4800
- `/users/${userId}/skills/${skillId}`,
4801
- options,
4802
- request
4803
- );
4804
- }
4805
- async function getRecommendations(userId, params = {}, options) {
4806
- if (!userId || userId.trim() === "") {
4807
- throw new SkillsMarketplaceApiError(
4808
- "User ID is required",
4809
- 400,
4810
- "INVALID_PARAMS"
4811
- );
4812
- }
4813
- const endpoint = `/users/${userId}/recommendations`;
4814
- const url = buildUrl(endpoint, params);
4815
- const { token, signal, timeout = 3e4 } = options;
4816
- const controller = new AbortController();
4817
- const timeoutId = setTimeout(() => controller.abort(), timeout);
4818
- const requestSignal = signal || controller.signal;
4819
- try {
4820
- const response = await fetch(url, {
4821
- method: "GET",
4822
- headers: {
4823
- "Accept": "application/json",
4824
- "Content-Type": "application/json",
4825
- "Authorization": `Bearer ${token}`
4826
- },
4827
- signal: requestSignal
4828
- });
4829
- clearTimeout(timeoutId);
4830
- if (!response.ok) {
4831
- let errorData;
4832
- let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
4833
- let errorCode;
4834
- try {
4835
- errorData = await response.json();
4836
- if (typeof errorData === "object" && errorData !== null) {
4837
- const err = errorData;
4838
- if (typeof err.error === "string") {
4839
- errorMessage = err.error;
4840
- }
4841
- if (typeof err.code === "string") {
4842
- errorCode = err.code;
4843
- }
4844
- }
4845
- } catch {
4846
- }
4847
- throw new SkillsMarketplaceApiError(errorMessage, response.status, errorCode, errorData);
4848
- }
4849
- const apiResponse = await response.json();
4850
- if (!apiResponse.success || !apiResponse.data) {
4851
- throw new SkillsMarketplaceApiError(
4852
- apiResponse.error || "Request failed",
4853
- response.status,
4854
- apiResponse.code
4855
- );
4856
- }
4857
- return apiResponse.data;
4858
- } catch (error) {
4859
- clearTimeout(timeoutId);
4860
- if (error instanceof SkillsMarketplaceApiError) {
4861
- throw error;
4862
- }
4863
- if (error instanceof Error && error.name === "AbortError") {
4864
- throw new SkillsMarketplaceApiError("Request was cancelled", 0, "ABORT_ERROR");
4865
- }
4866
- if (error instanceof TypeError && error.message.includes("fetch")) {
4867
- throw new SkillsMarketplaceApiError(
4868
- "Network error: Unable to connect to the API",
4869
- 0,
4870
- "NETWORK_ERROR"
4871
- );
4872
- }
4873
- throw new SkillsMarketplaceApiError(
4874
- error instanceof Error ? error.message : "Unknown error occurred",
4875
- 0,
4876
- "UNKNOWN_ERROR"
4877
- );
4878
- }
4879
- }
4880
- async function getUserQuota(userId, options) {
4881
- if (!userId || userId.trim() === "") {
4882
- throw new SkillsMarketplaceApiError(
4883
- "User ID is required",
4884
- 400,
4885
- "INVALID_PARAMS"
4886
- );
4887
- }
4888
- return authenticatedRequest(
4889
- "GET",
4890
- `/users/${userId}/quota`,
4891
- options
4892
- );
4893
- }
4894
- function canInstallMore(quota) {
4895
- return quota.remaining > 0;
4896
- }
4897
- function getQuotaUsagePercentage(quota) {
4898
- if (quota.limit === 0) {
4899
- return 0;
4900
- }
4901
- return Math.round(quota.used / quota.limit * 100);
4902
- }
4903
- function isSkillInstalled(skills, skillId) {
4904
- return skills.some((skill) => skill.skillId === skillId);
4905
- }
4906
- function getEnabledSkills(skills) {
4907
- return skills.filter((skill) => skill.isEnabled);
4908
- }
4909
- function getDisabledSkills(skills) {
4910
- return skills.filter((skill) => !skill.isEnabled);
4911
- }
4912
- function sortByUsage(skills, order = "desc") {
4913
- return [...skills].sort((a, b) => {
4914
- return order === "desc" ? b.usageCount - a.usageCount : a.usageCount - b.usageCount;
4915
- });
4916
- }
4917
- function sortByLastUsed(skills, order = "desc") {
4918
- return [...skills].sort((a, b) => {
4919
- const aTime = a.lastUsedAt ? new Date(a.lastUsedAt).getTime() : 0;
4920
- const bTime = b.lastUsedAt ? new Date(b.lastUsedAt).getTime() : 0;
4921
- return order === "desc" ? bTime - aTime : aTime - bTime;
4922
- });
4923
- }
4924
- const userSkillsApi = {
4925
- getUserSkills,
4926
- installSkill,
4927
- uninstallSkill,
4928
- updateSkill,
4929
- getRecommendations,
4930
- getUserQuota,
4931
- // Utility functions
4932
- canInstallMore,
4933
- getQuotaUsagePercentage,
4934
- isSkillInstalled,
4935
- getEnabledSkills,
4936
- getDisabledSkills,
4937
- sortByUsage,
4938
- sortByLastUsed
4939
- };
4940
-
4941
- export { AiderTool, BaseCodeTool, BaseError, ClaudeCodeTool, ClineTool, CodexTool, ConfigManager, ConfigValidator, ConfigurationError, ContinueTool, CursorTool, InternalError, Logger, Mutex, NotFoundError, RatingsApiError, RatingsApiErrorCode, Semaphore, TimeoutError, ToolFactory, ToolRegistry, UnauthorizedError, ValidationError, index$6 as array, assert, assertDefined, index$5 as async, batchProcessFiles, camelCase, canInstallMore, capitalize, chunk, index$4 as command, commandExists, convertBatchTemplateResponse, convertConfig, convertParameterDefault, convertProjectAnalysisResponse, convertRecommendation, convertTemplate, convertTemplateParameter, copyFile, countLines, createCloudClient, createConfigManager, createLogger, createRating, createTool, createValidator, debounce, deepClone, deepMerge, deleteDir, deleteFile, difference, ensureDir, index$3 as error, executeCommand, executeCommandStream, exists, extractString, flatten, flatten$1 as flattenArray, formatError, index$2 as fs, generateCompactWelcome, generateRecommendations, generateWelcome, get, getArchitecture, getCacheDir, getCapabilitiesByType, getCapability, getCloudMcpRecommendations, getCloudRecommendations, getCloudRecommendedHooks, getCloudSkillRecommendations, getCommandPath, getCommandVersion, getCommunityHooks, getConfigDir, getDataDir, getDisabledSkills, getEnabledSkills, getErrorMessage, getFileInfo, getFileSize, getHomeDir, getPlatform, getPlatformInfo, getQuotaUsagePercentage, getRecommendations, getRegistry, getSkillRatings, getTempDir, getUserQuota, getUserSkills, has, installSkill, intersection, isArray, isBoolean, isDefined, isDirectory, isDuplicateRatingError, isEmail, isFile, isLargeFile, isLinux, isMacOS, isNumber, isObject, isRecommendationConfig, isSkillInstalled, isSkillNotFoundError, isString, isTelemetryEventData, isTemplateParameterValue, isURL, isUnauthorizedError, isUnix, isWindows, kebabCase, listDirs, listFiles, logger, moveFile, index$1 as object, omit, parallelLimit, partition, pascalCase, pick, processLargeFile, processLineByLine, ratingsApi, readFile, readJSON, retry, scanCapabilities, sequence, set, shuffle, skillsMarketplaceApi, sleep, slugify, snakeCase, sortByLastUsed, sortByUsage, streamJSON, streamWriteJSON, index as string, submitHookAnalytics, template, throttle, timeout, truncate, tryCatch, tryCatchAsync, unflatten, uninstallSkill, union, unique, updateSkill, userSkillsApi, validateBatchTemplateRequest, validateProjectAnalysisRequest, validateUsageReport, validation, validators, waitFor, wrapError, writeFile, writeJSON };