@cimplify/cli 0.14.0 → 0.15.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 (70) hide show
  1. package/README.md +1 -1
  2. package/dist/{add-PPUGTTDA.mjs → add-X3OUBJ7D.mjs} +3 -3
  3. package/dist/{assets-OEY6FHHZ.mjs → assets-CWB72PZG.mjs} +3 -3
  4. package/dist/{auth-step-up-ALEUQUCE.mjs → auth-step-up-Z6KOTTV7.mjs} +19 -17
  5. package/dist/{cancel-FD66LTTS.mjs → cancel-ZHVVILOU.mjs} +3 -3
  6. package/dist/{chunk-4O4G2CDE.mjs → chunk-3QUK5BPY.mjs} +7 -3
  7. package/dist/{chunk-7CI5RWNE.mjs → chunk-A6WHBSXZ.mjs} +5 -5
  8. package/dist/{chunk-IK6NQHTG.mjs → chunk-DMLQBAGC.mjs} +4 -11
  9. package/dist/{dev-L3W6UXYN.mjs → chunk-F2UI225N.mjs} +5 -5
  10. package/dist/{chunk-RU53TQLZ.mjs → chunk-I2UP7YTG.mjs} +1 -1
  11. package/dist/{chunk-YIBOOKQQ.mjs → chunk-KN2YSKXZ.mjs} +1 -1
  12. package/dist/{chunk-KAZMZD4X.mjs → chunk-MGQD5MEC.mjs} +3 -3
  13. package/dist/{chunk-6CHBU7O4.mjs → chunk-MLE4MVYC.mjs} +1 -1
  14. package/dist/chunk-MTEMM6WI.mjs +6463 -0
  15. package/dist/{chunk-PDGKBATF.mjs → chunk-NK6VC264.mjs} +1 -1
  16. package/dist/{chunk-TOQGLBWF.mjs → chunk-NYXA6X56.mjs} +1 -1
  17. package/dist/{chunk-5ZQURRIM.mjs → chunk-TH4XENKH.mjs} +1 -1
  18. package/dist/{chunk-SOYZZZVT.mjs → chunk-WAHYTXOF.mjs} +5 -5
  19. package/dist/{deploy-64ZVAQ3R.mjs → deploy-JE6TUYCL.mjs} +53 -9
  20. package/dist/dev-V7JSUVOI.mjs +8 -0
  21. package/dist/dispatcher.mjs +30 -30
  22. package/dist/{doctor-6ZIFM5J5.mjs → doctor-YP5NOD75.mjs} +12 -14
  23. package/dist/{domains-7D7WJAMC.mjs → domains-BZKGIDF4.mjs} +4 -4
  24. package/dist/{env-PAENNABF.mjs → env-FZNXKLGL.mjs} +5 -5
  25. package/dist/{explain-REIDDRKC.mjs → explain-YX5DKW5T.mjs} +5 -5
  26. package/dist/{inspect-MGVG4Z44.mjs → inspect-X3M7WSTL.mjs} +2 -2
  27. package/dist/introspect-HI65VEHQ.mjs +8 -0
  28. package/dist/{link-AWC7VJNN.mjs → link-4NM2QMI5.mjs} +4 -4
  29. package/dist/{lint-EYKIQ6RO.mjs → lint-DDZ7HUQN.mjs} +1 -1
  30. package/dist/{list-7ZL6FRKT.mjs → list-PRB7KCPF.mjs} +2 -2
  31. package/dist/{login-NCO4P5G5.mjs → login-RLMDEWAL.mjs} +11 -15
  32. package/dist/{logout-MF6SOLPE.mjs → logout-Z57X6HPE.mjs} +2 -2
  33. package/dist/{logs-76TCJBIQ.mjs → logs-36BLYJHJ.mjs} +3 -3
  34. package/dist/{mock-CAWNXSGC.mjs → mock-EVER34IX.mjs} +1 -1
  35. package/dist/{projects-P65SUETQ.mjs → projects-4XRNHJAH.mjs} +3 -3
  36. package/dist/repo-X3KZ5R64.mjs +9 -0
  37. package/dist/{rollback-ZL3V7SYH.mjs → rollback-WCRWXSE3.mjs} +4 -4
  38. package/dist/{status-52HG63FE.mjs → status-VA326DWD.mjs} +3 -3
  39. package/dist/{unlink-TCG3NBAR.mjs → unlink-H3BO3DOQ.mjs} +2 -2
  40. package/dist/{update-MBEPZANS.mjs → update-62RJTAMU.mjs} +3 -3
  41. package/dist/{whoami-B5Y5KSOZ.mjs → whoami-CQPPARRS.mjs} +4 -4
  42. package/package.json +3 -3
  43. package/templates/manifest.json +26 -26
  44. package/templates/storefront-auto/app/account/orders/page.tsx +1 -2
  45. package/templates/storefront-auto/bun.lock +7 -69
  46. package/templates/storefront-auto/package.json +1 -1
  47. package/templates/storefront-bakery/app/account/orders/page.tsx +1 -2
  48. package/templates/storefront-bakery/bun.lock +7 -69
  49. package/templates/storefront-bakery/package.json +1 -1
  50. package/templates/storefront-fashion/app/account/orders/page.tsx +1 -2
  51. package/templates/storefront-fashion/bun.lock +7 -69
  52. package/templates/storefront-fashion/package.json +1 -1
  53. package/templates/storefront-grocery/app/account/orders/page.tsx +1 -2
  54. package/templates/storefront-grocery/bun.lock +7 -69
  55. package/templates/storefront-grocery/package.json +1 -1
  56. package/templates/storefront-pharmacy/app/account/orders/page.tsx +1 -2
  57. package/templates/storefront-pharmacy/bun.lock +7 -69
  58. package/templates/storefront-pharmacy/package.json +1 -1
  59. package/templates/storefront-restaurant/app/account/orders/page.tsx +1 -2
  60. package/templates/storefront-restaurant/bun.lock +7 -69
  61. package/templates/storefront-restaurant/package.json +1 -1
  62. package/templates/storefront-retail/app/account/orders/page.tsx +1 -2
  63. package/templates/storefront-retail/bun.lock +7 -69
  64. package/templates/storefront-retail/package.json +1 -1
  65. package/templates/storefront-services/app/account/orders/page.tsx +1 -2
  66. package/templates/storefront-services/bun.lock +7 -69
  67. package/templates/storefront-services/package.json +1 -1
  68. package/dist/chunk-JOF7ESSA.mjs +0 -6463
  69. package/dist/introspect-APRI7R7K.mjs +0 -8
  70. package/dist/repo-ZPYZK3KW.mjs +0 -9
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { TERMINAL_DEPLOYMENT_STATUSES, DEPLOYMENT_STATUS } from './chunk-MXYUAJEW.mjs';
3
- import { dim, CliError, CLI_ERROR_CODE, failure, success, isJsonMode } from './chunk-4O4G2CDE.mjs';
3
+ import { dim, CliError, CLI_ERROR_CODE, failure, success, isJsonMode } from './chunk-3QUK5BPY.mjs';
4
4
 
5
5
  // src/progress.ts
6
6
  var POLL_INTERVAL_MS = 1e3;
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { CliError, CLI_ERROR_CODE } from './chunk-4O4G2CDE.mjs';
2
+ import { CliError, CLI_ERROR_CODE } from './chunk-3QUK5BPY.mjs';
3
3
 
4
4
  // src/api-client.ts
5
5
  var DEFAULT_API_BASE_URL = "https://api.cimplify.io";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { isAutoYes, isInteractive, CliError, CLI_ERROR_CODE } from './chunk-4O4G2CDE.mjs';
2
+ import { isAutoYes, isInteractive, CliError, CLI_ERROR_CODE } from './chunk-3QUK5BPY.mjs';
3
3
  import readline from 'readline';
4
4
 
