@claudetools/cli 0.13.12 → 0.13.15

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 (368) hide show
  1. package/dist/__tests__/factories.d.ts +173 -0
  2. package/dist/__tests__/factories.d.ts.map +1 -0
  3. package/dist/__tests__/factories.js +150 -0
  4. package/dist/__tests__/factories.js.map +1 -0
  5. package/dist/__tests__/helpers.d.ts +36 -0
  6. package/dist/__tests__/helpers.d.ts.map +1 -0
  7. package/dist/__tests__/helpers.js +52 -0
  8. package/dist/__tests__/helpers.js.map +1 -0
  9. package/dist/analytics/index.d.ts +14 -0
  10. package/dist/analytics/index.d.ts.map +1 -0
  11. package/dist/analytics/index.js +259 -0
  12. package/dist/analytics/index.js.map +1 -0
  13. package/dist/analytics/session.d.ts +17 -0
  14. package/dist/analytics/session.d.ts.map +1 -0
  15. package/dist/analytics/session.js +130 -0
  16. package/dist/analytics/session.js.map +1 -0
  17. package/dist/analytics/token-tracker.d.ts +48 -0
  18. package/dist/analytics/token-tracker.d.ts.map +1 -0
  19. package/dist/analytics/token-tracker.js +269 -0
  20. package/dist/analytics/token-tracker.js.map +1 -0
  21. package/dist/analytics/tracker.d.ts +33 -0
  22. package/dist/analytics/tracker.d.ts.map +1 -0
  23. package/dist/analytics/tracker.js +210 -0
  24. package/dist/analytics/tracker.js.map +1 -0
  25. package/dist/api-keys/index.d.ts +15 -0
  26. package/dist/api-keys/index.d.ts.map +1 -0
  27. package/dist/api-keys/index.js +228 -0
  28. package/dist/api-keys/index.js.map +1 -0
  29. package/dist/auth/config.d.ts +15 -0
  30. package/dist/auth/config.d.ts.map +1 -0
  31. package/dist/auth/config.js +67 -0
  32. package/dist/auth/config.js.map +1 -0
  33. package/dist/auth/index.d.ts +8 -0
  34. package/dist/auth/index.d.ts.map +1 -0
  35. package/dist/auth/index.js +299 -0
  36. package/dist/auth/index.js.map +1 -0
  37. package/dist/auth/keychain.d.ts +21 -0
  38. package/dist/auth/keychain.d.ts.map +1 -0
  39. package/dist/auth/keychain.js +256 -0
  40. package/dist/auth/keychain.js.map +1 -0
  41. package/dist/billing/index.d.ts +7 -0
  42. package/dist/billing/index.d.ts.map +1 -0
  43. package/dist/billing/index.js +233 -0
  44. package/dist/billing/index.js.map +1 -0
  45. package/dist/cli.js +291 -43
  46. package/dist/cli.js.map +1 -1
  47. package/dist/commands/hook.d.ts +12 -0
  48. package/dist/commands/hook.d.ts.map +1 -0
  49. package/dist/commands/hook.js +190 -0
  50. package/dist/commands/hook.js.map +1 -0
  51. package/dist/commands/keys.d.ts +4 -0
  52. package/dist/commands/keys.d.ts.map +1 -0
  53. package/dist/commands/keys.js +43 -0
  54. package/dist/commands/keys.js.map +1 -0
  55. package/dist/commands/mcp.d.ts +4 -0
  56. package/dist/commands/mcp.d.ts.map +1 -0
  57. package/dist/commands/mcp.js +43 -0
  58. package/dist/commands/mcp.js.map +1 -0
  59. package/dist/commands/project.d.ts +4 -0
  60. package/dist/commands/project.d.ts.map +1 -0
  61. package/dist/commands/project.js +68 -0
  62. package/dist/commands/project.js.map +1 -0
  63. package/dist/commands/skill.d.ts +4 -0
  64. package/dist/commands/skill.d.ts.map +1 -0
  65. package/dist/commands/skill.js +37 -0
  66. package/dist/commands/skill.js.map +1 -0
  67. package/dist/commands/stacks.d.ts +4 -0
  68. package/dist/commands/stacks.d.ts.map +1 -0
  69. package/dist/commands/stacks.js +103 -0
  70. package/dist/commands/stacks.js.map +1 -0
  71. package/dist/commands/stats.d.ts +4 -0
  72. package/dist/commands/stats.d.ts.map +1 -0
  73. package/dist/commands/stats.js +6 -0
  74. package/dist/commands/stats.js.map +1 -0
  75. package/dist/commands/sync.d.ts +4 -0
  76. package/dist/commands/sync.d.ts.map +1 -0
  77. package/dist/commands/sync.js +60 -0
  78. package/dist/commands/sync.js.map +1 -0
  79. package/dist/commands/update.d.ts +4 -0
  80. package/dist/commands/update.d.ts.map +1 -0
  81. package/dist/commands/update.js +63 -0
  82. package/dist/commands/update.js.map +1 -0
  83. package/dist/daemon/client.d.ts +107 -0
  84. package/dist/daemon/client.d.ts.map +1 -0
  85. package/dist/daemon/client.js +250 -0
  86. package/dist/daemon/client.js.map +1 -0
  87. package/dist/daemon/health.d.ts +38 -0
  88. package/dist/daemon/health.d.ts.map +1 -0
  89. package/dist/daemon/health.js +212 -0
  90. package/dist/daemon/health.js.map +1 -0
  91. package/dist/daemon/index.d.ts +34 -0
  92. package/dist/daemon/index.d.ts.map +1 -0
  93. package/dist/daemon/index.js +197 -0
  94. package/dist/daemon/index.js.map +1 -0
  95. package/dist/daemon/protocol.d.ts +144 -0
  96. package/dist/daemon/protocol.d.ts.map +1 -0
  97. package/dist/daemon/protocol.js +5 -0
  98. package/dist/daemon/protocol.js.map +1 -0
  99. package/dist/gamification/index.d.ts +13 -0
  100. package/dist/gamification/index.d.ts.map +1 -0
  101. package/dist/gamification/index.js +120 -0
  102. package/dist/gamification/index.js.map +1 -0
  103. package/dist/gamification/types.d.ts +34 -0
  104. package/dist/gamification/types.d.ts.map +1 -0
  105. package/dist/gamification/types.js +5 -0
  106. package/dist/gamification/types.js.map +1 -0
  107. package/dist/hooks/index.d.ts +65 -0
  108. package/dist/hooks/index.d.ts.map +1 -0
  109. package/dist/hooks/index.js +403 -0
  110. package/dist/hooks/index.js.map +1 -0
  111. package/dist/lib/api.d.ts +29 -0
  112. package/dist/lib/api.d.ts.map +1 -0
  113. package/dist/lib/api.js +213 -0
  114. package/dist/lib/api.js.map +1 -0
  115. package/dist/lib/browser.d.ts +6 -0
  116. package/dist/lib/browser.d.ts.map +1 -0
  117. package/dist/lib/browser.js +14 -0
  118. package/dist/lib/browser.js.map +1 -0
  119. package/dist/lib/channel-config.d.ts +10 -0
  120. package/dist/lib/channel-config.d.ts.map +1 -0
  121. package/dist/lib/channel-config.js +48 -0
  122. package/dist/lib/channel-config.js.map +1 -0
  123. package/dist/lib/command-runner.d.ts +16 -0
  124. package/dist/lib/command-runner.d.ts.map +1 -0
  125. package/dist/lib/command-runner.js +59 -0
  126. package/dist/lib/command-runner.js.map +1 -0
  127. package/dist/lib/command-utils.d.ts +22 -0
  128. package/dist/lib/command-utils.d.ts.map +1 -0
  129. package/dist/lib/command-utils.js +88 -0
  130. package/dist/lib/command-utils.js.map +1 -0
  131. package/dist/lib/error-handler.d.ts +13 -0
  132. package/dist/lib/error-handler.d.ts.map +1 -0
  133. package/dist/lib/error-handler.js +70 -0
  134. package/dist/lib/error-handler.js.map +1 -0
  135. package/dist/lib/errors.d.ts +35 -0
  136. package/dist/lib/errors.d.ts.map +1 -0
  137. package/dist/lib/errors.js +70 -0
  138. package/dist/lib/errors.js.map +1 -0
  139. package/dist/lib/exit.d.ts +10 -0
  140. package/dist/lib/exit.d.ts.map +1 -0
  141. package/dist/lib/exit.js +21 -0
  142. package/dist/lib/exit.js.map +1 -0
  143. package/dist/lib/formatters.d.ts +65 -0
  144. package/dist/lib/formatters.d.ts.map +1 -0
  145. package/dist/lib/formatters.js +180 -0
  146. package/dist/lib/formatters.js.map +1 -0
  147. package/dist/lib/hybrid-data.d.ts +47 -0
  148. package/dist/lib/hybrid-data.d.ts.map +1 -0
  149. package/dist/lib/hybrid-data.js +326 -0
  150. package/dist/lib/hybrid-data.js.map +1 -0
  151. package/dist/lib/local-store.d.ts +113 -0
  152. package/dist/lib/local-store.d.ts.map +1 -0
  153. package/dist/lib/local-store.js +220 -0
  154. package/dist/lib/local-store.js.map +1 -0
  155. package/dist/lib/machine-id.d.ts +8 -0
  156. package/dist/lib/machine-id.d.ts.map +1 -0
  157. package/dist/lib/machine-id.js +39 -0
  158. package/dist/lib/machine-id.js.map +1 -0
  159. package/dist/lib/network.d.ts +15 -0
  160. package/dist/lib/network.d.ts.map +1 -0
  161. package/dist/lib/network.js +46 -0
  162. package/dist/lib/network.js.map +1 -0
  163. package/dist/lib/theme.d.ts +77 -0
  164. package/dist/lib/theme.d.ts.map +1 -0
  165. package/dist/lib/theme.js +137 -0
  166. package/dist/lib/theme.js.map +1 -0
  167. package/dist/lib/tool-availability.d.ts +13 -0
  168. package/dist/lib/tool-availability.d.ts.map +1 -0
  169. package/dist/lib/tool-availability.js +48 -0
  170. package/dist/lib/tool-availability.js.map +1 -0
  171. package/dist/lib/update-checker.d.ts +21 -0
  172. package/dist/lib/update-checker.d.ts.map +1 -0
  173. package/dist/lib/update-checker.js +110 -0
  174. package/dist/lib/update-checker.js.map +1 -0
  175. package/dist/lib/validation.d.ts +30 -0
  176. package/dist/lib/validation.d.ts.map +1 -0
  177. package/dist/lib/validation.js +82 -0
  178. package/dist/lib/validation.js.map +1 -0
  179. package/dist/lib/validators.d.ts +18 -0
  180. package/dist/lib/validators.d.ts.map +1 -0
  181. package/dist/lib/validators.js +30 -0
  182. package/dist/lib/validators.js.map +1 -0
  183. package/dist/marketplace/api.d.ts +24 -0
  184. package/dist/marketplace/api.d.ts.map +1 -0
  185. package/dist/marketplace/api.js +92 -0
  186. package/dist/marketplace/api.js.map +1 -0
  187. package/dist/marketplace/index.d.ts +13 -0
  188. package/dist/marketplace/index.d.ts.map +1 -0
  189. package/dist/marketplace/index.js +155 -0
  190. package/dist/marketplace/index.js.map +1 -0
  191. package/dist/marketplace/installer.d.ts +18 -0
  192. package/dist/marketplace/installer.d.ts.map +1 -0
  193. package/dist/marketplace/installer.js +184 -0
  194. package/dist/marketplace/installer.js.map +1 -0
  195. package/dist/mcp/api.d.ts +93 -0
  196. package/dist/mcp/api.d.ts.map +1 -0
  197. package/dist/mcp/api.js +106 -0
  198. package/dist/mcp/api.js.map +1 -0
  199. package/dist/mcp/config.d.ts +72 -0
  200. package/dist/mcp/config.d.ts.map +1 -0
  201. package/dist/mcp/config.js +156 -0
  202. package/dist/mcp/config.js.map +1 -0
  203. package/dist/mcp/index.d.ts +54 -0
  204. package/dist/mcp/index.d.ts.map +1 -0
  205. package/dist/mcp/index.js +381 -0
  206. package/dist/mcp/index.js.map +1 -0
  207. package/dist/mcp/prompt.clean.d.ts +25 -0
  208. package/dist/mcp/prompt.clean.d.ts.map +1 -0
  209. package/dist/mcp/prompt.clean.js +206 -0
  210. package/dist/mcp/prompt.clean.js.map +1 -0
  211. package/dist/mcp/prompt.d.ts +52 -0
  212. package/dist/mcp/prompt.d.ts.map +1 -0
  213. package/dist/mcp/prompt.js +210 -0
  214. package/dist/mcp/prompt.js.map +1 -0
  215. package/dist/mcp/secrets.clean.d.ts +18 -0
  216. package/dist/mcp/secrets.clean.d.ts.map +1 -0
  217. package/dist/mcp/secrets.clean.js +357 -0
  218. package/dist/mcp/secrets.clean.js.map +1 -0
  219. package/dist/mcp/secrets.d.ts +46 -0
  220. package/dist/mcp/secrets.d.ts.map +1 -0
  221. package/dist/mcp/secrets.js +339 -0
  222. package/dist/mcp/secrets.js.map +1 -0
  223. package/dist/memory/index.d.ts +14 -0
  224. package/dist/memory/index.d.ts.map +1 -0
  225. package/dist/memory/index.js +98 -0
  226. package/dist/memory/index.js.map +1 -0
  227. package/dist/onboard/agents-md-builder.d.ts.map +1 -1
  228. package/dist/onboard/agents-md-builder.js +45 -0
  229. package/dist/onboard/agents-md-builder.js.map +1 -1
  230. package/dist/onboard/claude-inference.d.ts.map +1 -1
  231. package/dist/onboard/claude-inference.js +31 -5
  232. package/dist/onboard/claude-inference.js.map +1 -1
  233. package/dist/onboard/context7-fetcher.d.ts +1 -1
  234. package/dist/onboard/context7-fetcher.d.ts.map +1 -1
  235. package/dist/onboard/context7-fetcher.js +50 -16
  236. package/dist/onboard/context7-fetcher.js.map +1 -1
  237. package/dist/onboard/docs-builder.d.ts.map +1 -1
  238. package/dist/onboard/docs-builder.js +523 -50
  239. package/dist/onboard/docs-builder.js.map +1 -1
  240. package/dist/onboard/index.d.ts.map +1 -1
  241. package/dist/onboard/index.js +74 -25
  242. package/dist/onboard/index.js.map +1 -1
  243. package/dist/onboard/stack-detector.d.ts.map +1 -1
  244. package/dist/onboard/stack-detector.js +5 -55
  245. package/dist/onboard/stack-detector.js.map +1 -1
  246. package/dist/project/constants.d.ts +21 -0
  247. package/dist/project/constants.d.ts.map +1 -0
  248. package/dist/project/constants.js +21 -0
  249. package/dist/project/constants.js.map +1 -0
  250. package/dist/project/format.d.ts +16 -0
  251. package/dist/project/format.d.ts.map +1 -0
  252. package/dist/project/format.js +40 -0
  253. package/dist/project/format.js.map +1 -0
  254. package/dist/project/git.d.ts +28 -0
  255. package/dist/project/git.d.ts.map +1 -0
  256. package/dist/project/git.js +93 -0
  257. package/dist/project/git.js.map +1 -0
  258. package/dist/project/index.d.ts +36 -0
  259. package/dist/project/index.d.ts.map +1 -0
  260. package/dist/project/index.js +272 -0
  261. package/dist/project/index.js.map +1 -0
  262. package/dist/project/mapper.d.ts +27 -0
  263. package/dist/project/mapper.d.ts.map +1 -0
  264. package/dist/project/mapper.js +64 -0
  265. package/dist/project/mapper.js.map +1 -0
  266. package/dist/project/storage.d.ts +71 -0
  267. package/dist/project/storage.d.ts.map +1 -0
  268. package/dist/project/storage.js +274 -0
  269. package/dist/project/storage.js.map +1 -0
  270. package/dist/project/sync-bridge.d.ts +33 -0
  271. package/dist/project/sync-bridge.d.ts.map +1 -0
  272. package/dist/project/sync-bridge.js +155 -0
  273. package/dist/project/sync-bridge.js.map +1 -0
  274. package/dist/project/types.d.ts +107 -0
  275. package/dist/project/types.d.ts.map +1 -0
  276. package/dist/project/types.js +77 -0
  277. package/dist/project/types.js.map +1 -0
  278. package/dist/publish/index.d.ts +4 -0
  279. package/dist/publish/index.d.ts.map +1 -0
  280. package/dist/publish/index.js +92 -0
  281. package/dist/publish/index.js.map +1 -0
  282. package/dist/setup.d.ts.map +1 -1
  283. package/dist/setup.js +29 -10
  284. package/dist/setup.js.map +1 -1
  285. package/dist/skills/index.d.ts +51 -0
  286. package/dist/skills/index.d.ts.map +1 -0
  287. package/dist/skills/index.js +509 -0
  288. package/dist/skills/index.js.map +1 -0
  289. package/dist/stacks/check.d.ts +2 -0
  290. package/dist/stacks/check.d.ts.map +1 -0
  291. package/dist/stacks/check.js +144 -0
  292. package/dist/stacks/check.js.map +1 -0
  293. package/dist/stacks/diff.d.ts +11 -0
  294. package/dist/stacks/diff.d.ts.map +1 -0
  295. package/dist/stacks/diff.js +123 -0
  296. package/dist/stacks/diff.js.map +1 -0
  297. package/dist/stacks/index.d.ts +17 -0
  298. package/dist/stacks/index.d.ts.map +1 -0
  299. package/dist/stacks/index.js +525 -0
  300. package/dist/stacks/index.js.map +1 -0
  301. package/dist/stacks/index.refactored.d.ts.map +1 -0
  302. package/dist/stacks/index.refactored.js.map +1 -0
  303. package/dist/stacks/io.d.ts +11 -0
  304. package/dist/stacks/io.d.ts.map +1 -0
  305. package/dist/stacks/io.js +179 -0
  306. package/dist/stacks/io.js.map +1 -0
  307. package/dist/stacks/rollback.d.ts +5 -0
  308. package/dist/stacks/rollback.d.ts.map +1 -0
  309. package/dist/stacks/rollback.js +162 -0
  310. package/dist/stacks/rollback.js.map +1 -0
  311. package/dist/stacks/types.d.ts +70 -0
  312. package/dist/stacks/types.d.ts.map +1 -0
  313. package/dist/stacks/types.js +6 -0
  314. package/dist/stacks/types.js.map +1 -0
  315. package/dist/stacks/utils.d.ts +9 -0
  316. package/dist/stacks/utils.d.ts.map +1 -0
  317. package/dist/stacks/utils.js +11 -0
  318. package/dist/stacks/utils.js.map +1 -0
  319. package/dist/start/index.d.ts +23 -0
  320. package/dist/start/index.d.ts.map +1 -0
  321. package/dist/start/index.js +386 -0
  322. package/dist/start/index.js.map +1 -0
  323. package/dist/sync/index.d.ts +49 -0
  324. package/dist/sync/index.d.ts.map +1 -0
  325. package/dist/sync/index.js +207 -0
  326. package/dist/sync/index.js.map +1 -0
  327. package/dist/sync-engine/__tests__/test-helpers.d.ts +14 -0
  328. package/dist/sync-engine/__tests__/test-helpers.d.ts.map +1 -0
  329. package/dist/sync-engine/__tests__/test-helpers.js +73 -0
  330. package/dist/sync-engine/__tests__/test-helpers.js.map +1 -0
  331. package/dist/sync-engine/client.d.ts +128 -0
  332. package/dist/sync-engine/client.d.ts.map +1 -0
  333. package/dist/sync-engine/client.js +289 -0
  334. package/dist/sync-engine/client.js.map +1 -0
  335. package/dist/sync-engine/health.d.ts +38 -0
  336. package/dist/sync-engine/health.d.ts.map +1 -0
  337. package/dist/sync-engine/health.js +259 -0
  338. package/dist/sync-engine/health.js.map +1 -0
  339. package/dist/sync-engine/index.d.ts +34 -0
  340. package/dist/sync-engine/index.d.ts.map +1 -0
  341. package/dist/sync-engine/index.js +197 -0
  342. package/dist/sync-engine/index.js.map +1 -0
  343. package/dist/sync-engine/protocol.d.ts +153 -0
  344. package/dist/sync-engine/protocol.d.ts.map +1 -0
  345. package/dist/sync-engine/protocol.js +5 -0
  346. package/dist/sync-engine/protocol.js.map +1 -0
  347. package/dist/tasks/index.d.ts +14 -0
  348. package/dist/tasks/index.d.ts.map +1 -0
  349. package/dist/tasks/index.js +109 -0
  350. package/dist/tasks/index.js.map +1 -0
  351. package/dist/team/index.d.ts +12 -0
  352. package/dist/team/index.d.ts.map +1 -0
  353. package/dist/team/index.js +151 -0
  354. package/dist/team/index.js.map +1 -0
  355. package/dist/updater.d.ts +5 -5
  356. package/dist/updater.d.ts.map +1 -1
  357. package/dist/updater.js +24 -88
  358. package/dist/updater.js.map +1 -1
  359. package/dist/usage/index.d.ts +10 -0
  360. package/dist/usage/index.d.ts.map +1 -0
  361. package/dist/usage/index.js +104 -0
  362. package/dist/usage/index.js.map +1 -0
  363. package/dist/webhooks/index.d.ts +7 -0
  364. package/dist/webhooks/index.d.ts.map +1 -0
  365. package/dist/webhooks/index.js +81 -0
  366. package/dist/webhooks/index.js.map +1 -0
  367. package/package.json +26 -15
  368. package/scripts/postinstall.js +282 -0
