@cimplify/cli 0.2.8 → 0.3.1

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 (230) hide show
  1. package/dist/{add-7PTWJV4F.mjs → add-OUMIT4YX.mjs} +10 -10
  2. package/dist/assets-DMK2QOPD.mjs +208 -0
  3. package/dist/chunk-42PFJBC6.mjs +5707 -0
  4. package/dist/{chunk-4SBJVRGM.mjs → chunk-C4M3DXKC.mjs} +3 -1
  5. package/dist/{chunk-NC3GKHDD.mjs → chunk-D7WMSGKK.mjs} +1 -1
  6. package/dist/{chunk-NZ4RG62Z.mjs → chunk-I3XQSSOT.mjs} +4 -1
  7. package/dist/chunk-I6P3I2YJ.mjs +259 -0
  8. package/dist/{chunk-UPEHLREA.mjs → chunk-IQJ45AK3.mjs} +3 -3
  9. package/dist/{chunk-JJYWETGA.mjs → chunk-LS2VTSMQ.mjs} +8 -2
  10. package/dist/{chunk-JOUXICGV.mjs → chunk-MOZQODQS.mjs} +1 -1
  11. package/dist/{chunk-KPGRCXQY.mjs → chunk-QGBXGDA5.mjs} +5 -5
  12. package/dist/chunk-RRY3NEZZ.mjs +79 -0
  13. package/dist/{chunk-L6474RPL.mjs → chunk-RZQTHTXX.mjs} +1 -1
  14. package/dist/{chunk-4YSOZ6LY.mjs → chunk-YI7UMMM7.mjs} +1 -1
  15. package/dist/{deploy-6KVOROT3.mjs → deploy-UKOOPJAE.mjs} +8 -82
  16. package/dist/{dev-AQP6TMYK.mjs → dev-FD4PM3UD.mjs} +5 -5
  17. package/dist/dispatcher.mjs +34 -22
  18. package/dist/doctor-AY7VDIJZ.mjs +314 -0
  19. package/dist/{domains-2ZQ7AG27.mjs → domains-JQMV6GAP.mjs} +5 -5
  20. package/dist/{env-FDBPGU3W.mjs → env-EVMYQUIK.mjs} +6 -6
  21. package/dist/explain-QZVAK5I3.mjs +223 -0
  22. package/dist/introspect-MNTC26UY.mjs +8 -0
  23. package/dist/{link-P4K2HRXY.mjs → link-X3E4UZBF.mjs} +4 -4
  24. package/dist/{list-44MLIFI2.mjs → list-TEQ73IR7.mjs} +3 -3
  25. package/dist/{login-RSKGT6GU.mjs → login-7O7ZXKU3.mjs} +9 -15
  26. package/dist/{logout-ZFZLSJ32.mjs → logout-DJDINVDF.mjs} +2 -2
  27. package/dist/{logs-E2AGTDCF.mjs → logs-KUKGEXR2.mjs} +4 -4
  28. package/dist/{projects-5CJOZ3MT.mjs → projects-364HGWHO.mjs} +13 -11
  29. package/dist/repo-26N2CHF6.mjs +8 -0
  30. package/dist/{rollback-36O4NOEL.mjs → rollback-5YALPQXL.mjs} +5 -5
  31. package/dist/{status-6AT4HF63.mjs → status-W4HW3CX3.mjs} +4 -4
  32. package/dist/{unlink-5ABCT7B6.mjs → unlink-HIIW57OO.mjs} +2 -2
  33. package/dist/{update-6KEG7EWK.mjs → update-2DCENLHM.mjs} +7 -7
  34. package/dist/{whoami-DIJZYZIN.mjs → whoami-LACWBSNL.mjs} +3 -3
  35. package/package.json +3 -3
  36. package/templates/storefront-auto/.claude/skills/cimplify-storefront/SKILL.md +145 -0
  37. package/templates/storefront-auto/.cursor/rules/cimplify-storefront.mdc +25 -0
  38. package/templates/storefront-auto/.env.example +22 -0
  39. package/templates/storefront-auto/AGENTS.md +95 -0
  40. package/templates/storefront-auto/CLAUDE.md +22 -0
  41. package/templates/storefront-auto/README.md +48 -0
  42. package/templates/storefront-auto/__tests__/brand.test.ts +4 -0
  43. package/templates/storefront-auto/__tests__/cart-flow.test.ts +4 -0
  44. package/templates/storefront-auto/__tests__/contract.test.ts +4 -0
  45. package/templates/storefront-auto/app/.well-known/ucp/route.ts +65 -0
  46. package/templates/storefront-auto/app/about/page.tsx +41 -0
  47. package/templates/storefront-auto/app/accessibility/page.tsx +11 -0
  48. package/templates/storefront-auto/app/account/addresses/page.tsx +21 -0
  49. package/templates/storefront-auto/app/account/orders/page.tsx +21 -0
  50. package/templates/storefront-auto/app/account/page.tsx +22 -0
  51. package/templates/storefront-auto/app/account/settings/page.tsx +21 -0
  52. package/templates/storefront-auto/app/cart/page.tsx +9 -0
  53. package/templates/storefront-auto/app/categories/[slug]/listing-client.tsx +19 -0
  54. package/templates/storefront-auto/app/categories/[slug]/page.tsx +130 -0
  55. package/templates/storefront-auto/app/checkout/page.tsx +17 -0
  56. package/templates/storefront-auto/app/collections/[slug]/listing-client.tsx +20 -0
  57. package/templates/storefront-auto/app/collections/[slug]/page.tsx +130 -0
  58. package/templates/storefront-auto/app/contact/contact-form.tsx +109 -0
  59. package/templates/storefront-auto/app/contact/page.tsx +54 -0
  60. package/templates/storefront-auto/app/error.tsx +61 -0
  61. package/templates/storefront-auto/app/faq/page.tsx +46 -0
  62. package/templates/storefront-auto/app/globals.css +47 -0
  63. package/templates/storefront-auto/app/layout.tsx +77 -0
  64. package/templates/storefront-auto/app/llms.txt/route.ts +94 -0
  65. package/templates/storefront-auto/app/login/page.tsx +17 -0
  66. package/templates/storefront-auto/app/not-found.tsx +39 -0
  67. package/templates/storefront-auto/app/opensearch.xml/route.ts +37 -0
  68. package/templates/storefront-auto/app/orders/[id]/page.tsx +24 -0
  69. package/templates/storefront-auto/app/page.tsx +94 -0
  70. package/templates/storefront-auto/app/privacy/page.tsx +44 -0
  71. package/templates/storefront-auto/app/products/[slug]/page.tsx +165 -0
  72. package/templates/storefront-auto/app/products/[slug]/product-detail.tsx +70 -0
  73. package/templates/storefront-auto/app/returns/page.tsx +11 -0
  74. package/templates/storefront-auto/app/robots.ts +18 -0
  75. package/templates/storefront-auto/app/search/page.tsx +38 -0
  76. package/templates/storefront-auto/app/search/search-client.tsx +7 -0
  77. package/templates/storefront-auto/app/shipping/page.tsx +16 -0
  78. package/templates/storefront-auto/app/shop/page.tsx +63 -0
  79. package/templates/storefront-auto/app/shop/shop-client.tsx +32 -0
  80. package/templates/storefront-auto/app/signup/page.tsx +17 -0
  81. package/templates/storefront-auto/app/sitemap-page/page.tsx +167 -0
  82. package/templates/storefront-auto/app/sitemap.ts +59 -0
  83. package/templates/storefront-auto/app/terms/page.tsx +44 -0
  84. package/templates/storefront-auto/app/track-order/page.tsx +24 -0
  85. package/templates/storefront-auto/app/track-order/track-order-form.tsx +69 -0
  86. package/templates/storefront-auto/components/account-iframe.tsx +13 -0
  87. package/templates/storefront-auto/components/auto-hero.tsx +85 -0
  88. package/templates/storefront-auto/components/brand-marquee.tsx +27 -0
  89. package/templates/storefront-auto/components/cart-drawer.tsx +14 -0
  90. package/templates/storefront-auto/components/cart-pill.tsx +36 -0
  91. package/templates/storefront-auto/components/category-grid.tsx +28 -0
  92. package/templates/storefront-auto/components/category-tiles.tsx +104 -0
  93. package/templates/storefront-auto/components/collection-strip.tsx +45 -0
  94. package/templates/storefront-auto/components/feature-hero.tsx +84 -0
  95. package/templates/storefront-auto/components/fitment-finder.tsx +184 -0
  96. package/templates/storefront-auto/components/footer.tsx +153 -0
  97. package/templates/storefront-auto/components/header.tsx +45 -0
  98. package/templates/storefront-auto/components/hero.tsx +28 -0
  99. package/templates/storefront-auto/components/nav-link.tsx +20 -0
  100. package/templates/storefront-auto/components/newsletter.tsx +50 -0
  101. package/templates/storefront-auto/components/policy-page.tsx +49 -0
  102. package/templates/storefront-auto/components/promo-banner.tsx +41 -0
  103. package/templates/storefront-auto/components/providers.tsx +35 -0
  104. package/templates/storefront-auto/components/section-heading.tsx +37 -0
  105. package/templates/storefront-auto/components/service-brief.tsx +65 -0
  106. package/templates/storefront-auto/components/store-product-card.tsx +88 -0
  107. package/templates/storefront-auto/components/trade-in-cta.tsx +54 -0
  108. package/templates/storefront-auto/components/trust-bar.tsx +66 -0
  109. package/templates/storefront-auto/lib/brand.ts +744 -0
  110. package/templates/storefront-auto/lib/cart.ts +12 -0
  111. package/templates/storefront-auto/lib/cimplify-loader.ts +19 -0
  112. package/templates/storefront-auto/next.config.ts +45 -0
  113. package/templates/storefront-auto/package.json +35 -0
  114. package/templates/storefront-auto/postcss.config.mjs +7 -0
  115. package/templates/storefront-auto/tsconfig.json +23 -0
  116. package/templates/storefront-auto/vitest.config.ts +9 -0
  117. package/templates/storefront-bakery/.env.example +2 -2
  118. package/templates/storefront-bakery/README.md +1 -1
  119. package/templates/storefront-bakery/lib/cimplify-loader.ts +19 -0
  120. package/templates/storefront-bakery/next.config.ts +3 -0
  121. package/templates/storefront-bakery/package.json +1 -1
  122. package/templates/storefront-fashion/.env.example +2 -2
  123. package/templates/storefront-fashion/README.md +1 -1
  124. package/templates/storefront-fashion/lib/cimplify-loader.ts +19 -0
  125. package/templates/storefront-fashion/next.config.ts +3 -0
  126. package/templates/storefront-fashion/package.json +1 -1
  127. package/templates/storefront-grocery/.env.example +2 -2
  128. package/templates/storefront-grocery/README.md +1 -1
  129. package/templates/storefront-grocery/lib/cimplify-loader.ts +19 -0
  130. package/templates/storefront-grocery/next.config.ts +3 -0
  131. package/templates/storefront-grocery/package.json +1 -1
  132. package/templates/storefront-pharmacy/.claude/skills/cimplify-storefront/SKILL.md +145 -0
  133. package/templates/storefront-pharmacy/.cursor/rules/cimplify-storefront.mdc +25 -0
  134. package/templates/storefront-pharmacy/.env.example +22 -0
  135. package/templates/storefront-pharmacy/AGENTS.md +118 -0
  136. package/templates/storefront-pharmacy/CLAUDE.md +22 -0
  137. package/templates/storefront-pharmacy/README.md +87 -0
  138. package/templates/storefront-pharmacy/__tests__/brand.test.ts +4 -0
  139. package/templates/storefront-pharmacy/__tests__/cart-flow.test.ts +4 -0
  140. package/templates/storefront-pharmacy/__tests__/contract.test.ts +4 -0
  141. package/templates/storefront-pharmacy/app/.well-known/ucp/route.ts +65 -0
  142. package/templates/storefront-pharmacy/app/about/page.tsx +41 -0
  143. package/templates/storefront-pharmacy/app/accessibility/page.tsx +11 -0
  144. package/templates/storefront-pharmacy/app/account/addresses/page.tsx +21 -0
  145. package/templates/storefront-pharmacy/app/account/orders/page.tsx +21 -0
  146. package/templates/storefront-pharmacy/app/account/page.tsx +22 -0
  147. package/templates/storefront-pharmacy/app/account/settings/page.tsx +21 -0
  148. package/templates/storefront-pharmacy/app/cart/page.tsx +9 -0
  149. package/templates/storefront-pharmacy/app/categories/[slug]/listing-client.tsx +19 -0
  150. package/templates/storefront-pharmacy/app/categories/[slug]/page.tsx +130 -0
  151. package/templates/storefront-pharmacy/app/checkout/page.tsx +17 -0
  152. package/templates/storefront-pharmacy/app/collections/[slug]/listing-client.tsx +20 -0
  153. package/templates/storefront-pharmacy/app/collections/[slug]/page.tsx +130 -0
  154. package/templates/storefront-pharmacy/app/contact/contact-form.tsx +109 -0
  155. package/templates/storefront-pharmacy/app/contact/page.tsx +54 -0
  156. package/templates/storefront-pharmacy/app/error.tsx +61 -0
  157. package/templates/storefront-pharmacy/app/faq/page.tsx +46 -0
  158. package/templates/storefront-pharmacy/app/globals.css +47 -0
  159. package/templates/storefront-pharmacy/app/layout.tsx +77 -0
  160. package/templates/storefront-pharmacy/app/llms.txt/route.ts +94 -0
  161. package/templates/storefront-pharmacy/app/login/page.tsx +17 -0
  162. package/templates/storefront-pharmacy/app/not-found.tsx +39 -0
  163. package/templates/storefront-pharmacy/app/opensearch.xml/route.ts +37 -0
  164. package/templates/storefront-pharmacy/app/orders/[id]/page.tsx +24 -0
  165. package/templates/storefront-pharmacy/app/page.tsx +78 -0
  166. package/templates/storefront-pharmacy/app/privacy/page.tsx +44 -0
  167. package/templates/storefront-pharmacy/app/products/[slug]/page.tsx +165 -0
  168. package/templates/storefront-pharmacy/app/products/[slug]/product-detail.tsx +70 -0
  169. package/templates/storefront-pharmacy/app/returns/page.tsx +11 -0
  170. package/templates/storefront-pharmacy/app/robots.ts +18 -0
  171. package/templates/storefront-pharmacy/app/search/page.tsx +38 -0
  172. package/templates/storefront-pharmacy/app/search/search-client.tsx +7 -0
  173. package/templates/storefront-pharmacy/app/shipping/page.tsx +16 -0
  174. package/templates/storefront-pharmacy/app/shop/page.tsx +63 -0
  175. package/templates/storefront-pharmacy/app/shop/shop-client.tsx +32 -0
  176. package/templates/storefront-pharmacy/app/signup/page.tsx +17 -0
  177. package/templates/storefront-pharmacy/app/sitemap-page/page.tsx +167 -0
  178. package/templates/storefront-pharmacy/app/sitemap.ts +59 -0
  179. package/templates/storefront-pharmacy/app/terms/page.tsx +44 -0
  180. package/templates/storefront-pharmacy/app/track-order/page.tsx +24 -0
  181. package/templates/storefront-pharmacy/app/track-order/track-order-form.tsx +69 -0
  182. package/templates/storefront-pharmacy/components/account-iframe.tsx +13 -0
  183. package/templates/storefront-pharmacy/components/brand-marquee.tsx +27 -0
  184. package/templates/storefront-pharmacy/components/cart-drawer.tsx +14 -0
  185. package/templates/storefront-pharmacy/components/cart-pill.tsx +36 -0
  186. package/templates/storefront-pharmacy/components/category-grid.tsx +28 -0
  187. package/templates/storefront-pharmacy/components/category-tiles.tsx +104 -0
  188. package/templates/storefront-pharmacy/components/collection-strip.tsx +45 -0
  189. package/templates/storefront-pharmacy/components/feature-hero.tsx +84 -0
  190. package/templates/storefront-pharmacy/components/footer.tsx +153 -0
  191. package/templates/storefront-pharmacy/components/header.tsx +45 -0
  192. package/templates/storefront-pharmacy/components/health-brief.tsx +65 -0
  193. package/templates/storefront-pharmacy/components/hero.tsx +28 -0
  194. package/templates/storefront-pharmacy/components/nav-link.tsx +20 -0
  195. package/templates/storefront-pharmacy/components/newsletter.tsx +50 -0
  196. package/templates/storefront-pharmacy/components/pharmacy-hero.tsx +95 -0
  197. package/templates/storefront-pharmacy/components/policy-page.tsx +49 -0
  198. package/templates/storefront-pharmacy/components/promo-banner.tsx +41 -0
  199. package/templates/storefront-pharmacy/components/providers.tsx +35 -0
  200. package/templates/storefront-pharmacy/components/section-heading.tsx +37 -0
  201. package/templates/storefront-pharmacy/components/store-product-card.tsx +88 -0
  202. package/templates/storefront-pharmacy/components/symptom-finder.tsx +108 -0
  203. package/templates/storefront-pharmacy/components/trade-in-cta.tsx +54 -0
  204. package/templates/storefront-pharmacy/components/trust-bar.tsx +66 -0
  205. package/templates/storefront-pharmacy/components/urgent-ctas.tsx +117 -0
  206. package/templates/storefront-pharmacy/lib/brand.ts +790 -0
  207. package/templates/storefront-pharmacy/lib/cart.ts +12 -0
  208. package/templates/storefront-pharmacy/lib/cimplify-loader.ts +19 -0
  209. package/templates/storefront-pharmacy/next.config.ts +45 -0
  210. package/templates/storefront-pharmacy/package.json +35 -0
  211. package/templates/storefront-pharmacy/postcss.config.mjs +7 -0
  212. package/templates/storefront-pharmacy/tsconfig.json +23 -0
  213. package/templates/storefront-pharmacy/vitest.config.ts +9 -0
  214. package/templates/storefront-restaurant/.env.example +2 -2
  215. package/templates/storefront-restaurant/README.md +1 -1
  216. package/templates/storefront-restaurant/lib/cimplify-loader.ts +19 -0
  217. package/templates/storefront-restaurant/next.config.ts +3 -0
  218. package/templates/storefront-restaurant/package.json +1 -1
  219. package/templates/storefront-retail/.env.example +2 -2
  220. package/templates/storefront-retail/README.md +1 -1
  221. package/templates/storefront-retail/lib/cimplify-loader.ts +19 -0
  222. package/templates/storefront-retail/next.config.ts +3 -0
  223. package/templates/storefront-retail/package.json +1 -1
  224. package/templates/storefront-services/.env.example +2 -2
  225. package/templates/storefront-services/README.md +1 -1
  226. package/templates/storefront-services/lib/cimplify-loader.ts +19 -0
  227. package/templates/storefront-services/next.config.ts +3 -0
  228. package/templates/storefront-services/package.json +1 -1
  229. package/dist/chunk-H2HJQGFY.mjs +0 -3911
  230. package/dist/repo-E6SBKVDG.mjs +0 -8
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { REGISTRY_INDEX, REGISTRY } from './chunk-H2HJQGFY.mjs';
3
- import { promptYesNo } from './chunk-L6474RPL.mjs';
4
- import { parseArgs, flagString, flagBool } from './chunk-4SBJVRGM.mjs';
5
- import { CliError, CLI_ERROR_CODE, info, bold, dim, success, result, yellow } from './chunk-NZ4RG62Z.mjs';
2
+ import { REGISTRY_INDEX, REGISTRY } from './chunk-42PFJBC6.mjs';
3
+ import { promptYesNo } from './chunk-RZQTHTXX.mjs';
4
+ import { parseArgs, flagString, flagBool } from './chunk-C4M3DXKC.mjs';
5
+ import { CliError, CLI_ERROR_CODE, info, bold, dim, success, result, yellow } from './chunk-I3XQSSOT.mjs';
6
6
  import { mkdirSync, existsSync, writeFileSync } from 'fs';