5
5
  async function promptLine(question) {
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { parseEnvFile } from './chunk-RU53TQLZ.mjs';
3
- import { package_default } from './chunk-KAZMZD4X.mjs';
4
- import { gitDetectRoot, gitCurrentBranch, gitCurrentSha, gitStatusPorcelain } from './chunk-YIBOOKQQ.mjs';
2
+ import { parseEnvFile } from './chunk-I2UP7YTG.mjs';
3
+ import { package_default } from './chunk-MGQD5MEC.mjs';
4
+ import { gitDetectRoot, gitCurrentBranch, gitCurrentSha, gitStatusPorcelain } from './chunk-KN2YSKXZ.mjs';
5
5
  import { parseArgs } from './chunk-5KYR6WJB.mjs';
6
- import { readAuthOrNull, readProjectLinkOrNull, readProjectState } from './chunk-6CHBU7O4.mjs';
7
- import { bold, dim, yellow, green, info, result, red } from './chunk-4O4G2CDE.mjs';
6
+ import { readAuthOrNull, readProjectLinkOrNull, readProjectState } from './chunk-MLE4MVYC.mjs';
7
+ import { bold, dim, yellow, green, info, result, red } from './chunk-3QUK5BPY.mjs';
8
8
  import { promises } from 'fs';
9
9
  import path from 'path';
10
10
 
@@ -1,21 +1,29 @@
1
1
  #!/usr/bin/env node
2
- import { pollDeployment } from './chunk-PDGKBATF.mjs';
3
- import { fetchRepoRecord, fetchCloneToken } from './chunk-7CI5RWNE.mjs';
4
- import { promptYesNo } from './chunk-5ZQURRIM.mjs';
2
+ import { detectPackageManager } from './chunk-F2UI225N.mjs';
3
+ import { fetchRepoRecord, fetchCloneToken } from './chunk-A6WHBSXZ.mjs';
4
+ import { pollDeployment } from './chunk-NK6VC264.mjs';
5
+ import './chunk-I2UP7YTG.mjs';
6
+ import { promptYesNo } from './chunk-TH4XENKH.mjs';
5
7
  import { REPO_PROVIDER, ENV_SCOPE, DEPLOY_TRIGGER, DEPLOYMENT_STATUS, TOKEN_PURPOSE } from './chunk-MXYUAJEW.mjs';
6
- import { isFreestyleRemote, gitDetectRoot, gitStatusPorcelain, gitCurrentBranch, gitCurrentSha, gitGetRemoteUrl, gitPushToUrl, gitPush } from './chunk-YIBOOKQQ.mjs';
8
+ import { isFreestyleRemote, gitDetectRoot, gitStatusPorcelain, gitCurrentBranch, gitCurrentSha, gitGetRemoteUrl, gitPushToUrl, gitPush } from './chunk-KN2YSKXZ.mjs';
7
9
  import { parseArgs, flagBool, flagString } from './chunk-5KYR6WJB.mjs';
8
- import { ApiClient } from './chunk-TOQGLBWF.mjs';
9
- import { readAuth, readProjectLink, writeProjectState } from './chunk-6CHBU7O4.mjs';
10
- import { CliError, CLI_ERROR_CODE, info, dim, step, success, result, EXIT_CODE } from './chunk-4O4G2CDE.mjs';
10
+ import { ApiClient } from './chunk-NYXA6X56.mjs';
11
+ import { readAuth, readProjectLink, writeProjectState } from './chunk-MLE4MVYC.mjs';
12
+ import { info, dim, step, CliError, CLI_ERROR_CODE, success, result, EXIT_CODE } from './chunk-3QUK5BPY.mjs';
13
+ import { spawn } from 'child_process';
14
+ import { promises } from 'fs';
15
+ import path from 'path';
11
16
 
12
- // src/commands/deploy.ts
13
17
  var FLAG_PROD = "prod";
14
18
  var FLAG_REF = "ref";
15
19
  var FLAG_NO_PUSH = "no-push";
16
20
  var FLAG_ALLOW_DIRTY = "allow-dirty";
17
21
  var FLAG_NO_POLL = "no-poll";
18
22
  var FLAG_SKIP_ENV_CHECK = "skip-env-check";
23
+ var FLAG_SKIP_BUILD = "skip-build";
24
+ var SCRIPT_BUILD = "build";
25
+ var NODE_MODULES_DIR = "node_modules";
26
+ var PACKAGE_JSON_FILE = "package.json";
19
27
  function deployEndpoint(businessId, projectId) {
20
28
  return `/v1/businesses/${encodeURIComponent(businessId)}/projects/${encodeURIComponent(projectId)}/deploy`;
21
29
  }
@@ -26,6 +34,39 @@ function missingProductionKeys(preview, production) {
26
34
  const productionKeys = new Set(production.map((record) => record.key));
27
35
  return [...new Set(preview.map((record) => record.key))].filter((key) => !productionKeys.has(key)).sort();
28
36
  }
37
+ async function runLocalBuildCheck(cwd) {
38
+ let pkg;
39
+ try {
40
+ pkg = JSON.parse(await promises.readFile(path.join(cwd, PACKAGE_JSON_FILE), "utf8"));
41
+ } catch {
42
+ return "skipped_no_package";
43
+ }
44
+ if (!pkg.scripts?.[SCRIPT_BUILD]) {
45
+ return "skipped_no_script";
46
+ }
47
+ try {
48
+ await promises.stat(path.join(cwd, NODE_MODULES_DIR));
49
+ } catch {
50
+ info(dim("Dependencies not installed locally \u2014 skipping the local build check."));
51
+ return "skipped_no_modules";
52
+ }
53
+ const pm = await detectPackageManager(cwd);
54
+ step(`Building locally first (${pm} run ${SCRIPT_BUILD}) to catch failures before the cloud`);
55
+ const code = await new Promise((resolve, reject) => {
56
+ const child = spawn(pm, ["run", SCRIPT_BUILD], { cwd, stdio: "inherit" });
57
+ child.on("error", reject);
58
+ child.on("close", (exit) => resolve(exit ?? 1));
59
+ });
60
+ if (code !== 0) {
61
+ throw new CliError(
62
+ CLI_ERROR_CODE.BUILD_FAILED,
63
+ `Local build failed (exit ${code}), so the deploy was not started.
64
+ Fix the build errors above, or deploy anyway with --${FLAG_SKIP_BUILD} if your machine is the problem.`
65
+ );
66
+ }
67
+ success("Local build passed");
68
+ return "passed";
69
+ }
29
70
  async function checkProductionEnv(client, businessId, projectId) {
30
71
  const [preview, production] = await Promise.all([
31
72
  client.get(envEndpoint(businessId, projectId), {
@@ -121,6 +162,7 @@ async function run(argv) {
121
162
  if (flagBool(args, FLAG_PROD) && !flagBool(args, FLAG_SKIP_ENV_CHECK)) {
122
163
  await checkProductionEnv(client, link.businessId, link.projectId);
123
164
  }
165
+ const buildCheck = flagBool(args, FLAG_SKIP_BUILD) ? "skipped_flag" : await runLocalBuildCheck(cwd);
124
166
  if (!flagBool(args, FLAG_NO_PUSH)) {
125
167
  await pushForDeploy(client, link.businessId, link.projectId, root, branch, link.remoteUrl);
126
168
  } else {
@@ -154,6 +196,7 @@ async function run(argv) {
154
196
  }
155
197
  if (flagBool(args, FLAG_NO_POLL)) {
156
198
  result({
199
+ build_check: buildCheck,
157
200
  deployment: {
158
201
  id: enqueued.deployment_id,
159
202
  git_sha: enqueued.git_sha,
@@ -171,6 +214,7 @@ async function run(argv) {
171
214
  enqueued.deployment_id
172
215
  );
173
216
  result({
217
+ build_check: buildCheck,
174
218
  deployment: {
175
219
  id: enqueued.deployment_id,
176
220
  git_sha: enqueued.git_sha,
@@ -191,4 +235,4 @@ async function run(argv) {
191
235
  process.exitCode = EXIT_CODE.ERROR;
192
236
  }
193
237
 
194
- export { run as default, missingProductionKeys, resolvePushStrategy };
238
+ export { run as default, missingProductionKeys, resolvePushStrategy, runLocalBuildCheck };
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ export { run as default, detectPackageManager, mergeEnvEntries } from './chunk-F2UI225N.mjs';
3
+ import './chunk-I2UP7YTG.mjs';
4
+ import './chunk-MXYUAJEW.mjs';
5
+ import './chunk-5KYR6WJB.mjs';
6
+ import './chunk-NYXA6X56.mjs';
7
+ import './chunk-MLE4MVYC.mjs';
8
+ import './chunk-3QUK5BPY.mjs';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { TEMPLATES } from './chunk-JOF7ESSA.mjs';
3
- import { package_default } from './chunk-KAZMZD4X.mjs';
2
+ import { TEMPLATES } from './chunk-MTEMM6WI.mjs';
3
+ import { package_default } from './chunk-MGQD5MEC.mjs';
4
4
 
5
5
  // src/dispatcher.ts
6
6
  var VERSION = package_default.version ?? "unknown";
@@ -100,7 +100,7 @@ Init flags:
100
100
  Login flags:
101
101
  (no flags) Open a browser to authorize this CLI (default)
102
102
  --no-browser Print the URL instead of opening it (useful over SSH)
103
- --api-key <dk_...> Skip the browser and authenticate with a key (CI / headless)
103
+ --api-key <cak_...> Skip the browser with a user-bound Personal key
104
104
  --base-url <url> API base URL (env: CIMPLIFY_CLI_API_URL; default https://api.cimplify.io)
105
105
 
106
106
  Deploy flags:
@@ -134,33 +134,33 @@ Local mock server (custom demo data, no fork needed):
134
134
  cimplify mock --seed-module ./seed.ts Boot from a seed module (defineSeed from @cimplify/sdk/mock)
135
135
  `;
136
136
  var COMMANDS = {
137
- login: () => import('./login-NCO4P5G5.mjs'),
138
- logout: () => import('./logout-MF6SOLPE.mjs'),
139
- whoami: () => import('./whoami-B5Y5KSOZ.mjs'),
140
- projects: () => import('./projects-P65SUETQ.mjs'),
141
- link: () => import('./link-AWC7VJNN.mjs'),
142
- unlink: () => import('./unlink-TCG3NBAR.mjs'),
143
- deploy: () => import('./deploy-64ZVAQ3R.mjs'),
144
- cancel: () => import('./cancel-FD66LTTS.mjs'),
145
- rollback: () => import('./rollback-ZL3V7SYH.mjs'),
146
- env: () => import('./env-PAENNABF.mjs'),
147
- domains: () => import('./domains-7D7WJAMC.mjs'),
148
- logs: () => import('./logs-76TCJBIQ.mjs'),
149
- status: () => import('./status-52HG63FE.mjs'),
150
- dev: () => import('./dev-L3W6UXYN.mjs'),
151
- mock: () => import('./mock-CAWNXSGC.mjs'),
152
- introspect: () => import('./introspect-APRI7R7K.mjs'),
153
- inspect: () => import('./inspect-MGVG4Z44.mjs'),
154
- doctor: () => import('./doctor-6ZIFM5J5.mjs'),
155
- lint: () => import('./lint-EYKIQ6RO.mjs'),
156
- explain: () => import('./explain-REIDDRKC.mjs'),
157
- assets: () => import('./assets-OEY6FHHZ.mjs'),
158
- repo: () => import('./repo-ZPYZK3KW.mjs'),
159
- list: () => import('./list-7ZL6FRKT.mjs'),
160
- add: () => import('./add-PPUGTTDA.mjs'),
161
- update: () => import('./update-MBEPZANS.mjs'),
162
- upgrade: () => import('./update-MBEPZANS.mjs'),
163
- "auth-step-up": () => import('./auth-step-up-ALEUQUCE.mjs')
137
+ login: () => import('./login-RLMDEWAL.mjs'),
138
+ logout: () => import('./logout-Z57X6HPE.mjs'),
139
+ whoami: () => import('./whoami-CQPPARRS.mjs'),
140
+ projects: () => import('./projects-4XRNHJAH.mjs'),
141
+ link: () => import('./link-4NM2QMI5.mjs'),
142
+ unlink: () => import('./unlink-H3BO3DOQ.mjs'),
143
+ deploy: () => import('./deploy-JE6TUYCL.mjs'),
144
+ cancel: () => import('./cancel-ZHVVILOU.mjs'),
145
+ rollback: () => import('./rollback-WCRWXSE3.mjs'),
146
+ env: () => import('./env-FZNXKLGL.mjs'),
147
+ domains: () => import('./domains-BZKGIDF4.mjs'),
148
+ logs: () => import('./logs-36BLYJHJ.mjs'),
149
+ status: () => import('./status-VA326DWD.mjs'),
150
+ dev: () => import('./dev-V7JSUVOI.mjs'),
151
+ mock: () => import('./mock-EVER34IX.mjs'),
152
+ introspect: () => import('./introspect-HI65VEHQ.mjs'),
153
+ inspect: () => import('./inspect-X3M7WSTL.mjs'),
154
+ doctor: () => import('./doctor-YP5NOD75.mjs'),
155
+ lint: () => import('./lint-DDZ7HUQN.mjs'),
156
+ explain: () => import('./explain-YX5DKW5T.mjs'),
157
+ assets: () => import('./assets-CWB72PZG.mjs'),
158
+ repo: () => import('./repo-X3KZ5R64.mjs'),
159
+ list: () => import('./list-PRB7KCPF.mjs'),
160
+ add: () => import('./add-X3OUBJ7D.mjs'),
161
+ update: () => import('./update-62RJTAMU.mjs'),
162
+ upgrade: () => import('./update-62RJTAMU.mjs'),
163
+ "auth-step-up": () => import('./auth-step-up-Z6KOTTV7.mjs')
164
164
  };
165
165
  var COMMAND_PREFIXES = {
166
166
  auth: { "step-up": "auth-step-up" }
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import { gatherIntrospection } from './chunk-SOYZZZVT.mjs';
3
- import './chunk-RU53TQLZ.mjs';
4
- import './chunk-KAZMZD4X.mjs';
5
- import './chunk-YIBOOKQQ.mjs';
2
+ import { gatherIntrospection } from './chunk-WAHYTXOF.mjs';
3
+ import './chunk-I2UP7YTG.mjs';
4
+ import './chunk-MGQD5MEC.mjs';
5
+ import './chunk-KN2YSKXZ.mjs';
6
6
  import { parseArgs, flagBool } from './chunk-5KYR6WJB.mjs';
7
- import { SDK_ENV_API_URL, DEFAULT_API_BASE_URL, ApiClient, ENV_API_BASE_URL } from './chunk-TOQGLBWF.mjs';
8
- import { readAuthOrNull } from './chunk-6CHBU7O4.mjs';
9
- import { bold, dim, info, result, isCliError, CLI_ERROR_CODE, red, yellow, green } from './chunk-4O4G2CDE.mjs';
7
+ import { SDK_ENV_API_URL, DEFAULT_API_BASE_URL, ApiClient, ENV_API_BASE_URL } from './chunk-NYXA6X56.mjs';
8
+ import { readAuthOrNull } from './chunk-MLE4MVYC.mjs';
9
+ import { bold, dim, info, result, isCliError, CLI_ERROR_CODE, red, yellow, green } from './chunk-3QUK5BPY.mjs';
10
10
  import { promises } from 'fs';
11
11
  import path from 'path';
12
12
 
13
- var ENDPOINT_AUTH_ME = "/v1/auth/me";
13
+ var ENDPOINT_AUTH_ME = "/v1/auth/cli/me";
14
14
  var NON_BUN_LOCKFILES = ["package-lock.json", "yarn.lock", "pnpm-lock.yaml"];
15
15
  var BUN_LOCKFILES = ["bun.lock", "bun.lockb"];
16
16
  function ok(name, message) {
@@ -60,7 +60,9 @@ function deriveLocalChecks(snapshot, extras) {
60
60
  } else {
61
61
  checks.push(ok("package_json", snapshot.package.name ?? "(unnamed)"));
62
62
  if (!extras.nodeModules) {
63
- checks.push(fail("node_modules", "missing \u2014 dependencies not installed", "run `bun install`"));
63
+ checks.push(
64
+ fail("node_modules", "missing \u2014 dependencies not installed", "run `bun install`")
65
+ );
64
66
  } else {
65
67
  checks.push(ok("node_modules", "installed"));
66
68
  }
@@ -80,11 +82,7 @@ function deriveLocalChecks(snapshot, extras) {
80
82
  const pin = snapshot.package.sdk_pin;
81
83
  if (!pin) {
82
84
  checks.push(
83
- fail(
84
- "sdk_pin",
85
- "@cimplify/sdk not in dependencies",
86
- "run `bun add @cimplify/sdk`"
87
- )
85
+ fail("sdk_pin", "@cimplify/sdk not in dependencies", "run `bun add @cimplify/sdk`")
88
86
  );
89
87
  } else if (pin === "*" || pin === "latest") {
90
88
  checks.push(
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { promptYesNo } from './chunk-5ZQURRIM.mjs';
2
+ import { promptYesNo } from './chunk-TH4XENKH.mjs';
3
3
  import { ENV_SCOPE, DOMAIN_TYPE } from './chunk-MXYUAJEW.mjs';
4
4
  import { parseArgs, flagBool, flagString } from './chunk-5KYR6WJB.mjs';
5
- import { ApiClient } from './chunk-TOQGLBWF.mjs';
6
- import { readAuth, readProjectLink } from './chunk-6CHBU7O4.mjs';
7
- import { CliError, CLI_ERROR_CODE, result, info, dim, bold, success } from './chunk-4O4G2CDE.mjs';
5
+ import { ApiClient } from './chunk-NYXA6X56.mjs';
6
+ import { readAuth, readProjectLink } from './chunk-MLE4MVYC.mjs';
7
+ import { CliError, CLI_ERROR_CODE, result, info, dim, bold, success } from './chunk-3QUK5BPY.mjs';
8
8
 
9
9
  // src/commands/domains.ts
10
10
  var SUB_LS = "ls";
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { formatEnvFile, parseEnvFile, parseKeyValueArg } from './chunk-RU53TQLZ.mjs';
3
- import { promptYesNo } from './chunk-5ZQURRIM.mjs';
2
+ import { formatEnvFile, parseEnvFile, parseKeyValueArg } from './chunk-I2UP7YTG.mjs';
3
+ import { promptYesNo } from './chunk-TH4XENKH.mjs';
4
4
  import { ENV_SCOPE, PUBLIC_ENV_PREFIX, SECRET_MASK } from './chunk-MXYUAJEW.mjs';
5
5
  import { parseArgs, flagString, flagBool } from './chunk-5KYR6WJB.mjs';
6
- import { ApiClient } from './chunk-TOQGLBWF.mjs';
7
- import { readAuth, readProjectLink } from './chunk-6CHBU7O4.mjs';
8
- import { CliError, CLI_ERROR_CODE, info, dim, result, bold, success } from './chunk-4O4G2CDE.mjs';
6
+ import { ApiClient } from './chunk-NYXA6X56.mjs';
7
+ import { readAuth, readProjectLink } from './chunk-MLE4MVYC.mjs';
8
+ import { CliError, CLI_ERROR_CODE, info, dim, result, bold, success } from './chunk-3QUK5BPY.mjs';
9
9
  import { promises } from 'fs';
10
10
  import path from 'path';
11
11
 
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { package_default } from './chunk-KAZMZD4X.mjs';
2
+ import { package_default } from './chunk-MGQD5MEC.mjs';
3
3
  import { parseArgs } from './chunk-5KYR6WJB.mjs';
4
- import { bold, dim, info, result, CliError, CLI_ERROR_CODE } from './chunk-4O4G2CDE.mjs';
4
+ import { bold, dim, info, result, CliError, CLI_ERROR_CODE } from './chunk-3QUK5BPY.mjs';
5
5
 
6
6
  // src/embedded-docs.ts
7
7
  var TOPICS = [
@@ -80,14 +80,14 @@ var TOPICS = [
80
80
  "title": "Checkout",
81
81
  "description": "Flat ProcessArgs body for /checkout, payment methods",
82
82
  "source_url": "https://cimplify.dev/docs/sdk/checkout",
83
- "body": "## Process a checkout\n\n \n \n\n```ts\nconst r = await client.checkout.process({\n cart_id: cart.id,\n location_id: 'loc_main',\n order_type: 'pickup', // 'delivery' | 'pickup' | 'dine-in' | 'walk-in'\n payment_method: 'mobile_money', // 'mobile_money' | 'card'\n customer: {\n name: 'Jane Doe',\n email: 'jane@example.com',\n phone: '+233244000000',\n save_details: true,\n },\n address_info: {\n pickup_time: '2026-05-08T15:00:00Z',\n },\n mobile_money_details: {\n phone_number: '+233244000000',\n provider: 'mtn',\n },\n special_instructions: 'No straw, please.',\n})\n\nif (!r.ok) {\n console.error(r.error.code, r.error.message)\n return\n}\n\nconst result = r.value\nconsole.log(result.order_id, result.order_number)\nconsole.log(result.payment_status) // 'pending' | 'success' | 'failed' | ...\nconsole.log(result.requires_authorization)\nconsole.log(result.next_action) // discriminated union, see below\n```\n\n \n\n \n\n## bill_token: guest order lookups\n\n \n\nOn a successful guest checkout the response carries a `bill_token`. The SDK persists it client-side keyed by `order_id`, then attaches it to every subsequent ` orders.get` / `checkout.pollPaymentStatus` call. You do not need to thread it through manually; it just works in the same browser session.\n\n \n \n\n```ts\nif (r.ok && r.value.bill_token) {\n // Already cached on the client; this read is purely for your records.\n // No need to pass it back in subsequent calls.\n console.log(r.value.bill_token)\n}\n```\n\n \n\n \n\n## next_action: branch on what to do next\n\n \n \n\n```ts\nswitch (result.next_action?.type) {\n case 'none':\n // Payment captured. Show a confirmation screen.\n break\n\n case 'redirect':\n window.location.href = result.next_action.authorization_url\n break\n\n case 'card_popup':\n openProviderPopup({\n provider: result.next_action.provider,\n clientSecret: result.next_action.client_secret,\n publicKey: result.next_action.public_key,\n })\n break\n\n case 'authorization':\n // Collect OTP / PIN / phone / birthday / address from the user, then submit\n promptForAuthorization(result.next_action.authorization_type, result.next_action.display_text)\n break\n\n case 'poll':\n pollUntilTerminal(result.order_id)\n break\n}\n```\n\n \n\n \n\n## submitAuthorization\n\n \n\nWhen the customer completes an OTP / PIN / etc., POST it back through the SDK. The response is the same `CheckoutResult` shape, with an updated `next_action`.\n\n \n \n\n```ts\nconst r = await client.checkout.submitAuthorization({\n order_id: 'ord_xxx',\n authorization_type: 'otp',\n authorization_value: '123456',\n})\n\nif (!r.ok) {\n console.error(r.error.code, r.error.message)\n return\n}\n\nif (r.value.next_action?.type === 'poll') {\n await pollUntilTerminal(r.value.order_id)\n}\n```\n\n \n\n \n\n## pollPaymentStatus\n\n \n \n\n```ts\nasync function pollUntilTerminal(orderId: string, intervalMs = 2000, maxAttempts = 30) {\n for (let i = 0; i < maxAttempts; i++) {\n const r = await client.checkout.pollPaymentStatus(orderId)\n if (!r.ok) return r\n\n const status = r.value.status\n if (status === 'success' || status === 'failed') {\n return r\n }\n\n await new Promise((resolve) => setTimeout(resolve, intervalMs))\n }\n}\n```\n\n \n\n \n\n## Attach a customer to a guest order\n\n \n \n\n```ts\n// After a guest checkout, attach customer info to the order (uses bill_token automatically)\nconst r = await client.checkout.updateOrderCustomer('ord_xxx', {\n name: 'Jane Doe',\n email: 'jane@example.com',\n phone: '+233244000000',\n save_details: false,\n})\n```\n\n \n\n \n\n## Cross-currency checkout\n\n \n\nSet `pay_currency` on the request and the SDK locks an FX quote for you behind the scenes; the `fx` field on the response shows the locked rate.\n\n \n \n\n```ts\nconst r = await client.checkout.process({\n cart_id: cart.id,\n customer: { /* ... */ },\n order_type: 'pickup',\n payment_method: 'card',\n address_info: {},\n pay_currency: 'USD',\n})\n\nif (r.ok && r.value.fx) {\n console.log(r.value.fx.base_amount, '\u2192', r.value.fx.pay_amount)\n console.log(r.value.fx.rate, r.value.fx.quote_id)\n}\n```\n\n \n\n \n\n## CheckoutFormData (request body)\n\n \n \n\n| Field | Type | Notes |\n| --- | --- | --- |\n| `cart_id` | `string` | Required. |\n| `customer` | `CheckoutCustomerInfo` | Required. `name, email, phone, save_details`. |\n| `order_type` | `'delivery' \\| 'pickup' \\| 'dine-in' \\| 'walk-in'` | Required. |\n| `payment_method` | `'mobile_money' \\| 'card'` | Required. |\n| `address_info` | `CheckoutAddressInfo` | Required (can be empty for pickup). |\n| `location_id` | `string` | Multi-location businesses. |\n| `mobile_money_details` | `MobileMoneyDetails` | Required when `payment_method = 'mobile_money'`. |\n| `special_instructions` | `string` | Free-form note for the order. |\n| `idempotency_key` | `string` | Auto-generated if omitted. |\n| `pay_currency` | `CurrencyCode` | Triggers FX quoting if different from cart currency. |\n| `fx_quote_id` | `string` | Pre-locked quote (otherwise the SDK locks one). |\n| `metadata` | `Record<string, unknown>` | Round-tripped to webhooks. |\n\n \n\n \n\n## Method reference\n\n \n \n\n| Method | Returns |\n| --- | --- |\n| `process(data)` | `Result<CheckoutResult>` |\n| `submitAuthorization(input)` | `Result<CheckoutResult>` |\n| `pollPaymentStatus(orderId)` | `Result<PaymentStatusResponse>` |\n| `updateOrderCustomer(orderId, customer)` | `Result<Order>` |\n| `verifyPayment(orderId)` | `Result<Order>` |\n\n \n\n \n\n## Related\n\n \n \n- [**Cart**](/docs/sdk/cart)\n The `cart_id` input comes from here\n\n \n- [**Orders**](/docs/sdk/orders)\n Read the order created by checkout.process\n\n \n- [**FX**](/docs/sdk/fx)\n Rates and locked quotes for cross-currency pay\n\n \n- [**Error handling**](/docs/sdk/errors)\n PAYMENT_FAILED, AUTH_INCOMPLETE, recovery flows\n"
83
+ "body": "`client.purchaseIntents` is the checkout authority. Minting creates a durable\nPurchaseIntent and immutable terms; it does **not** create an Order. Confirmation\ncreates the Order only after the server revalidates the accepted terms, source,\ninventory, funding allocation, and opaque payment option.\n\n## Mint Cart terms\n\n```ts\n MOBILE_MONEY_TENDER_AUTHORITY_KIND,\n ORDER_TYPE,\n PURCHASE_INTENT_PAYMENT_METHOD,\n PURCHASE_INTENT_MOBILE_MONEY_NETWORK,\n PURCHASE_INTENT_SOURCE_KIND,\n} from '@cimplify/sdk'\n\nconst minted = await client.purchaseIntents.mint({\n client_intent_key: crypto.randomUUID(),\n source: {\n kind: PURCHASE_INTENT_SOURCE_KIND.CART,\n cart_id: cart.id,\n },\n checkout: {\n customer: {\n name: 'Jane Doe',\n email: 'jane@example.com',\n phone: '+233244000000',\n save_details: false,\n },\n order_type: ORDER_TYPE.PICKUP,\n address_info: { pickup_time: '2026-08-23T15:00:00Z' },\n tender_preference: {\n method_kind: PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY,\n authority: {\n authority_kind: MOBILE_MONEY_TENDER_AUTHORITY_KIND.TRANSIENT,\n phone_number: '+233244000000',\n network: PURCHASE_INTENT_MOBILE_MONEY_NETWORK.MTN,\n },\n },\n },\n})\n\nif (!minted.ok) throw minted.error\nif (!minted.value.current_terms) throw new Error('Checkout terms are not prepared')\n```\n\nThe server derives seller and owner authority from the authenticated client. Do not\nsend a business, account, staff-session, or hosted-session owner in the body.\n\nFor a saved Mobile Money authority, send only the opaque ID:\n\n```ts\nconst tenderPreference = {\n method_kind: PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY,\n authority: {\n authority_kind: MOBILE_MONEY_TENDER_AUTHORITY_KIND.SAVED_REFERENCE,\n stored_instrument_id: savedMobileMoney.id,\n },\n} as const\n```\n\nThe server independently verifies ownership and derives its network. Never pair a\nsaved reference with a phone number.\n\n## Review one exact option\n\n```ts\n\nconst terms = minted.value.current_terms\nconst option = selectPurchaseIntentPaymentOption(terms, {\n method_kind: PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY,\n})\n\nif (!option) throw new Error('The selected payment method is unavailable')\n\nrenderPaymentReview({\n commercePrincipal: option.principal_amount,\n collectionFee: option.fee_amount,\n customerDebit: option.customer_debit_amount,\n currency: option.currency,\n})\n```\n\nThe exact equations are:\n\n```text\nstore_credit_consumed + voucher_credit_consumed + rail_amount = due_now\nprincipal_amount + fee_amount = customer_debit_amount\n```\n\nFunding allocations belong to the accepted terms. Payment options collect only the\nresidual principal and their own provider/offline fee. Do not display one top-level\npayment fee: different options may have different fees.\n\n## Confirm reviewed terms\n\n```ts\n PURCHASE_INTENT_CONFIRM_STATUS,\n createPurchaseIntentConfirmation,\n} from '@cimplify/sdk'\n\nconst confirmation = createPurchaseIntentConfirmation(\n terms,\n option,\n crypto.randomUUID(),\n)\nconst confirmed = await client.purchaseIntents.confirm(\n minted.value.id,\n confirmation,\n)\nif (!confirmed.ok) throw confirmed.error\n\nswitch (confirmed.value.status) {\n case PURCHASE_INTENT_CONFIRM_STATUS.ORDER_CREATED:\n showOrder(confirmed.value.order_id, confirmed.value.order_number)\n break\n case PURCHASE_INTENT_CONFIRM_STATUS.TERMS_CHANGED:\n showTermsReview(confirmed.value.replacement, confirmed.value.deltas)\n break\n case PURCHASE_INTENT_CONFIRM_STATUS.SELECTION_UNAVAILABLE:\n showUnavailableLines(confirmed.value.lines)\n break\n case PURCHASE_INTENT_CONFIRM_STATUS.PAYMENT_FAILED:\n showDeclinedPayment()\n break\n default:\n handleProviderOrRecoveryState(confirmed.value)\n}\n```\n\n`createPurchaseIntentConfirmation` binds the current intent revision, terms version,\ndue-now value, currency, selected option ID, and its exact\n`customer_debit_amount`. A true zero-rail purchase is the only case that can confirm\nwithout an option.\n\n## Resolve provider actions and replay\n\n`resolve` drives the canonical confirm/action/poll loop while keeping one durable\nattempt authority:\n\n```ts\n CHECKOUT_NEXT_ACTION,\n PAYMENT_AUTHORIZATION_OUTCOME_STATUS,\n PURCHASE_INTENT_ACTION_DECISION,\n PURCHASE_INTENT_CONFIRM_STATUS,\n} from '@cimplify/sdk'\n\nconst resolution = await client.purchaseIntents.resolve(minted.value.id, {\n confirmation,\n onActionRequired: async (action) => {\n if (action.status === PURCHASE_INTENT_CONFIRM_STATUS.REDIRECT_REQUIRED) {\n window.location.assign(action.authorization_url)\n return PURCHASE_INTENT_ACTION_DECISION.STOP\n }\n\n if (action.status === PURCHASE_INTENT_CONFIRM_STATUS.CARD_POPUP_REQUIRED) {\n const outcome = await client.checkout.authorizeCardPopup({\n type: CHECKOUT_NEXT_ACTION.CARD_POPUP,\n provider: action.provider,\n client_secret: action.client_secret,\n public_key: action.public_key,\n provider_account_id: action.provider_account_id ?? undefined,\n })\n return outcome.status === PAYMENT_AUTHORIZATION_OUTCOME_STATUS.SUBMITTED\n ? PURCHASE_INTENT_ACTION_DECISION.CONTINUE\n : PURCHASE_INTENT_ACTION_DECISION.STOP\n }\n\n const authorization = await collectAuthorization(action.authorization_type)\n return {\n kind: PURCHASE_INTENT_ACTION_DECISION.SUBMIT,\n request: { authorization },\n }\n },\n})\n```\n\nKeep the same confirmation idempotency key after an ambiguous response. A definitive\ndecline or an explicitly accepted replacement terms version starts a new attempt key.\nPersist only opaque intent, attempt, terms, option, and idempotency authorities for\nbrowser recovery\u2014never customer contact, address, voucher, note, or raw tender data,\nand never a hash of low-entropy PII.\n\n## Hosted checkout\n\nHosted PurchaseIntents belong to the CheckoutSession, not the storefront API session:\n\n```ts\nconst hosted = client.purchaseIntents.forHostedSession(sessionId)\nconst prepared = await hosted.prepare({\n expected_intent_revision: 0,\n idempotency_key: crypto.randomUUID(),\n checkout,\n})\n\nif (!prepared.ok || !prepared.value.current_terms) {\n throw prepared.ok ? new Error('Terms unavailable') : prepared.error\n}\n\nconst result = await hosted.resolve(prepared.value.id, {\n confirmation: createPurchaseIntentConfirmation(\n prepared.value.current_terms,\n selectPurchaseIntentPaymentOption(prepared.value.current_terms, tender) ?? null,\n crypto.randomUUID(),\n ),\n})\n```\n\nUse the hosted service for prepare, confirm, replay, and action submission. An intent\nID is the durable resource ID, but it does not replace the hosted session's owner\nauthority.\n\n## Compatibility adapter\n\n`client.checkout.process()` remains a deprecated SDK adapter over purchase-intent\nroutes for one migration window. New integrations should use\n`client.purchaseIntents` so terms review, per-option fees, attempt replay, and hosted\nownership remain explicit. The backend `/api/v1/checkout` endpoint no longer exists,\nand new checkout responses do not issue legacy Order bill tokens.\n\nThe deprecated `client.checkout.submitAuthorization()` method is fail-closed. It\ncan submit an action only when the same in-memory `CheckoutService` instance has\njust received the matching `payment_id`, `intent_id`, and `attempt_id` from\n`process()`. The SDK sends the authorization to the owner-fenced purchase-intent\nattempt action route; it never falls back to the legacy payment-id authorization\nmutation. After a reload, use the durable purchase-intent replay/action API instead.\n\n- [**Checkout Elements**](/docs/checkout/elements)\n Use the hosted UI and its `reviewing_terms` state.\n\n- [**Orders**](/docs/sdk/orders)\n Read the committed Order after `order_created`.\n"
84
84
  },
85
85
  {
86
86
  "name": "orders",
87
87
  "title": "Orders",
88
88
  "description": "Order shape and status flow",
89
89
  "source_url": "https://cimplify.dev/docs/sdk/orders",
90
- "body": "`client.orders.list()` returns different results depending on how the\nclient was constructed:\n\n- **Guest client** (`getServerClient()` with no `accessToken`, or the\n browser `cimplify` client with no signed-in shopper): returns nothing\n by default; the API has no customer to scope to. `client.orders.get()`\n still works on the same browser session that placed the order via the\n cached `bill_token`.\n- **Authenticated client** (`getAuthenticatedServerClient()` from the\n templates, or `getServerClient({ accessToken })` from a custom integration):\n returns *that customer's* orders at *this merchant*.\n\nSee [Sign in with Cimplify \u2192 Personalized server-side reads](/docs/sdk/auth#personalized-server-side-reads)\nfor the full setup.\n\n## Render orders for the signed-in shopper\n\n```tsx title=\"app/account/orders/page.tsx\"\n\nexport const revalidate = 0; // personalized; do not ISR-cache\n\nexport default async function OrdersPage() {\n const client = await getAuthenticatedServerClient();\n const r = await client.orders.list({ limit: 20 });\n if (!r.ok) throw new Error(r.error.message);\n\n if (r.value.length === 0) {\n return <p>No orders yet.</p>;\n }\n return (\n <ul>\n {r.value.map((o) => (\n <li key={o.id}>#{o.order_number} \xB7 {o.status} \xB7 {o.total_price}</li>\n ))}\n </ul>\n );\n}\n```\n\nIf `cimplify_access` is missing (signed-out shopper), `client.orders.list()`\nreturns the empty guest view. Branch on `getSession()` from `lib/auth.ts`\nif you want to redirect to sign-in instead.\n\n## List orders\n\n \n \n\n```ts\nconst r = await client.orders.list({ limit: 20 })\nif (!r.ok) {\n console.error(r.error.code, r.error.message)\n return\n}\n\nconsole.log(r.value.length)\nfor (const order of r.value) {\n console.log(order.id, order.order_number, order.status)\n}\n```\n\n \n\n \n\n## Filter by status\n\n \n \n\n```ts\nconst pending = await client.orders.list({ status: 'pending' })\nconst completed = await client.orders.list({ status: 'completed', limit: 50 })\n\n// Convenience wrappers\nconst recent = await client.orders.getRecent(5) // last 5\nconst cancelled = await client.orders.getByStatus('cancelled')\n```\n\n \n\n \n\n## Get a single order\n\n \n\nFor guest orders the SDK appends the cached `bill_token` automatically; the lookup works in the same browser session that placed the order, with no auth.\n\n \n \n\n```ts\n\nconst r = await client.orders.get('ord_xxx')\nif (!r.ok) return\n\nconst order = r.value\nconsole.log(order.status)\nconsole.log(order.items.length)\nconsole.log(order.total_price) // Money string\nconsole.log(formatPrice(parsePrice(order.total_price), order.currency))\n```\n\n \n\n \n\n## Cancel an order\n\n \n \n\n```ts\nconst cancelled = await client.orders.cancel('ord_xxx', 'changed_mind')\nif (!cancelled.ok) {\n // Codes you'll see: ORDER_NOT_CANCELLABLE, ORDER_ALREADY_FULFILLED\n console.error(cancelled.error.code, cancelled.error.message)\n}\n\n// Idempotent retry: same key, same outcome on the server\nawait client.orders.cancel('ord_xxx', 'changed_mind', {\n idempotencyKey: 'cancel-ord_xxx-once',\n})\n```\n\n \n\n \n\n## Order status values\n\n \n \n\n| Status | Meaning |\n| --- | --- |\n| `pending` | Created, awaiting payment confirmation |\n| `confirmed` | Accepted by the business |\n| `preparing` | Being assembled or fulfilled |\n| `ready` | Ready for pickup or delivery dispatch |\n| `completed` | Fulfilled; terminal state |\n| `cancelled` | Cancelled; terminal state |\n| `refunded` | Payment refunded |\n\n \n\n \n\n## Poll until terminal\n\n \n \n\n```ts\nasync function pollUntilTerminal(orderId: string, intervalMs = 5000) {\n for (;;) {\n const r = await client.orders.get(orderId)\n if (!r.ok) return r\n\n const status = r.value.status\n if (status === 'completed' || status === 'cancelled' || status === 'refunded') {\n return r\n }\n\n await new Promise((resolve) => setTimeout(resolve, intervalMs))\n }\n}\n```\n\n \n\n \n\n## Method reference\n\n \n \n\n| Method | Returns |\n| --- | --- |\n| `list({ status?, limit?, offset? })` | `Result<Order[]>` |\n| `get(orderId)` | `Result<Order>` |\n| `cancel(orderId, reason?, opts?)` | `Result<Order>` |\n| `getRecent(limit?)` | `Result<Order[]>` |\n| `getByStatus(status)` | `Result<Order[]>` |\n\n \n\n \n\n## Related\n\n \n \n- [**Checkout**](/docs/sdk/checkout)\n Create the orders that this page lists\n\n \n- [**Subscriptions**](/docs/sdk/subscriptions)\n For recurring orders, see the subscription surface\n\n \n- [**Scheduling**](/docs/sdk/scheduling)\n Reschedule or cancel a booking line item\n\n \n- [**Error handling**](/docs/sdk/errors)\n Cancellation guards and retryable errors\n"
90
+ "body": "`client.orders.list()` returns different results depending on how the\nclient was constructed:\n\n- **Guest client** (`getServerClient()` with no `accessToken`, or the\n browser `cimplify` client with no signed-in shopper): returns nothing\n by default; the API has no customer to scope to. `client.orders.get()`\n may still use a previously cached historical Order token for its original\n pre-convergence order. New purchase-intent checkout does not issue one.\n- **Authenticated client** (`getAuthenticatedServerClient()` from the\n templates, or `getServerClient({ accessToken })` from a custom integration):\n returns *that customer's* orders at *this merchant*.\n\nSee [Sign in with Cimplify \u2192 Personalized server-side reads](/docs/sdk/auth#personalized-server-side-reads)\nfor the full setup.\n\n## Render orders for the signed-in shopper\n\n```tsx title=\"app/account/orders/page.tsx\"\n\nexport const revalidate = 0; // personalized; do not ISR-cache\n\nexport default async function OrdersPage() {\n const client = await getAuthenticatedServerClient();\n const r = await client.orders.list({ limit: 20 });\n if (!r.ok) throw new Error(r.error.message);\n\n if (r.value.length === 0) {\n return <p>No orders yet.</p>;\n }\n return (\n <ul>\n {r.value.map((o) => (\n <li key={o.id}>#{o.order_number} \xB7 {o.status} \xB7 {o.total_price}</li>\n ))}\n </ul>\n );\n}\n```\n\nIf `cimplify_access` is missing (signed-out shopper), `client.orders.list()`\nreturns the empty guest view. Branch on `getSession()` from `lib/auth.ts`\nif you want to redirect to sign-in instead.\n\n## List orders\n\n \n \n\n```ts\nconst r = await client.orders.list({ limit: 20 })\nif (!r.ok) {\n console.error(r.error.code, r.error.message)\n return\n}\n\nconsole.log(r.value.length)\nfor (const order of r.value) {\n console.log(order.id, order.order_number, order.status)\n}\n```\n\n \n\n \n\n## Filter by status\n\n \n \n\n```ts\nconst pending = await client.orders.list({ status: 'pending' })\nconst completed = await client.orders.list({ status: 'completed', limit: 50 })\n\n// Convenience wrappers\nconst recent = await client.orders.getRecent(5) // last 5\nconst cancelled = await client.orders.getByStatus('cancelled')\n```\n\n \n\n \n\n## Get a single order\n\n \n\nAuthenticated and recognised shoppers read the Order created by a confirmed purchase intent through their existing owner/session authority. The SDK still appends a cached historical Order token when one already exists, solely so old orders remain readable during the compatibility window.\n\n \n \n\n```ts\n\nconst r = await client.orders.get('ord_xxx')\nif (!r.ok) return\n\nconst order = r.value\nconsole.log(order.status)\nconsole.log(order.items.length)\nconsole.log(order.total_price) // Money string\nconsole.log(formatPrice(parsePrice(order.total_price), order.currency))\n```\n\n \n\n \n\n## Cancel an order\n\n \n \n\n```ts\nconst cancelled = await client.orders.cancel('ord_xxx', 'changed_mind')\nif (!cancelled.ok) {\n // Codes you'll see: ORDER_NOT_CANCELLABLE, ORDER_ALREADY_FULFILLED\n console.error(cancelled.error.code, cancelled.error.message)\n}\n\n// Idempotent retry: same key, same outcome on the server\nawait client.orders.cancel('ord_xxx', 'changed_mind', {\n idempotencyKey: 'cancel-ord_xxx-once',\n})\n```\n\n \n\n \n\n## Order status values\n\n \n \n\n| Status | Meaning |\n| --- | --- |\n| `pending` | Created, awaiting payment confirmation |\n| `confirmed` | Accepted by the business |\n| `preparing` | Being assembled or fulfilled |\n| `ready` | Ready for pickup or delivery dispatch |\n| `completed` | Fulfilled; terminal state |\n| `cancelled` | Cancelled; terminal state |\n| `refunded` | Payment refunded |\n\n \n\n \n\n## Poll until terminal\n\n \n \n\n```ts\nasync function pollUntilTerminal(orderId: string, intervalMs = 5000) {\n for (;;) {\n const r = await client.orders.get(orderId)\n if (!r.ok) return r\n\n const status = r.value.status\n if (status === 'completed' || status === 'cancelled' || status === 'refunded') {\n return r\n }\n\n await new Promise((resolve) => setTimeout(resolve, intervalMs))\n }\n}\n```\n\n \n\n \n\n## Method reference\n\n \n \n\n| Method | Returns |\n| --- | --- |\n| `list({ status?, limit?, offset? })` | `Result<Order[]>` |\n| `get(orderId)` | `Result<Order>` |\n| `cancel(orderId, reason?, opts?)` | `Result<Order>` |\n| `getRecent(limit?)` | `Result<Order[]>` |\n| `getByStatus(status)` | `Result<Order[]>` |\n\n \n\n \n\n## Related\n\n \n \n- [**Checkout**](/docs/sdk/checkout)\n Create the orders that this page lists\n\n \n- [**Subscriptions**](/docs/sdk/subscriptions)\n For recurring orders, see the subscription surface\n\n \n- [**Scheduling**](/docs/sdk/scheduling)\n Reschedule or cancel a booking line item\n\n \n- [**Error handling**](/docs/sdk/errors)\n Cancellation guards and retryable errors\n"
91
91
  },
92
92
  {
93
93
  "name": "subscriptions",
@@ -171,7 +171,7 @@ var TOPICS = [
171
171
  "title": "Agent prompts",
172
172
  "description": "Copy-paste prompts for common Cimplify workflows",
173
173
  "source_url": "https://cimplify.dev/docs/agent-prompts",
174
- "body": 'These prompts are deliberately terse. Each one names the canonical doc the agent should read first, the exact commands or [MCP tools](/docs/mcp) to call, and the exit condition. Replace `<angle-bracket>` placeholders before running.\n\nEvery prompt assumes the agent has either:\n\n- the [Cimplify CLI](/docs/cli) installed and `cimplify login` complete, **or**\n- an MCP connection to `https://api.cimplify.io/mcp` ([setup](/docs/mcp#connect))\n\n## Ship a new storefront end-to-end\n\n```text title="Scaffold \u2192 deploy \u2192 custom domain"\nSet up a Cimplify <retail> storefront called <my-store> and deploy it to <shop.example.com>.\n\nSource of truth: https://cimplify.dev/docs/tldr\n- Use the MCP tools at api.cimplify.io/mcp when available; otherwise shell `cimplify <cmd> --json`.\n- After every command, echo the JSON envelope.\n- Stop on the first non-zero exit code and name it from https://cimplify.dev/docs/cli#exit-codes.\n- Poll deployment status with cimplify_get_deployment_status (or `cimplify status --json`); never `sleep`.\n- Idempotent: re-running any step is safe.\n```\n\n## Rebrand an existing storefront\n\n```text title="Apply a new brand to a scaffolded template"\nRebrand the storefront in <./my-store> to match these tokens:\n name: <Acme Coffee>\n primary: <#0F172A>\n accent: <#F59E0B>\n fontDisplay: <"Playfair Display">\n fontBody: <"Inter">\n\nRules (https://cimplify.dev/docs/templates/brand):\n- Single source of truth is `lib/brand.ts`. Update it first.\n- Mirror color tokens into `app/globals.css` `@theme` block. Do not hard-code colors elsewhere.\n- Do not edit ejected SDK components; they pick up tokens automatically.\n- Run `bun run check:brand` after edits; fix any schema errors it reports.\n- Verify by opening `http://localhost:3000` (start `bun dev` if not running).\n- Commit with message `brand: <name>`. Do not deploy.\n```\n\n## Add a homepage section\n\n```text title="New Server Component section, cache-tagged"\nAdd a `<Stories>` section to the homepage of the storefront in <./my-store>.\n\nPattern (mirrors the Server Component sections under `app/_sections/` in the scaffolded template):\n- Create `app/_sections/stories.tsx` as an async Server Component. Pass `cacheOptions: { revalidate: 3600, tags: [tags.collections()] }` to the SDK read (from `@cimplify/sdk/server`). Do NOT use `\'use cache\'` / `cacheTag` / `cacheLife`. Cimplify storefronts run on CF Workers where Cache Components is broken; use the ISR Previous Model.\n- Source data from `client.catalogue.getCollection({ slug: "stories" })`.\n- Render with the existing `<SectionHeader>` and `<ProductCard>` SDK components (do not eject).\n- Insert into `app/page.tsx` between the hero and the featured collection.\n- Run `bun run check`. It must pass typecheck, lint, brand, cart-flow, contract.\n- Do not modify `lib/brand.ts` or any file under `components/ui/`.\n```\n\n## Migrate to a new SDK version\n\n```text title="SDK upgrade with breaking-change scan"\nUpgrade the storefront in <./my-store> from `@cimplify/sdk@<0.44.x>` to `@cimplify/sdk@<latest>`.\n\nProcess:\n- Read the release notes for the target range (`npm view @cimplify/sdk versions --json` to list, then `npm view @cimplify/sdk@<version>` per release).\n- Bump the pin in `package.json`, run `bun install`.\n- For each breaking change called out in the changelog, grep the project for the old symbol and apply the documented replacement.\n- Run `bun run check`. If `check:contract` fails, the SDK \u2194 mock contract drifted; stop and report.\n- Do not run `cimplify deploy`. End by printing a summary of every file you changed and every breaking change you applied.\n```\n\n## Add a custom checkout payment method\n\n```text title="Wire an additional payment option"\nAdd <mobile_money> as a checkout payment option in the storefront at <./my-store>.\n\nReference: https://cimplify.dev/docs/api-reference/checkout (flat ProcessArgs body: top-level fields, not nested).\n- The body shape is the contract; never wrap fields.\n- Eject the existing `<PaymentMethodPicker>` component with `cimplify add payment-method-picker`.\n- Add the option in the ejected picker, wiring the provider-specific body (e.g. `mobile_money_details: { phone_number, provider }`).\n- Validate the body against the typed `ProcessArgs` from `@cimplify/sdk`.\n- Run `bun run check:cart`; the add\u2192checkout flow must still pass.\n```\n\n## Provision a CI deploy key\n\n```text title="One-time setup for headless deploys"\nCreate a CI-scoped API key for the Cimplify project linked at <./my-store>, and write the GitHub Actions snippet that uses it.\n\nSteps:\n- Confirm `.cimplify/project.json` exists; if not, fail with NOT_LINKED (exit 4).\n- Print the dashboard URL the human needs to visit to create the key (https://app.cimplify.io/settings/developer).\n- Once the user provides `dk_live_\u2026`, store it as a repo secret named `CIMPLIFY_API_KEY` (instruct, do not perform).\n- Write `.github/workflows/deploy.yml` that runs on push to main: install CLI via the curl one-liner, `cimplify deploy --prod --api-key "$CIMPLIFY_API_KEY" --yes --json`.\n- Print the exit-code legend from https://cimplify.dev/docs/cli#exit-codes so the workflow can map failures.\n```\n\n## Diagnose a deploy that didn\'t go live\n\n```text title="Triage a failed or stuck deployment"\nThe latest deploy of the project at <./my-store> isn\'t live. Find out why.\n\nTriage path:\n- `cimplify status --json`: what\'s the latest deployment_id and status?\n- If status is `failed`, `cimplify logs --deployment <id> --json | tail -200`. Quote the first error line you see.\n- If status is `queued` or `building` for >5 minutes, the build is stuck; try `cimplify rollback <previous-deploy-id>`.\n- If status is `superseded` (exit 2), a newer push raced it; usually fine, so confirm with `cimplify status` again.\n- If domains misroute, `cimplify domains ls --json`: confirm the verified+attached domain.\n- Report: deployment_id, status, the failing log line (if any), and the recommended next action. Do not auto-rollback without confirming.\n```\n\n## Add a hero image and reference it in the homepage\n\n```text title="Upload brand assets \u2192 use them in source"\nAdd the image at <./Downloads/hero.jpg> as the homepage hero for the storefront in <./my-store>.\n\nReference: https://cimplify.dev/docs/cli/assets\n- `cp <./Downloads/hero.jpg> public/hero/main.jpg`\n- `cimplify assets upload public/hero/ --folder hero --json`: captures the manifest entry for `hero/main.jpg`.\n- Edit `app/page.tsx`: replace the hero `<Image>` `src` with `assetUrl("hero/main.jpg")` from `@cimplify/sdk`.\n- Do NOT touch existing `<Image>` calls that point at Cloudinary or other external hosts; the loader passes them through unchanged.\n- Run `bun run check`. Open `http://localhost:3000`; verify the hero image renders.\n- Commit `cimplify-assets.json` along with the source change so the manifest is reviewable.\n```\n\n## Audit caching and asset delivery\n\n```text title="Find caching and asset regressions on a live storefront"\nAudit the live storefront at <https://my-store.mycimplify.com> for caching and asset-delivery regressions.\n\nSources of truth:\n- https://cimplify.dev/docs/sdk/optimization (page + asset caching)\n- https://cimplify.dev/docs/templates/seo-and-resource-hints (responsive images)\n\n- Page cache: curl /, /shop, and a PDP 2\u20133\xD7 each; `X-Cimplify-Edge-Cache` must warm to HIT and `Cache-Control` must carry `s-maxage`. A BYPASS or missing `s-maxage` means the page lost its `revalidate` or carries a Cookie.\n- Asset cache: pull a `/_next/static/*` chunk; it must be `public, max-age=31536000, immutable`.\n- Images: flag raw `<img>` from a third-party CDN, and Cloudinary URLs with no `/upload/<transform>/` segment (full-resolution originals).\n- Report a table (route/asset, observed header, expected, severity). Do not change source unless asked.\n```\n\n## Reset a sandbox storefront to a clean state\n\n```text title="Wipe and re-seed for repeatable demos"\nReset the local mock state for the storefront in <./my-store>.\n\n- Stop any running `bun dev` process.\n- `cimplify mock reset` (clears the in-process mock backing store).\n- `cimplify mock seed <retail>` (re-seeds with the chosen industry fixture).\n- `bun dev` to restart both servers.\n- Verify: `curl localhost:8787/v1/catalogue/products | jq \'.data | length\'` returns the expected seed count (~24 for retail).\n- Do not touch the linked cloud project; this is local-only.\n```\n\n## How these are built\n\nEvery prompt above is structured the same way so you can adapt them:\n\n1. **Goal**: one sentence, with `<angle-bracket>` placeholders for the moving parts.\n2. **Source of truth**: the canonical doc URL the agent reads first.\n3. **Rules**: operational guardrails for which tools to call, what to echo, and when to stop.\n4. **Exit condition**: what counts as success, what counts as a halt.\n\nIf you build a prompt that should live here, open a PR against `content/docs/agent-prompts.mdx`. Keep them under ~12 lines; if a workflow needs more, it belongs in a dedicated doc page and the prompt should link to it.\n'
174
+ "body": 'These prompts are deliberately terse. Each one names the canonical doc the agent should read first, the exact commands or [MCP tools](/docs/mcp) to call, and the exit condition. Replace `<angle-bracket>` placeholders before running.\n\nEvery prompt assumes the agent has either:\n\n- the [Cimplify CLI](/docs/cli) installed and `cimplify login` complete, **or**\n- an MCP connection to `https://api.cimplify.io/mcp` ([setup](/docs/mcp#connect))\n\n## Ship a new storefront end-to-end\n\n```text title="Scaffold \u2192 deploy \u2192 custom domain"\nSet up a Cimplify <retail> storefront called <my-store> and deploy it to <shop.example.com>.\n\nSource of truth: https://cimplify.dev/docs/tldr\n- Use the MCP tools at api.cimplify.io/mcp when available; otherwise shell `cimplify <cmd> --json`.\n- After every command, echo the JSON envelope.\n- Stop on the first non-zero exit code and name it from https://cimplify.dev/docs/cli#exit-codes.\n- Poll deployment status with cimplify_get_deployment_status (or `cimplify status --json`); never `sleep`.\n- Idempotent: re-running any step is safe.\n```\n\n## Rebrand an existing storefront\n\n```text title="Apply a new brand to a scaffolded template"\nRebrand the storefront in <./my-store> to match these tokens:\n name: <Acme Coffee>\n primary: <#0F172A>\n accent: <#F59E0B>\n fontDisplay: <"Playfair Display">\n fontBody: <"Inter">\n\nRules (https://cimplify.dev/docs/templates/brand):\n- Single source of truth is `lib/brand.ts`. Update it first.\n- Mirror color tokens into `app/globals.css` `@theme` block. Do not hard-code colors elsewhere.\n- Do not edit ejected SDK components; they pick up tokens automatically.\n- Run `bun run check:brand` after edits; fix any schema errors it reports.\n- Verify by opening `http://localhost:3000` (start `bun dev` if not running).\n- Commit with message `brand: <name>`. Do not deploy.\n```\n\n## Add a homepage section\n\n```text title="New Server Component section, cache-tagged"\nAdd a `<Stories>` section to the homepage of the storefront in <./my-store>.\n\nPattern (mirrors the Server Component sections under `app/_sections/` in the scaffolded template):\n- Create `app/_sections/stories.tsx` as an async Server Component. Pass `cacheOptions: { revalidate: 3600, tags: [tags.collections()] }` to the SDK read (from `@cimplify/sdk/server`). Do NOT use `\'use cache\'` / `cacheTag` / `cacheLife`. Cimplify storefronts run on CF Workers where Cache Components is broken; use the ISR Previous Model.\n- Source data from `client.catalogue.getCollection({ slug: "stories" })`.\n- Render with the existing `<SectionHeader>` and `<ProductCard>` SDK components (do not eject).\n- Insert into `app/page.tsx` between the hero and the featured collection.\n- Run `bun run check`. It must pass typecheck, lint, brand, cart-flow, contract.\n- Do not modify `lib/brand.ts` or any file under `components/ui/`.\n```\n\n## Migrate to a new SDK version\n\n```text title="SDK upgrade with breaking-change scan"\nUpgrade the storefront in <./my-store> from `@cimplify/sdk@<0.44.x>` to `@cimplify/sdk@<latest>`.\n\nProcess:\n- Read the release notes for the target range (`npm view @cimplify/sdk versions --json` to list, then `npm view @cimplify/sdk@<version>` per release).\n- Bump the pin in `package.json`, run `bun install`.\n- For each breaking change called out in the changelog, grep the project for the old symbol and apply the documented replacement.\n- Run `bun run check`. If `check:contract` fails, the SDK \u2194 mock contract drifted; stop and report.\n- Do not run `cimplify deploy`. End by printing a summary of every file you changed and every breaking change you applied.\n```\n\n## Add a custom checkout payment method\n\n```text title="Wire an additional payment option"\nAdd <mobile_money> as a checkout payment option in the storefront at <./my-store>.\n\nReference: https://cimplify.dev/docs/api-reference/checkout (purchase-intent mint, immutable terms review, then exact option confirmation).\n- Use the exported `PURCHASE_INTENT_*` constants and closed tender preference types.\n- Eject the existing `<PaymentMethodPicker>` component with `cimplify add payment-method-picker`.\n- Add the option in the ejected picker, preparing provider input into an opaque server-issued payment option.\n- Show `fee_amount` and `customer_debit_amount`, then confirm the reviewed option ID.\n- Validate mint and confirmation bodies against the purchase-intent schemas from `@cimplify/sdk/testing`.\n- Run `bun run check:cart`; the add\u2192checkout flow must still pass.\n```\n\n## Provision a CI deploy key\n\n```text title="One-time setup for headless deploys"\nCreate a CI-scoped API key for the Cimplify project linked at <./my-store>, and write the GitHub Actions snippet that uses it.\n\nSteps:\n- Confirm `.cimplify/project.json` exists; if not, fail with NOT_LINKED (exit 4).\n- Print the dashboard URL the human needs to visit to create the key (https://app.cimplify.io/settings/developer).\n- Once the user provides `dk_live_\u2026`, store it as a repo secret named `CIMPLIFY_API_KEY` (instruct, do not perform).\n- Write `.github/workflows/deploy.yml` that runs on push to main: install CLI via the curl one-liner, `cimplify deploy --prod --api-key "$CIMPLIFY_API_KEY" --yes --json`.\n- Print the exit-code legend from https://cimplify.dev/docs/cli#exit-codes so the workflow can map failures.\n```\n\n## Diagnose a deploy that didn\'t go live\n\n```text title="Triage a failed or stuck deployment"\nThe latest deploy of the project at <./my-store> isn\'t live. Find out why.\n\nTriage path:\n- `cimplify status --json`: what\'s the latest deployment_id and status?\n- If status is `failed`, `cimplify logs --deployment <id> --json | tail -200`. Quote the first error line you see.\n- If status is `queued` or `building` for >5 minutes, the build is stuck; try `cimplify rollback <previous-deploy-id>`.\n- If status is `superseded` (exit 2), a newer push raced it; usually fine, so confirm with `cimplify status` again.\n- If domains misroute, `cimplify domains ls --json`: confirm the verified+attached domain.\n- Report: deployment_id, status, the failing log line (if any), and the recommended next action. Do not auto-rollback without confirming.\n```\n\n## Add a hero image and reference it in the homepage\n\n```text title="Upload brand assets \u2192 use them in source"\nAdd the image at <./Downloads/hero.jpg> as the homepage hero for the storefront in <./my-store>.\n\nReference: https://cimplify.dev/docs/cli/assets\n- `cp <./Downloads/hero.jpg> public/hero/main.jpg`\n- `cimplify assets upload public/hero/ --folder hero --json`: captures the manifest entry for `hero/main.jpg`.\n- Edit `app/page.tsx`: replace the hero `<Image>` `src` with `assetUrl("hero/main.jpg")` from `@cimplify/sdk`.\n- Do NOT touch existing `<Image>` calls that point at Cloudinary or other external hosts; the loader passes them through unchanged.\n- Run `bun run check`. Open `http://localhost:3000`; verify the hero image renders.\n- Commit `cimplify-assets.json` along with the source change so the manifest is reviewable.\n```\n\n## Audit caching and asset delivery\n\n```text title="Find caching and asset regressions on a live storefront"\nAudit the live storefront at <https://my-store.mycimplify.com> for caching and asset-delivery regressions.\n\nSources of truth:\n- https://cimplify.dev/docs/sdk/optimization (page + asset caching)\n- https://cimplify.dev/docs/templates/seo-and-resource-hints (responsive images)\n\n- Page cache: curl /, /shop, and a PDP 2\u20133\xD7 each; `X-Cimplify-Edge-Cache` must warm to HIT and `Cache-Control` must carry `s-maxage`. A BYPASS or missing `s-maxage` means the page lost its `revalidate` or carries a Cookie.\n- Asset cache: pull a `/_next/static/*` chunk; it must be `public, max-age=31536000, immutable`.\n- Images: flag raw `<img>` from a third-party CDN, and Cloudinary URLs with no `/upload/<transform>/` segment (full-resolution originals).\n- Report a table (route/asset, observed header, expected, severity). Do not change source unless asked.\n```\n\n## Reset a sandbox storefront to a clean state\n\n```text title="Wipe and re-seed for repeatable demos"\nReset the local mock state for the storefront in <./my-store>.\n\n- Stop any running `bun dev` process.\n- `cimplify mock reset` (clears the in-process mock backing store).\n- `cimplify mock seed <retail>` (re-seeds with the chosen industry fixture).\n- `bun dev` to restart both servers.\n- Verify: `curl localhost:8787/v1/catalogue/products | jq \'.data | length\'` returns the expected seed count (~24 for retail).\n- Do not touch the linked cloud project; this is local-only.\n```\n\n## How these are built\n\nEvery prompt above is structured the same way so you can adapt them:\n\n1. **Goal**: one sentence, with `<angle-bracket>` placeholders for the moving parts.\n2. **Source of truth**: the canonical doc URL the agent reads first.\n3. **Rules**: operational guardrails for which tools to call, what to echo, and when to stop.\n4. **Exit condition**: what counts as success, what counts as a halt.\n\nIf you build a prompt that should live here, open a PR against `content/docs/agent-prompts.mdx`. Keep them under ~12 lines; if a workflow needs more, it belongs in a dedicated doc page and the prompt should link to it.\n'
175
175
  },
176
176
  {
177
177
  "name": "seeds",
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { parseEnvFile } from './chunk-RU53TQLZ.mjs';
2
+ import { parseEnvFile } from './chunk-I2UP7YTG.mjs';
3
3
  import { parseArgs, flagString, flagBool } from './chunk-5KYR6WJB.mjs';
4
- import { CliError, CLI_ERROR_CODE, isJsonMode, result, info, bold, dim, yellow, green, red } from './chunk-4O4G2CDE.mjs';
4
+ import { CliError, CLI_ERROR_CODE, isJsonMode, result, info, bold, dim, yellow, green, red } from './chunk-3QUK5BPY.mjs';
5
5
  import { promises } from 'fs';
6
6
  import path from 'path';
7
7
  import { createCimplifyClient } from '@cimplify/sdk';
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ export { run as default, extractMockSeed, gatherIntrospection, renderIntrospection } from './chunk-WAHYTXOF.mjs';
3
+ import './chunk-I2UP7YTG.mjs';
4
+ import './chunk-MGQD5MEC.mjs';
5
+ import './chunk-KN2YSKXZ.mjs';
6
+ import './chunk-5KYR6WJB.mjs';
7
+ import './chunk-MLE4MVYC.mjs';
8
+ import './chunk-3QUK5BPY.mjs';
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { gitDetectRoot, gitGetRemoteUrl, gitAddRemote } from './chunk-YIBOOKQQ.mjs';
2
+ import { gitDetectRoot, gitGetRemoteUrl, gitAddRemote } from './chunk-KN2YSKXZ.mjs';
3
3
  import { parseArgs } from './chunk-5KYR6WJB.mjs';
4
- import { ApiClient } from './chunk-TOQGLBWF.mjs';
5
- import { readAuth, writeProjectLink } from './chunk-6CHBU7O4.mjs';
6
- import { CliError, CLI_ERROR_CODE, success, info, dim, result } from './chunk-4O4G2CDE.mjs';
4
+ import { ApiClient } from './chunk-NYXA6X56.mjs';
5
+ import { readAuth, writeProjectLink } from './chunk-MLE4MVYC.mjs';
6
+ import { CliError, CLI_ERROR_CODE, success, info, dim, result } from './chunk-3QUK5BPY.mjs';
7
7
 
8
8
  // src/commands/link.ts
9
9
  function projectEndpoint(businessId, projectId) {
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { parseArgs, flagBool, flagString } from './chunk-5KYR6WJB.mjs';
3
- import { isJsonMode, result, info, CliError, CLI_ERROR_CODE, configureOutput, OUTPUT_MODE } from './chunk-4O4G2CDE.mjs';
3
+ import { isJsonMode, result, info, CliError, CLI_ERROR_CODE, configureOutput, OUTPUT_MODE } from './chunk-3QUK5BPY.mjs';
4
4
  import { promises } from 'fs';
5
5
  import path from 'path';
6
6
  import { parse } from '@babel/parser';
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { REGISTRY_INDEX } from './chunk-JOF7ESSA.mjs';
2
+ import { REGISTRY_INDEX } from './chunk-MTEMM6WI.mjs';
3
3
  import { parseArgs, flagBool } from './chunk-5KYR6WJB.mjs';
4
- import { CliError, CLI_ERROR_CODE, info, bold, dim, green, result } from './chunk-4O4G2CDE.mjs';
4
+ import { CliError, CLI_ERROR_CODE, info, bold, dim, green, result } from './chunk-3QUK5BPY.mjs';
5
5
 
6
6
  // src/commands/list.ts
7
7
  async function run(argv) {
@@ -1,26 +1,20 @@
1
1
  #!/usr/bin/env node
2
- import { generatePkcePair, openBrowser } from './chunk-IK6NQHTG.mjs';
2
+ import { generatePkcePair, openBrowser } from './chunk-DMLQBAGC.mjs';
3
3
  import { parseArgs, flagString, flagBool } from './chunk-5KYR6WJB.mjs';
4
- import { resolveBaseUrl, ApiClient } from './chunk-TOQGLBWF.mjs';
5
- import { writeAuth } from './chunk-6CHBU7O4.mjs';
6
- import { CliError, CLI_ERROR_CODE, success, result, isJsonMode, step, info, dim } from './chunk-4O4G2CDE.mjs';
4
+ import { resolveBaseUrl, ApiClient } from './chunk-NYXA6X56.mjs';
5
+ import { writeAuth } from './chunk-MLE4MVYC.mjs';
6
+ import { CliError, CLI_ERROR_CODE, success, result, isJsonMode, step, info, dim } from './chunk-3QUK5BPY.mjs';
7
7
  import os from 'os';
8
8
 
9
9
  var FLAG_API_KEY = "api-key";
10
10
  var FLAG_BASE_URL = "base-url";
11
11
  var FLAG_NO_BROWSER = "no-browser";
12
12
  var FLAG_SCOPE = "scope";
13
- var VALID_CLI_SCOPES = /* @__PURE__ */ new Set([
14
- "cli:read",
15
- "cli:write",
16
- "cli:deploy",
17
- "cli:admin"
18
- ]);
19
- var ENDPOINT_AUTH_ME = "/v1/auth/me";
13
+ var VALID_CLI_SCOPES = /* @__PURE__ */ new Set(["cli:read", "cli:write", "cli:deploy", "cli:admin"]);
14
+ var ENDPOINT_AUTH_ME = "/v1/auth/cli/me";
20
15
  var ENDPOINT_CLI_START = "/v1/auth/cli/start";
21
16
  var ENDPOINT_CLI_TOKEN = "/v1/auth/cli/token";
22
17
  var KEY_PREFIX_CAK = "cak_";
23
- var KEY_PREFIX_CSK = "csk_";
24
18
  var PRODUCT_NAME = "cimplify-cli";
25
19
  var POLL_INTERVAL_MS = 2e3;
26
20
  async function run(argv) {
@@ -48,10 +42,10 @@ function parseScopeFlag(raw) {
48
42
  return items;
49
43
  }
50
44
  async function loginWithKey(baseUrl, apiKey) {
51
- if (!apiKey.startsWith(KEY_PREFIX_CAK) && !apiKey.startsWith(KEY_PREFIX_CSK)) {
45
+ if (!apiKey.startsWith(KEY_PREFIX_CAK)) {
52
46
  throw new CliError(
53
47
  CLI_ERROR_CODE.INVALID_INPUT,
54
- `API key must start with "${KEY_PREFIX_CAK}" or "${KEY_PREFIX_CSK}".`
48
+ `CLI login requires a user-bound Personal API key starting with "${KEY_PREFIX_CAK}".`
55
49
  );
56
50
  }
57
51
  const client = ApiClient.withKey(apiKey, baseUrl);
@@ -78,7 +72,9 @@ async function loginWithBrowser(baseUrl, noBrowser, requestedScopes) {
78
72
  throw new CliError(
79
73
  CLI_ERROR_CODE.INTERACTIVE_REQUIRED,
80
74
  "browser login is not supported in --json mode",
81
- { remediation: "pass --api-key dk_\u2026 (create one in the dashboard or via `cimplify auth keys create`)" }
75
+ {
76
+ remediation: "pass --api-key cak_\u2026 (create one in the dashboard or via `cimplify auth keys create`)"
77
+ }
82
78
  );
83
79
  }
84
80
  const pkce = generatePkcePair();
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { clearAuth } from './chunk-6CHBU7O4.mjs';
3
- import { success, info, result } from './chunk-4O4G2CDE.mjs';
2
+ import { clearAuth } from './chunk-MLE4MVYC.mjs';
3
+ import { success, info, result } from './chunk-3QUK5BPY.mjs';
4
4
 
5
5
  // src/commands/logout.ts
6
6
  async function run(_argv) {