@@ -0,0 +1,386 @@
1
+ /**
2
+ * Start Module - First-Time User Onboarding
3
+ *
4
+ * Guides new users through initial setup:
5
+ * 1. Check sync engine installation -> prompt to install if missing
6
+ * 2. Check authentication -> run device flow login if not logged in
7
+ * 3. Create first stack -> prompt for name, offer popular extensions
8
+ * 4. Show next steps / quick reference
9
+ */
10
+ import chalk from 'chalk';
11
+ import ora from 'ora';
12
+ import prompts from 'prompts';
13
+ import { existsSync, mkdirSync, writeFileSync } from 'fs';
14
+ import { join } from 'path';
15
+ import { homedir } from 'os';
16
+ import { execFileSync } from 'child_process';
17
+ import { createRequire } from 'node:module';
18
+ import { isSyncEngineProcessRunning, startSyncEngine, getSyncEngineStatus } from '../sync-engine/index.js';
19
+ import { isLoggedIn } from '../auth/config.js';
20
+ import { runLogin } from '../auth/index.js';
21
+ import { getApiClient, ApiError } from '../lib/api.js';
22
+ // Onboarded flag location
23
+ const CLAUDETOOLS_DIR = join(homedir(), '.claudetools');
24
+ const ONBOARDED_FLAG = join(CLAUDETOOLS_DIR, 'onboarded');
25
+ // Popular extensions to suggest during onboarding
26
+ const POPULAR_EXTENSIONS = [
27
+ {
28
+ slug: 'code-review',
29
+ name: 'Code Review',
30
+ description: 'Automated code review with best practices',
31
+ type: 'skill',
32
+ },
33
+ {
34
+ slug: 'git-helper',
35
+ name: 'Git Helper',
36
+ description: 'Git operations and workflow assistance',
37
+ type: 'skill',
38
+ },
39
+ {
40
+ slug: 'test-writer',
41
+ name: 'Test Writer',
42
+ description: 'Generate unit and integration tests',
43
+ type: 'skill',
44
+ },
45
+ {
46
+ slug: 'docs-generator',
47
+ name: 'Docs Generator',
48
+ description: 'Generate documentation from code',
49
+ type: 'skill',
50
+ },
51
+ {
52
+ slug: 'refactor-assistant',
53
+ name: 'Refactor Assistant',
54
+ description: 'Safe code refactoring suggestions',
55
+ type: 'skill',
56
+ },
57
+ ];
58
+ /**
59
+ * Check if user has already completed onboarding
60
+ */
61
+ function isOnboarded() {
62
+ return existsSync(ONBOARDED_FLAG);
63
+ }
64
+ /**
65
+ * Mark onboarding as complete
66
+ */
67
+ function markOnboarded() {
68
+ if (!existsSync(CLAUDETOOLS_DIR)) {
69
+ mkdirSync(CLAUDETOOLS_DIR, { recursive: true });
70
+ }
71
+ writeFileSync(ONBOARDED_FLAG, new Date().toISOString());
72
+ }
73
+ /**
74
+ * Check if a command is available on PATH
75
+ */
76
+ function commandExists(cmd) {
77
+ try {
78
+ const whichCmd = process.platform === 'win32' ? 'where' : 'which';
79
+ execFileSync(whichCmd, [cmd], { stdio: 'ignore' });
80
+ return true;
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ }
86
+ /**
87
+ * Check if sync engine binary is available
88
+ */
89
+ function isSyncEngineInstalled() {
90
+ // Check PATH first
91
+ if (commandExists('claudetools-sync')) {
92
+ return true;
93
+ }
94
+ // Check npm optionalDependency resolution path
95
+ const platform = process.platform;
96
+ const arch = process.arch;
97
+ const pkgName = `@claudetools/sync-${platform}-${arch}`;
98
+ const ext = platform === 'win32' ? '.exe' : '';
99
+ try {
100
+ const require = createRequire(import.meta.url);
101
+ const resolved = require.resolve(`${pkgName}/bin/claudetools-sync${ext}`);
102
+ if (existsSync(resolved))
103
+ return true;
104
+ }
105
+ catch {
106
+ // Package not installed for this platform
107
+ }
108
+ // Check common installation paths
109
+ const fallbackPaths = [
110
+ join(homedir(), '.local', 'bin', 'claudetools-sync'),
111
+ '/usr/local/bin/claudetools-sync',
112
+ ];
113
+ for (const path of fallbackPaths) {
114
+ if (existsSync(path)) {
115
+ return true;
116
+ }
117
+ }
118
+ return false;
119
+ }
120
+ /**
121
+ * Display welcome header
122
+ */
123
+ function displayWelcome() {
124
+ console.log('');
125
+ console.log(chalk.bold.cyan(' ╭─────────────────────────────────────────────╮'));
126
+ console.log(chalk.bold.cyan(' │') + chalk.bold.white(' Welcome to ClaudeTools! ') + chalk.bold.cyan('│'));
127
+ console.log(chalk.bold.cyan(' ╰─────────────────────────────────────────────╯'));
128
+ console.log('');
129
+ console.log(chalk.dim(' Let\'s get you set up in a few quick steps.'));
130
+ console.log('');
131
+ }
132
+ /**
133
+ * Display completion summary
134
+ */
135
+ function displayCompletion(stackCreated, stackName) {
136
+ console.log('');
137
+ console.log(chalk.bold.green(' ╭─────────────────────────────────────────────╮'));
138
+ console.log(chalk.bold.green(' │') + chalk.bold.white(' Setup Complete! ') + chalk.bold.green('│'));
139
+ console.log(chalk.bold.green(' ╰─────────────────────────────────────────────╯'));
140
+ console.log('');
141
+ console.log(chalk.bold(' Quick Reference:'));
142
+ console.log('');
143
+ console.log(` ${chalk.cyan('claudetools search <query>')} Search for extensions`);
144
+ console.log(` ${chalk.cyan('claudetools install <slug>')} Install an extension`);
145
+ console.log(` ${chalk.cyan('claudetools list')} View installed extensions`);
146
+ if (stackCreated && stackName) {
147
+ console.log('');
148
+ console.log(` ${chalk.cyan(`claudetools stacks show ${stackName}`)} View your stack`);
149
+ console.log(` ${chalk.cyan(`claudetools stacks apply ${stackName}`)} Install all stack extensions`);
150
+ }
151
+ console.log('');
152
+ console.log(` ${chalk.cyan('claudetools --help')} See all commands`);
153
+ console.log('');
154
+ console.log(chalk.dim(' For the full TUI experience, run:'));
155
+ console.log(` ${chalk.cyan('claudetools-tui')} or ${chalk.cyan('ct')}`);
156
+ console.log('');
157
+ }
158
+ /**
159
+ * Run the first-time user onboarding flow
160
+ */
161
+ export async function runStart(options = {}) {
162
+ // Check if already onboarded (unless --force)
163
+ if (!options.force && isOnboarded()) {
164
+ console.log('');
165
+ console.log(chalk.dim(' Already set up. Run with --force to re-run onboarding.'));
166
+ console.log('');
167
+ console.log(chalk.bold(' Quick commands:'));
168
+ console.log(` ${chalk.cyan('claudetools search')} Find extensions`);
169
+ console.log(` ${chalk.cyan('claudetools stacks')} Manage your stacks`);
170
+ console.log(` ${chalk.cyan('claudetools --help')} See all commands`);
171
+ console.log('');
172
+ return;
173
+ }
174
+ displayWelcome();
175
+ // ==========================================================================
176
+ // Step 1: Sync Engine Check
177
+ // ==========================================================================
178
+ if (!options.skipSyncEngine) {
179
+ console.log(chalk.cyan(' ▸ Step 1/3: Sync Engine Setup'));
180
+ const syncEngineInstalled = isSyncEngineInstalled();
181
+ if (!syncEngineInstalled) {
182
+ console.log(chalk.yellow(' Sync engine not found'));
183
+ console.log('');
184
+ console.log(chalk.dim(' The sync engine provides background MCP server management.'));
185
+ console.log(chalk.dim(' Reinstall the CLI to get the bundled binary:'));
186
+ console.log('');
187
+ console.log(` ${chalk.cyan('npm install -g @claudetools/cli')}`);
188
+ console.log('');
189
+ const { continueWithout } = await prompts({
190
+ type: 'confirm',
191
+ name: 'continueWithout',
192
+ message: ' Continue without sync engine?',
193
+ initial: true,
194
+ });
195
+ if (!continueWithout) {
196
+ console.log('');
197
+ console.log(chalk.dim(' Run `claudetools start` again after reinstalling.'));
198
+ console.log('');
199
+ return;
200
+ }
201
+ console.log('');
202
+ }
203
+ else {
204
+ // Sync engine is installed, check if running
205
+ const running = isSyncEngineProcessRunning();
206
+ if (!running) {
207
+ const spinner = ora({ text: 'Starting sync engine...', indent: 4 }).start();
208
+ try {
209
+ const { pid } = await startSyncEngine();
210
+ spinner.succeed(chalk.green(`Sync engine started (PID ${pid})`));
211
+ }
212
+ catch (error) {
213
+ spinner.warn(chalk.yellow(`Could not start sync engine: ${error instanceof Error ? error.message : 'Unknown error'}`));
214
+ console.log(chalk.dim(' You can start it later with: claudetools sync start'));
215
+ }
216
+ }
217
+ else {
218
+ const status = await getSyncEngineStatus();
219
+ console.log(chalk.green(` ✓ Sync engine running (PID ${status.pid || 'unknown'})`));
220
+ }
221
+ // Offer TUI installation if not already present
222
+ const tuiInstalled = commandExists('claudetools-tui');
223
+ if (!tuiInstalled) {
224
+ console.log('');
225
+ const { installTui } = await prompts({
226
+ type: 'confirm',
227
+ name: 'installTui',
228
+ message: ' Install ClaudeTools TUI for a full terminal experience?',
229
+ initial: false,
230
+ });
231
+ if (installTui) {
232
+ const tuiSpinner = ora({ text: 'Installing ClaudeTools TUI...', indent: 4 }).start();
233
+ try {
234
+ const npmPath = process.platform === 'win32' ? 'npm.cmd' : 'npm';
235
+ execFileSync(npmPath, ['install', '-g', '@claudetools/tui'], { stdio: 'pipe' });
236
+ tuiSpinner.succeed(chalk.green('ClaudeTools TUI installed!'));
237
+ }
238
+ catch {
239
+ tuiSpinner.warn(chalk.yellow('TUI installation failed. You can install later: npm install -g @claudetools/tui'));
240
+ }
241
+ }
242
+ }
243
+ console.log('');
244
+ }
245
+ }
246
+ else {
247
+ console.log(chalk.dim(' Skipping sync engine check'));
248
+ console.log('');
249
+ }
250
+ // ==========================================================================
251
+ // Step 2: Authentication
252
+ // ==========================================================================
253
+ console.log(chalk.cyan(' ▸ Step 2/3: Authentication'));
254
+ if (isLoggedIn()) {
255
+ console.log(chalk.green(' ✓ Already logged in'));
256
+ console.log('');
257
+ }
258
+ else {
259
+ console.log(chalk.dim(' Sign in to sync stacks and access the marketplace.'));
260
+ console.log('');
261
+ const { doLogin } = await prompts({
262
+ type: 'confirm',
263
+ name: 'doLogin',
264
+ message: ' Sign in now?',
265
+ initial: true,
266
+ });
267
+ if (doLogin) {
268
+ console.log('');
269
+ await runLogin({});
270
+ }
271
+ else {
272
+ console.log('');
273
+ console.log(chalk.dim(' You can sign in later with: claudetools login'));
274
+ console.log('');
275
+ }
276
+ }
277
+ // ==========================================================================
278
+ // Step 3: Create First Stack
279
+ // ==========================================================================
280
+ let stackCreated = false;
281
+ let createdStackName;
282
+ if (!options.skipStack && isLoggedIn()) {
283
+ console.log(chalk.cyan(' ▸ Step 3/3: Create Your First Stack'));
284
+ console.log('');
285
+ console.log(chalk.dim(' Stacks bundle extensions for easy sharing and setup.'));
286
+ console.log('');
287
+ const { createStack } = await prompts({
288
+ type: 'confirm',
289
+ name: 'createStack',
290
+ message: ' Create a stack now?',
291
+ initial: true,
292
+ });
293
+ if (createStack) {
294
+ const { stackName } = await prompts({
295
+ type: 'text',
296
+ name: 'stackName',
297
+ message: ' Stack name:',
298
+ initial: 'My Stack',
299
+ validate: (value) => (value.length > 0 ? true : 'Name is required'),
300
+ });
301
+ if (stackName) {
302
+ console.log('');
303
+ const spinner = ora({ text: 'Creating stack...', indent: 4 }).start();
304
+ try {
305
+ const client = getApiClient({ authenticated: true });
306
+ const response = await client.post('/stacks', { name: stackName });
307
+ if (response.success && response.data) {
308
+ spinner.succeed(chalk.green(`Created stack: ${response.data.stack.name}`));
309
+ stackCreated = true;
310
+ createdStackName = response.data.stack.slug;
311
+ // Offer to add popular extensions
312
+ console.log('');
313
+ console.log(chalk.dim(' Popular extensions to get started:'));
314
+ console.log('');
315
+ const { selectedExtensions } = await prompts({
316
+ type: 'multiselect',
317
+ name: 'selectedExtensions',
318
+ message: ' Add to your stack (space to select, enter to confirm):',
319
+ choices: POPULAR_EXTENSIONS.map((ext) => ({
320
+ title: `${ext.name} - ${chalk.dim(ext.description)}`,
321
+ value: ext.slug,
322
+ })),
323
+ hint: '- Use arrow keys, space to select, enter to submit',
324
+ });
325
+ if (selectedExtensions && selectedExtensions.length > 0) {
326
+ console.log('');
327
+ const addSpinner = ora({ text: 'Adding extensions...', indent: 4 }).start();
328
+ let added = 0;
329
+ for (const extSlug of selectedExtensions) {
330
+ try {
331
+ await client.put(`/stacks/${response.data.stack.id}`, {
332
+ action: 'add',
333
+ extensionSlug: extSlug,
334
+ });
335
+ added++;
336
+ }
337
+ catch {
338
+ // Continue on failure
339
+ }
340
+ }
341
+ addSpinner.succeed(chalk.green(`Added ${added} extension(s) to stack`));
342
+ }
343
+ }
344
+ else {
345
+ spinner.fail(chalk.red('Failed to create stack'));
346
+ }
347
+ }
348
+ catch (error) {
349
+ if (error instanceof ApiError) {
350
+ spinner.fail(chalk.red(`Failed: ${error.message}`));
351
+ }
352
+ else {
353
+ spinner.fail(chalk.red('Failed to create stack'));
354
+ }
355
+ }
356
+ }
357
+ }
358
+ else {
359
+ console.log('');
360
+ console.log(chalk.dim(' Create one later with: claudetools stacks create <name>'));
361
+ }
362
+ console.log('');
363
+ }
364
+ else if (!isLoggedIn()) {
365
+ console.log(chalk.dim(' Skipping stack creation (sign in required)'));
366
+ console.log('');
367
+ }
368
+ // Mark as onboarded
369
+ markOnboarded();
370
+ // Display completion summary
371
+ displayCompletion(stackCreated, createdStackName);
372
+ }
373
+ /**
374
+ * Reset onboarding state (for testing)
375
+ */
376
+ export async function runStartReset() {
377
+ const { unlinkSync } = await import('fs');
378
+ if (existsSync(ONBOARDED_FLAG)) {
379
+ unlinkSync(ONBOARDED_FLAG);
380
+ console.log(chalk.green(' Onboarding state reset.'));
381
+ }
382
+ else {
383
+ console.log(chalk.dim(' No onboarding state to reset.'));
384
+ }
385
+ }
386
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/start/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ export interface SyncStack {
2
+ id: string;
3
+ name: string;
4
+ slug: string;
5
+ description: string | null;
6
+ extensions: Array<{
7
+ type: string;
8
+ slug: string;
9
+ version?: string;
10
+ }>;
11
+ isSynced: boolean;
12
+ createdAt: string;
13
+ updatedAt: string;
14
+ }
15
+ interface SyncResult {
16
+ synced: Array<{
17
+ id: string;
18
+ slug: string;
19
+ synced: boolean;
20
+ }>;
21
+ syncedAt: string;
22
+ }
23
+ /**
24
+ * Sync stacks to/from cloud (Pro/Team tier only)
25
+ * - Pushes local stacks to server
26
+ * - Pulls latest from server
27
+ * - Server wins on conflicts (last-write-wins)
28
+ */
29
+ export declare function syncStacks(options?: {
30
+ silent?: boolean;
31
+ }): Promise<void>;
32
+ /**
33
+ * Push local stacks to cloud
34
+ */
35
+ export declare function pushStacks(localStacks: SyncStack[]): Promise<SyncResult | null>;
36
+ /**
37
+ * Pull stacks from cloud
38
+ */
39
+ export declare function pullStacks(): Promise<SyncStack[] | null>;
40
+ /**
41
+ * Merge cloud stacks with local stacks (server wins on conflict)
42
+ */
43
+ export declare function mergeStacks(local: SyncStack[], cloud: SyncStack[]): SyncStack[];
44
+ /**
45
+ * Run manual sync command - shows local-first sync status
46
+ */
47
+ export declare function runSync(): Promise<void>;
48
+ export {};
49
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,KAAK,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,UAAU;IAClB,MAAM,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC7D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA0ClF;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,WAAW,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA4BrF;AAED;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,CA4B9D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,CAU/E;AAED;;GAEG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAoG7C"}
@@ -0,0 +1,207 @@
1
+ import { getApiClient, ApiError } from '../lib/api.js';
2
+ import { loadConfig } from '../auth/config.js';
3
+ import { getSyncStatus, getFailedTransactions } from '../lib/local-store.js';
4
+ import { hasPendingChanges } from '../lib/hybrid-data.js';
5
+ import { isOnlineCached } from '../lib/network.js';
6
+ import { theme, formatError, formatSuccess, formatWarning, formatInfo } from '../lib/theme.js';
7
+ /**
8
+ * Sync stacks to/from cloud (Pro/Team tier only)
9
+ * - Pushes local stacks to server
10
+ * - Pulls latest from server
11
+ * - Server wins on conflicts (last-write-wins)
12
+ */
13
+ export async function syncStacks(options = {}) {
14
+ const config = loadConfig();
15
+ // Only sync for Pro/Team users
16
+ if (!config.tier || config.tier === 'free') {
17
+ return;
18
+ }
19
+ const log = (msg) => {
20
+ if (!options.silent) {
21
+ console.log(msg);
22
+ }
23
+ };
24
+ try {
25
+ const api = getApiClient({ authenticated: true });
26
+ // Pull latest from cloud (server wins strategy)
27
+ const pullResponse = await api.get('/stacks/sync');
28
+ if (!pullResponse.success || !pullResponse.data) {
29
+ // Check if it's a feature availability error
30
+ if (pullResponse.error?.code === 'FEATURE_UNAVAILABLE') {
31
+ return; // Silently skip sync for free users
32
+ }
33
+ throw new Error(pullResponse.error?.message || 'Failed to pull stacks');
34
+ }
35
+ log(` Synced ${pullResponse.data.stacks.length} stack(s) from cloud`);
36
+ }
37
+ catch (error) {
38
+ if (error instanceof ApiError) {
39
+ if (error.code === 'FEATURE_UNAVAILABLE') {
40
+ return; // Silently skip sync for free users
41
+ }
42
+ if (!options.silent) {
43
+ console.error(` Sync failed: ${error.message}`);
44
+ }
45
+ }
46
+ else if (!options.silent) {
47
+ console.error(` Sync failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
48
+ }
49
+ }
50
+ }
51
+ /**
52
+ * Push local stacks to cloud
53
+ */
54
+ export async function pushStacks(localStacks) {
55
+ const config = loadConfig();
56
+ // Only sync for Pro/Team users
57
+ if (!config.tier || config.tier === 'free') {
58
+ return null;
59
+ }
60
+ try {
61
+ const api = getApiClient({ authenticated: true });
62
+ const response = await api.post('/stacks/sync', { stacks: localStacks });
63
+ if (!response.success || !response.data) {
64
+ if (response.error?.code === 'FEATURE_UNAVAILABLE') {
65
+ return null;
66
+ }
67
+ throw new Error(response.error?.message || 'Failed to push stacks');
68
+ }
69
+ return response.data;
70
+ }
71
+ catch (error) {
72
+ if (error instanceof ApiError && error.code === 'FEATURE_UNAVAILABLE') {
73
+ return null;
74
+ }
75
+ throw error;
76
+ }
77
+ }
78
+ /**
79
+ * Pull stacks from cloud
80
+ */
81
+ export async function pullStacks() {
82
+ const config = loadConfig();
83
+ // Only sync for Pro/Team users
84
+ if (!config.tier || config.tier === 'free') {
85
+ return null;
86
+ }
87
+ try {
88
+ const api = getApiClient({ authenticated: true });
89
+ const response = await api.get('/stacks/sync');
90
+ if (!response.success || !response.data) {
91
+ if (response.error?.code === 'FEATURE_UNAVAILABLE') {
92
+ return null;
93
+ }
94
+ throw new Error(response.error?.message || 'Failed to pull stacks');
95
+ }
96
+ return response.data.stacks;
97
+ }
98
+ catch (error) {
99
+ if (error instanceof ApiError && error.code === 'FEATURE_UNAVAILABLE') {
100
+ return null;
101
+ }
102
+ throw error;
103
+ }
104
+ }
105
+ /**
106
+ * Merge cloud stacks with local stacks (server wins on conflict)
107
+ */
108
+ export function mergeStacks(local, cloud) {
109
+ const merged = new Map();
110
+ // Add all local stacks
111
+ local.forEach(s => merged.set(s.slug, s));
112
+ // Overwrite with cloud stacks (server wins)
113
+ cloud.forEach(s => merged.set(s.slug, { ...s, isSynced: true }));
114
+ return Array.from(merged.values());
115
+ }
116
+ /**
117
+ * Run manual sync command - shows local-first sync status
118
+ */
119
+ export async function runSync() {
120
+ console.log();
121
+ try {
122
+ // Check online status
123
+ const online = await isOnlineCached();
124
+ if (!online) {
125
+ console.log(` ${formatWarning('Offline - cannot sync')}`);
126
+ console.log();
127
+ console.log(` ${theme.muted('Local changes will sync when connection is restored')}`);
128
+ console.log();
129
+ return;
130
+ }
131
+ // Get sync queue status
132
+ const status = await getSyncStatus();
133
+ const pending = await hasPendingChanges();
134
+ console.log(` ${theme.bold('Sync Status')}`);
135
+ console.log();
136
+ // Show queue status
137
+ if (status.pending > 0) {
138
+ console.log(` ${theme.symbols.pending} ${theme.warning('Pending changes')}: ${status.pending}`);
139
+ console.log(` ${theme.muted(`Created: ${status.created}`)}`);
140
+ console.log(` ${theme.muted(`Queued: ${status.queued}`)}`);
141
+ console.log(` ${theme.muted(`Executing: ${status.executing}`)}`);
142
+ }
143
+ else {
144
+ console.log(` ${formatSuccess('All changes synced')}`);
145
+ }
146
+ console.log();
147
+ console.log(` ${theme.muted('Completed')}: ${status.completed}`);
148
+ // Show failed transactions if any
149
+ if (status.failed > 0) {
150
+ console.log();
151
+ console.log(` ${formatError(`Failed: ${status.failed}`, 'ERR_SYNC_FAILED')}`);
152
+ const failed = await getFailedTransactions();
153
+ if (failed.length > 0) {
154
+ console.log();
155
+ console.log(` ${theme.bold('Failed Transactions:')}`);
156
+ for (const txId of failed.slice(0, 5)) {
157
+ console.log(` ${theme.symbols.bullet} ${theme.muted(txId)}`);
158
+ }
159
+ if (failed.length > 5) {
160
+ console.log(` ${theme.muted(`... and ${failed.length - 5} more`)}`);
161
+ }
162
+ }
163
+ }
164
+ console.log();
165
+ // Show sync tip
166
+ if (pending) {
167
+ console.log(` ${theme.muted('Tip: Sync happens automatically in the background')}`);
168
+ }
169
+ else {
170
+ console.log(` ${theme.muted('Everything is up to date')}`);
171
+ }
172
+ console.log();
173
+ }
174
+ catch (error) {
175
+ // Fall back to legacy cloud sync if local store unavailable
176
+ const config = loadConfig();
177
+ if (!config.tier || config.tier === 'free') {
178
+ console.log(` ${formatInfo('Cloud sync requires Pro')}`);
179
+ console.log();
180
+ console.log(' Benefits:');
181
+ console.log(` ${theme.symbols.bullet} Sync stacks across devices`);
182
+ console.log(` ${theme.symbols.bullet} 30-day history & rollback`);
183
+ console.log(` ${theme.symbols.bullet} Unlimited stacks`);
184
+ console.log();
185
+ console.log(` ${theme.command('claudetools upgrade')}`);
186
+ console.log();
187
+ return;
188
+ }
189
+ console.log(` ${formatInfo('Syncing stacks...')}`);
190
+ try {
191
+ const stacks = await pullStacks();
192
+ if (stacks === null) {
193
+ console.log(` ${formatWarning('Sync not available')}`);
194
+ console.log();
195
+ return;
196
+ }
197
+ console.log(` ${formatSuccess(`Synced ${stacks.length} stack(s) from cloud`)}`);
198
+ console.log();
199
+ }
200
+ catch (syncError) {
201
+ console.error(` ${formatError(syncError instanceof Error ? syncError.message : 'Unknown error', 'ERR_SYNC')}`);
202
+ console.log();
203
+ process.exit(1);
204
+ }
205
+ }
206
+ }
207
+ //# sourceMappingURL=index.js.map