7
7
  import { resolve, join, dirname } from 'path';
8
8
 
@@ -54,21 +54,21 @@ async function writeComponent(component, options) {
54
54
  }
55
55
  return outcome;
56
56
  }
57
- function resolveDependencyOrder(roots) {
57
+ function resolveOrder(roots, getDeps) {
58
58
  const visited = /* @__PURE__ */ new Set();
59
59
  const order = [];
60
60
  function visit(name) {
61
61
  if (visited.has(name)) return;
62
62
  visited.add(name);
63
- const component = loadComponent(name);
64
- for (const dep of component.registryDependencies) {
65
- visit(dep);
66
- }
63
+ for (const dep of getDeps(name)) visit(dep);
67
64
  order.push(name);
68
65
  }
69
66
  for (const root of roots) visit(root);
70
67
  return order;
71
68
  }
69
+ function resolveDependencyOrder(roots) {
70
+ return resolveOrder(roots, (name) => loadComponent(name).registryDependencies);
71
+ }
72
72
  async function run(argv) {
73
73
  const args = parseArgs(argv);
74
74
  const dirFlag = flagString(args, "dir");
@@ -122,4 +122,4 @@ async function run(argv) {
122
122
  });
123
123
  }
124
124
 
125
- export { run as default };
125
+ export { run as default, resolveOrder };
@@ -0,0 +1,208 @@
1
+ #!/usr/bin/env node
2
+ import { parseArgs, flagString, flagBool } from './chunk-C4M3DXKC.mjs';
3
+ import { ApiClient } from './chunk-D7WMSGKK.mjs';
4
+ import { readAuth } from './chunk-LS2VTSMQ.mjs';
5
+ import { CliError, CLI_ERROR_CODE, step, yellow, dim, success, info, result, bold, green } from './chunk-I3XQSSOT.mjs';
6
+ import { createHash } from 'crypto';
7
+ import { promises } from 'fs';
8
+ import path from 'path';
9
+
10
+ var MANIFEST_FILE = "cimplify-assets.json";
11
+ var DEFAULT_FOLDER = "assets";
12
+ var MAX_FILE_SIZE_BYTES = 50 * 1024 * 1024;
13
+ var CONTENT_TYPE_FALLBACK = "application/octet-stream";
14
+ var MIME_BY_EXT = {
15
+ ".jpg": "image/jpeg",
16
+ ".jpeg": "image/jpeg",
17
+ ".png": "image/png",
18
+ ".gif": "image/gif",
19
+ ".webp": "image/webp",
20
+ ".avif": "image/avif",
21
+ ".svg": "image/svg+xml",
22
+ ".pdf": "application/pdf",
23
+ ".mp4": "video/mp4",
24
+ ".webm": "video/webm",
25
+ ".woff2": "font/woff2",
26
+ ".woff": "font/woff",
27
+ ".ttf": "font/ttf"
28
+ };
29
+ function endpointInit(businessId) {
30
+ return `/v1/businesses/${encodeURIComponent(businessId)}/assets/init`;
31
+ }
32
+ function endpointConfirm(businessId) {
33
+ return `/v1/businesses/${encodeURIComponent(businessId)}/assets/confirm`;
34
+ }
35
+ function manifestPath(cwd = process.cwd()) {
36
+ return path.join(cwd, MANIFEST_FILE);
37
+ }
38
+ async function readManifest(cwd = process.cwd()) {
39
+ try {
40
+ const raw = await promises.readFile(manifestPath(cwd), "utf8");
41
+ return JSON.parse(raw);
42
+ } catch (err) {
43
+ if (err.code === "ENOENT") return {};
44
+ throw err;
45
+ }
46
+ }
47
+ async function writeManifest(manifest, cwd = process.cwd()) {
48
+ const payload = `${JSON.stringify(manifest, null, 2)}
49
+ `;
50
+ await promises.writeFile(manifestPath(cwd), payload, "utf8");
51
+ }
52
+ function mimeOf(filename) {
53
+ const ext = path.extname(filename).toLowerCase();
54
+ return MIME_BY_EXT[ext] ?? CONTENT_TYPE_FALLBACK;
55
+ }
56
+ function sha256Hex(buf) {
57
+ return createHash("sha256").update(buf).digest("hex");
58
+ }
59
+ async function walkFiles(root) {
60
+ const out = [];
61
+ async function visit(dir) {
62
+ const entries = await promises.readdir(dir, { withFileTypes: true });
63
+ for (const e of entries) {
64
+ const abs = path.join(dir, e.name);
65
+ if (e.isDirectory()) await visit(abs);
66
+ else if (e.isFile()) out.push(abs);
67
+ }
68
+ }
69
+ await visit(root);
70
+ return out;
71
+ }
72
+ async function run(argv) {
73
+ const args = parseArgs(argv);
74
+ const sub = args.positional[0];
75
+ if (!sub) {
76
+ throw new CliError(CLI_ERROR_CODE.INVALID_INPUT, "Usage: cimplify assets <upload|ls|rm>");
77
+ }
78
+ switch (sub) {
79
+ case "upload":
80
+ return runUpload(args);
81
+ case "ls":
82
+ return runLs(args);
83
+ case "rm":
84
+ return runRm(args);
85
+ default:
86
+ throw new CliError(
87
+ CLI_ERROR_CODE.INVALID_INPUT,
88
+ `Unknown subcommand "${sub}". Use upload, ls, or rm.`
89
+ );
90
+ }
91
+ }
92
+ async function runUpload(args) {
93
+ const dir = args.positional[1];
94
+ if (!dir) {
95
+ throw new CliError(CLI_ERROR_CODE.INVALID_INPUT, "Usage: cimplify assets upload <dir> [--folder <path>]");
96
+ }
97
+ const folder = flagString(args, "folder") ?? DEFAULT_FOLDER;
98
+ const force = flagBool(args, "force");
99
+ const root = path.resolve(process.cwd(), dir);
100
+ const stat = await promises.stat(root).catch(() => null);
101
+ if (!stat?.isDirectory()) {
102
+ throw new CliError(CLI_ERROR_CODE.NOT_FOUND, `Directory not found: ${root}`);
103
+ }
104
+ const auth = await readAuth();
105
+ const client = ApiClient.fromAuth(auth);
106
+ const manifest = await readManifest();
107
+ const files = await walkFiles(root);
108
+ const uploaded = [];
109
+ const skipped = [];
110
+ for (const abs of files) {
111
+ const rel = path.relative(root, abs).replaceAll(path.sep, "/");
112
+ const filename = path.basename(rel);
113
+ const keyForManifest = `${folder}/${rel}`;
114
+ const contentType = mimeOf(filename);
115
+ const buf = await promises.readFile(abs);
116
+ if (buf.byteLength > MAX_FILE_SIZE_BYTES) {
117
+ throw new CliError(
118
+ CLI_ERROR_CODE.INVALID_INPUT,
119
+ `${rel}: ${buf.byteLength} bytes exceeds 50 MB limit`
120
+ );
121
+ }
122
+ const hash = sha256Hex(buf);
123
+ const existing = manifest[keyForManifest];
124
+ if (existing && existing.sha256 === hash && !force) {
125
+ step(`${yellow("skip")} ${keyForManifest} ${dim("(unchanged)")}`);
126
+ skipped.push(keyForManifest);
127
+ continue;
128
+ }
129
+ const subfolder = path.posix.join(folder, path.posix.dirname(rel));
130
+ const init = await client.post(endpointInit(auth.businessId), {
131
+ folder: subfolder,
132
+ filename,
133
+ content_type: contentType,
134
+ size_bytes: buf.byteLength
135
+ });
136
+ step(`${dim("\u2192")} ${keyForManifest} ${dim(`(${buf.byteLength} bytes)`)}`);
137
+ const putRes = await fetch(init.upload_url, {
138
+ method: "PUT",
139
+ headers: { "content-type": contentType },
140
+ body: buf
141
+ });
142
+ if (!putRes.ok) {
143
+ throw new CliError(
144
+ CLI_ERROR_CODE.NETWORK_ERROR,
145
+ `PUT to R2 failed for ${keyForManifest}: ${putRes.status} ${putRes.statusText}`
146
+ );
147
+ }
148
+ const confirmed = await client.post(endpointConfirm(auth.businessId), {
149
+ upload_id: init.upload_id
150
+ });
151
+ manifest[keyForManifest] = {
152
+ url: confirmed.url,
153
+ upload_id: init.upload_id,
154
+ folder: subfolder,
155
+ filename,
156
+ content_type: contentType,
157
+ size_bytes: buf.byteLength,
158
+ sha256: hash,
159
+ uploaded_at: (/* @__PURE__ */ new Date()).toISOString()
160
+ };
161
+ uploaded.push(keyForManifest);
162
+ }
163
+ await writeManifest(manifest);
164
+ success(`Uploaded ${uploaded.length} file${uploaded.length === 1 ? "" : "s"} (${skipped.length} skipped)`);
165
+ info(dim(`Manifest: ${manifestPath()}`));
166
+ result({
167
+ uploaded_count: uploaded.length,
168
+ skipped_count: skipped.length,
169
+ manifest_path: manifestPath(),
170
+ uploaded,
171
+ skipped
172
+ });
173
+ }
174
+ async function runLs(args) {
175
+ const prefix = flagString(args, "prefix");
176
+ const manifest = await readManifest();
177
+ const entries = Object.entries(manifest).filter(([k]) => prefix ? k.startsWith(prefix) : true).sort(([a], [b]) => a.localeCompare(b));
178
+ if (entries.length === 0) {
179
+ info(dim("No assets uploaded yet."));
180
+ } else {
181
+ info(bold(`Assets in ${MANIFEST_FILE}:`));
182
+ for (const [key, entry] of entries) {
183
+ info(` ${green("\u25CF")} ${key} ${dim(`\u2192 ${entry.url}`)}`);
184
+ }
185
+ }
186
+ result({
187
+ count: entries.length,
188
+ assets: entries.map(([key, entry]) => ({ key, ...entry }))
189
+ });
190
+ }
191
+ async function runRm(args) {
192
+ const key = args.positional[1];
193
+ if (!key) {
194
+ throw new CliError(CLI_ERROR_CODE.INVALID_INPUT, "Usage: cimplify assets rm <key>");
195
+ }
196
+ const manifest = await readManifest();
197
+ if (!(key in manifest)) {
198
+ throw new CliError(CLI_ERROR_CODE.NOT_FOUND, `Key not found in manifest: ${key}`);
199
+ }
200
+ const removed = manifest[key];
201
+ delete manifest[key];
202
+ await writeManifest(manifest);
203
+ success(`Removed ${key} from manifest`);
204
+ info(dim("Note: remote blob is not deleted in v1 \u2014 only the manifest entry."));
205
+ result({ removed_key: key, removed_url: removed.url });
206
+ }
207
+
208
+ export { run as default, endpointConfirm, endpointInit, mimeOf, readManifest, sha256Hex, walkFiles, writeManifest };