@whop/cli 0.0.6 → 0.2.0

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.
package/dist/index.js CHANGED
@@ -8,9 +8,12 @@ import {
8
8
  Profile,
9
9
  PromptCancelledError,
10
10
  apiBaseUrl,
11
+ buildTarget,
11
12
  chooseAuthMethod,
13
+ configDir,
12
14
  createWhopFetch,
13
15
  deriveProfileName,
16
+ detectChannel,
14
17
  filterSpecByTag,
15
18
  getActiveProfile,
16
19
  getSecret,
@@ -22,17 +25,17 @@ import {
22
25
  readConfig,
23
26
  removeAllProfiles,
24
27
  removeProfile,
25
- resolveActiveCompanyId,
28
+ resolveActiveAccountId,
26
29
  selectProfile,
30
+ setActiveProfileAccount,
27
31
  startSpinner,
28
32
  switchProfile,
29
33
  upsertProfile,
30
34
  validateApiKey
31
- } from "./chunk-Z7WDX64Z.js";
35
+ } from "./chunk-2Y4EKBOD.js";
32
36
  import {
33
37
  external_exports
34
- } from "./chunk-CXNQ6UGC.js";
35
- import "./chunk-MELVTXNG.js";
38
+ } from "./chunk-KFCNNWPI.js";
36
39
 
37
40
  // src/api/groups.json
38
41
  var groups_default = [
@@ -92,6 +95,14 @@ var groups_default = [
92
95
  "referrals",
93
96
  "Referrals"
94
97
  ],
98
+ [
99
+ "people",
100
+ "People"
101
+ ],
102
+ [
103
+ "events",
104
+ "Events"
105
+ ],
95
106
  [
96
107
  "ads",
97
108
  "Ads"
@@ -118,7 +129,7 @@ var groups_default = [
118
129
  var loginOptions = external_exports.object({
119
130
  apiKey: external_exports.string().optional().describe("API key for non-interactive login (skips the prompt)"),
120
131
  profile: external_exports.string().optional().describe("Name for this profile (defaults to the account route)"),
121
- companyId: external_exports.string().optional().describe(
132
+ accountId: external_exports.string().optional().describe(
122
133
  "Business account to act on behalf of (biz_xxx) \u2014 for OAuth users who manage more than one"
123
134
  )
124
135
  });
@@ -183,7 +194,7 @@ async function performLogin(input) {
183
194
  const { profileName, identity: identity2, existed: existed2 } = await performOAuthLogin({
184
195
  profile: input.profile,
185
196
  agent: input.agent,
186
- companyId: input.companyId
197
+ accountId: input.accountId
187
198
  });
188
199
  return {
189
200
  ok: true,
@@ -252,7 +263,7 @@ async function loginAdapter(c2) {
252
263
  agent: c2.agent,
253
264
  apiKey: c2.options.apiKey ?? c2.env.WHOP_API_KEY,
254
265
  profile: c2.options.profile,
255
- companyId: c2.options.companyId
266
+ accountId: c2.options.accountId
256
267
  });
257
268
  } catch (error) {
258
269
  if (error instanceof PromptCancelledError) {
@@ -277,14 +288,14 @@ async function loginAdapter(c2) {
277
288
  }
278
289
  ]
279
290
  };
280
- } else if (result.code === "MULTIPLE_COMPANIES" || result.code === "COMPANY_NOT_FOUND") {
291
+ } else if (result.code === "MULTIPLE_ACCOUNTS" || result.code === "ACCOUNT_NOT_FOUND") {
281
292
  cta = {
282
293
  description: "Choose which business account to use:",
283
294
  commands: [
284
295
  {
285
296
  command: "auth login",
286
- options: { companyId: true },
287
- description: "Pass --company-id biz_xxx"
297
+ options: { accountId: true },
298
+ description: "Pass --account-id biz_xxx"
288
299
  }
289
300
  ]
290
301
  };
@@ -297,14 +308,14 @@ async function loginAdapter(c2) {
297
308
  });
298
309
  }
299
310
  let firstRun = !result.existed;
300
- const companyId = getActiveProfile()?.companyId ?? "";
301
- if (companyId) {
311
+ const accountId = getActiveProfile()?.accountId ?? "";
312
+ if (accountId) {
302
313
  try {
303
- const { createWhopFetch: createWhopFetch2 } = await import("./api-XJ22R3CT.js");
304
- const fetch2 = createWhopFetch2();
305
- const res = await fetch2(
314
+ const { createWhopFetch: createWhopFetch2 } = await import("./api-U7WU3JXH.js");
315
+ const fetch3 = createWhopFetch2();
316
+ const res = await fetch3(
306
317
  new Request(
307
- `https://api.whop.com/products?company_id=${companyId}&first=1`
318
+ `https://api.whop.com/products?company_id=${accountId}&first=1`
308
319
  )
309
320
  );
310
321
  if (res.ok) {
@@ -314,14 +325,14 @@ async function loginAdapter(c2) {
314
325
  } catch {
315
326
  }
316
327
  }
317
- if (!companyId) {
328
+ if (!accountId) {
318
329
  return c2.ok(result.output, {
319
330
  cta: {
320
- description: "You're logged in, but no business account is linked to this account yet. Create a business account on Whop, then log in again:",
331
+ description: "You're logged in, but you don't have a business account yet. Create one and start selling in one command:",
321
332
  commands: [
322
333
  {
323
- command: "auth login",
324
- description: "Re-authenticate once you have a business account"
334
+ command: "quickstart",
335
+ description: "Create your business account, product, and checkout link"
325
336
  }
326
337
  ]
327
338
  }
@@ -585,10 +596,10 @@ import { text, isCancel } from "@clack/prompts";
585
596
  // src/commerce/client.ts
586
597
  var PLACEHOLDER = "https://api.whop.com";
587
598
  var whopFetch = createWhopFetch();
588
- async function makeWhopRequest(method, path, body) {
599
+ async function makeWhopRequest(method, path3, body) {
589
600
  const init = { method };
590
601
  if (body !== void 0) init.body = JSON.stringify(body);
591
- const res = await whopFetch(new Request(`${PLACEHOLDER}${path}`, init));
602
+ const res = await whopFetch(new Request(`${PLACEHOLDER}${path3}`, init));
592
603
  if (!res.ok) {
593
604
  const payload = await res.json().catch(() => null);
594
605
  throw new Error(payload?.message ?? res.statusText);
@@ -630,13 +641,13 @@ function registerListCommand(group, config) {
630
641
  });
631
642
  }
632
643
  function registerItemCommands(group, config) {
633
- const { path, noun, idLabel, schema, updateOptions, transformBody } = config;
644
+ const { path: path3, noun, idLabel, schema, updateOptions, transformBody } = config;
634
645
  const idArg = external_exports.object({ id: external_exports.string().describe(idLabel) });
635
646
  group.command("get", {
636
647
  description: `Get a ${noun} by ID`,
637
648
  args: idArg,
638
649
  output: schema,
639
- run: (c2) => makeWhopRequest(`GET`, `${path}/${c2.args.id}`)
650
+ run: (c2) => makeWhopRequest(`GET`, `${path3}/${c2.args.id}`)
640
651
  });
641
652
  if (updateOptions) {
642
653
  group.command("update", {
@@ -646,14 +657,14 @@ function registerItemCommands(group, config) {
646
657
  output: schema,
647
658
  run: (c2) => {
648
659
  const body = buildBody(c2.options);
649
- return makeWhopRequest("PATCH", `${path}/${c2.args.id}`, transformBody ? transformBody(body) : body);
660
+ return makeWhopRequest("PATCH", `${path3}/${c2.args.id}`, transformBody ? transformBody(body) : body);
650
661
  }
651
662
  });
652
663
  }
653
664
  group.command("delete", {
654
665
  description: `Delete a ${noun}`,
655
666
  args: idArg,
656
- run: (c2) => makeWhopRequest("DELETE", `${path}/${c2.args.id}`)
667
+ run: (c2) => makeWhopRequest("DELETE", `${path3}/${c2.args.id}`)
657
668
  });
658
669
  }
659
670
 
@@ -840,7 +851,7 @@ async function resolveProductId(providedId, isAgent) {
840
851
  if (providedId) return { ok: true, productId: providedId, autoResolved: false };
841
852
  const profile = getActiveProfile();
842
853
  const params = new URLSearchParams({ first: "100" });
843
- if (profile?.companyId) params.set("company_id", profile.companyId);
854
+ if (profile?.accountId) params.set("company_id", profile.accountId);
844
855
  let data;
845
856
  try {
846
857
  const res = await makeWhopRequest("GET", `/products?${params}`);
@@ -1111,7 +1122,10 @@ var quickstartOptions = external_exports.object({
1111
1122
  "every_two_years",
1112
1123
  "one_time"
1113
1124
  ]).optional().describe("Billing interval \u2014 use 'one_time' for a single payment"),
1114
- company_id: external_exports.string().optional().describe(
1125
+ business_name: external_exports.string().optional().describe(
1126
+ "Name for a new business account \u2014 quickstart creates it and sets up your product under it (user logins only; ignored with API-key auth, which already belongs to a business)"
1127
+ ),
1128
+ account_id: external_exports.string().optional().describe(
1115
1129
  "Business account to act on behalf of (biz_xxx); defaults to your active account"
1116
1130
  )
1117
1131
  });
@@ -1121,7 +1135,11 @@ var quickstartOutput = external_exports.object({
1121
1135
  checkoutUrl: external_exports.string().nullable().describe(
1122
1136
  "The live checkout link to share \u2014 the journey's payoff, present once a plan exists"
1123
1137
  ),
1124
- created: external_exports.object({ productId: external_exports.string().optional(), planId: external_exports.string().optional() }).nullable().describe(
1138
+ created: external_exports.object({
1139
+ accountId: external_exports.string().optional(),
1140
+ productId: external_exports.string().optional(),
1141
+ planId: external_exports.string().optional()
1142
+ }).nullable().describe(
1125
1143
  "What this run created, if anything \u2014 null for a read-only status check"
1126
1144
  ),
1127
1145
  steps: external_exports.array(StepSchema).describe("The path to your first sale"),
@@ -1160,36 +1178,87 @@ ${chalk3.yellow("!")} Agent setup skipped: ${message}`);
1160
1178
  );
1161
1179
  }
1162
1180
  }
1163
- const companyId = c2.options.company_id ?? await resolveActiveCompanyId() ?? "";
1181
+ const accountId = c2.options.account_id ?? await resolveActiveAccountId() ?? "";
1164
1182
  const accountName = profile?.accountTitle ?? profile?.accountRoute ?? profile?.name ?? "your account";
1165
- if (!companyId) {
1166
- return c2.error({
1167
- code: "NO_COMPANY",
1168
- message: "No business account is linked to this login. Create a business account on Whop, then log in again.",
1169
- retryable: false,
1170
- cta: {
1171
- description: "Create a business account, then re-authenticate:",
1172
- commands: [
1173
- {
1174
- command: "auth login",
1175
- description: "Log in and pick a business account"
1176
- }
1177
- ]
1178
- }
1183
+ const interactive = !c2.agent && !c2.formatExplicit;
1184
+ const canCreateBusiness = profile?.method === "oauth";
1185
+ let newBusinessName = canCreateBusiness ? c2.options.business_name : void 0;
1186
+ if (!canCreateBusiness && c2.options.business_name !== void 0 && interactive) {
1187
+ console.log(
1188
+ `
1189
+ ${chalk3.dim("Ignoring --business_name \u2014 this API key already belongs to a business.")}`
1190
+ );
1191
+ }
1192
+ if (!accountId && newBusinessName === void 0) {
1193
+ if (!canCreateBusiness) {
1194
+ return c2.error({
1195
+ code: "NO_ACCOUNT",
1196
+ message: "Couldn't resolve the business account for this API key. Check the key, or log in again.",
1197
+ retryable: true,
1198
+ cta: {
1199
+ commands: [{ command: "auth login", description: "Log in to Whop" }]
1200
+ }
1201
+ });
1202
+ }
1203
+ if (!interactive) {
1204
+ return c2.error({
1205
+ code: "NO_ACCOUNT",
1206
+ message: "No business account is linked to this login. Pass --business_name to create one and continue.",
1207
+ retryable: true,
1208
+ cta: {
1209
+ description: "Create your business account and product in one run:",
1210
+ commands: [
1211
+ {
1212
+ command: "quickstart",
1213
+ options: { business_name: "My Business" },
1214
+ description: "Create a business account, then your product"
1215
+ }
1216
+ ]
1217
+ }
1218
+ });
1219
+ }
1220
+ console.log(
1221
+ `
1222
+ ${chalk3.bold("You don't have a business account yet \u2014 let's create one.")}`
1223
+ );
1224
+ const name = await text2({
1225
+ message: "What's your business called?",
1226
+ placeholder: "My Business"
1179
1227
  });
1228
+ if (isCancel3(name)) {
1229
+ return c2.error({
1230
+ code: "CANCELLED",
1231
+ message: "Setup cancelled.",
1232
+ exitCode: 130
1233
+ });
1234
+ }
1235
+ newBusinessName = name;
1236
+ }
1237
+ if (newBusinessName !== void 0) {
1238
+ try {
1239
+ return await runCreate(c2, {
1240
+ accountId: "",
1241
+ accountName,
1242
+ products: [],
1243
+ newBusinessName
1244
+ });
1245
+ } catch (err) {
1246
+ if (err instanceof QuickstartError) return c2.error(err.envelope);
1247
+ throw err;
1248
+ }
1180
1249
  }
1181
1250
  const [productsRes, plansRes, checkoutRes] = await Promise.allSettled([
1182
1251
  makeWhopRequest(
1183
1252
  "GET",
1184
- `/products?company_id=${companyId}&first=100`
1253
+ `/products?company_id=${accountId}&first=100`
1185
1254
  ),
1186
1255
  makeWhopRequest(
1187
1256
  "GET",
1188
- `/plans?account_id=${companyId}&first=100`
1257
+ `/plans?account_id=${accountId}&first=100`
1189
1258
  ),
1190
1259
  makeWhopRequest(
1191
1260
  "GET",
1192
- `/checkout_configurations?company_id=${companyId}&first=100`
1261
+ `/checkout_configurations?company_id=${accountId}&first=100`
1193
1262
  )
1194
1263
  ]);
1195
1264
  const critical = [productsRes, plansRes].find((r) => r.status === "rejected");
@@ -1206,11 +1275,17 @@ ${chalk3.yellow("!")} Agent setup skipped: ${message}`);
1206
1275
  const checkouts = checkoutRes.status === "fulfilled" ? checkoutRes.value.data ?? [] : [];
1207
1276
  const ready = products.length > 0 && plans.length > 0;
1208
1277
  const hasCreationFlags = c2.options.title !== void 0 || c2.options.price !== void 0 || c2.options.billing_period !== void 0;
1209
- const canMutateInteractively = !c2.agent && !c2.formatExplicit;
1210
- const shouldCreate = hasCreationFlags || !ready && canMutateInteractively;
1278
+ const shouldCreate = hasCreationFlags || !ready && interactive;
1211
1279
  if (shouldCreate) {
1212
1280
  try {
1213
- return await runCreate(c2, { companyId, accountName, products });
1281
+ return await runCreate(c2, {
1282
+ accountId,
1283
+ accountName,
1284
+ products,
1285
+ // Only offer the new-business choice in the fully-guided flow —
1286
+ // flags mean the user already said what they want.
1287
+ offerNewBusiness: interactive && !hasCreationFlags && c2.options.account_id === void 0 && canCreateBusiness
1288
+ });
1214
1289
  } catch (err) {
1215
1290
  if (err instanceof QuickstartError) return c2.error(err.envelope);
1216
1291
  throw err;
@@ -1256,7 +1331,39 @@ async function runCreate(c2, state) {
1256
1331
  ${chalk3.bold("Let's get you set up to sell.")}
1257
1332
  `);
1258
1333
  }
1259
- const needsNewProduct = state.products.length === 0 || c2.options.title !== void 0;
1334
+ let { accountId, accountName, products, newBusinessName } = state;
1335
+ if (state.offerNewBusiness) {
1336
+ const choice = await select2({
1337
+ message: "Which business account is this for?",
1338
+ options: [
1339
+ { value: "current", label: accountName, hint: accountId },
1340
+ { value: "new", label: "Create a new business account" }
1341
+ ]
1342
+ });
1343
+ if (isCancel3(choice)) {
1344
+ throw new QuickstartError({
1345
+ code: "CANCELLED",
1346
+ message: "Setup cancelled.",
1347
+ exitCode: 130
1348
+ });
1349
+ }
1350
+ if (choice === "new") {
1351
+ const name = await text2({
1352
+ message: "What's your new business called?",
1353
+ placeholder: "My Business"
1354
+ });
1355
+ if (isCancel3(name)) {
1356
+ throw new QuickstartError({
1357
+ code: "CANCELLED",
1358
+ message: "Setup cancelled.",
1359
+ exitCode: 130
1360
+ });
1361
+ }
1362
+ newBusinessName = name;
1363
+ products = [];
1364
+ }
1365
+ }
1366
+ const needsNewProduct = products.length === 0 || c2.options.title !== void 0;
1260
1367
  const newTitle = needsNewProduct ? await resolveOrPrompt(
1261
1368
  c2,
1262
1369
  c2.options.title,
@@ -1270,7 +1377,7 @@ ${chalk3.bold("Let's get you set up to sell.")}
1270
1377
  placeholder: "My Online Course"
1271
1378
  })
1272
1379
  ) : void 0;
1273
- const existing = needsNewProduct ? void 0 : await resolveExistingProduct(c2, state.products);
1380
+ const existing = needsNewProduct ? void 0 : await resolveExistingProduct(c2, products);
1274
1381
  const price = await resolveOrPrompt(
1275
1382
  c2,
1276
1383
  c2.options.price,
@@ -1306,6 +1413,33 @@ ${chalk3.bold("Let's get you set up to sell.")}
1306
1413
  ]
1307
1414
  })
1308
1415
  );
1416
+ let accountCreated = false;
1417
+ if (newBusinessName !== void 0) {
1418
+ let account;
1419
+ try {
1420
+ account = await makeWhopRequest("POST", "/accounts", { title: newBusinessName });
1421
+ } catch (err) {
1422
+ return c2.error({
1423
+ code: "ACCOUNT_FAILED",
1424
+ message: `Failed to create the business account: ${err instanceof Error ? err.message : "unknown error"}`,
1425
+ retryable: true
1426
+ });
1427
+ }
1428
+ accountId = account.id;
1429
+ accountName = account.title ?? newBusinessName;
1430
+ accountCreated = true;
1431
+ setActiveProfileAccount({
1432
+ id: account.id,
1433
+ title: account.title ?? void 0,
1434
+ route: account.route ?? void 0
1435
+ });
1436
+ if (!c2.agent) {
1437
+ console.log(
1438
+ `
1439
+ ${chalk3.green("\u2713")} Created business account "${accountName}" ${chalk3.dim(`(${accountId})`)} \u2014 the CLI now acts on behalf of it.`
1440
+ );
1441
+ }
1442
+ }
1309
1443
  let productId;
1310
1444
  let productTitle;
1311
1445
  let productCreated = false;
@@ -1320,7 +1454,7 @@ ${chalk3.bold("Let's get you set up to sell.")}
1320
1454
  "/products",
1321
1455
  {
1322
1456
  title: newTitle,
1323
- company_id: state.companyId
1457
+ company_id: accountId
1324
1458
  }
1325
1459
  );
1326
1460
  } catch (err) {
@@ -1337,7 +1471,7 @@ ${chalk3.bold("Let's get you set up to sell.")}
1337
1471
  const isRenewal = billingPeriod !== "one_time";
1338
1472
  const planBody = {
1339
1473
  product_id: productId,
1340
- account_id: state.companyId,
1474
+ account_id: accountId,
1341
1475
  initial_price: price,
1342
1476
  plan_type: isRenewal ? "renewal" : "one_time"
1343
1477
  };
@@ -1373,6 +1507,15 @@ ${chalk3.bold("Let's get you set up to sell.")}
1373
1507
  const checkoutUrl = plan.purchase_url ?? null;
1374
1508
  const steps = [
1375
1509
  { id: "auth", label: "Log in", complete: true },
1510
+ ...accountCreated ? [
1511
+ {
1512
+ id: "account",
1513
+ label: "Create a business account",
1514
+ complete: true,
1515
+ firstId: accountId,
1516
+ firstTitle: accountName
1517
+ }
1518
+ ] : [],
1376
1519
  {
1377
1520
  id: "products",
1378
1521
  label: "Create a product",
@@ -1395,20 +1538,17 @@ ${chalk3.bold("Let's get you set up to sell.")}
1395
1538
  false
1396
1539
  );
1397
1540
  if (!c2.agent && !c2.formatExplicit) {
1398
- printSummary(
1399
- state.accountName,
1400
- steps,
1401
- true,
1402
- checkoutUrl,
1403
- nextStep,
1404
- productTitle
1405
- );
1541
+ printSummary(accountName, steps, true, checkoutUrl, nextStep, productTitle);
1406
1542
  }
1407
1543
  return c2.ok({
1408
- account: state.accountName,
1544
+ account: accountName,
1409
1545
  ready: true,
1410
1546
  checkoutUrl,
1411
- created: { productId, planId: plan.id },
1547
+ created: {
1548
+ ...accountCreated ? { accountId } : {},
1549
+ productId,
1550
+ planId: plan.id
1551
+ },
1412
1552
  steps,
1413
1553
  nextStep
1414
1554
  });
@@ -1535,6 +1675,479 @@ ${c.success("\u2713 Your store is fully set up.")}`);
1535
1675
  console.log("");
1536
1676
  }
1537
1677
 
1678
+ // package.json
1679
+ var package_default = {
1680
+ name: "@whop/cli",
1681
+ version: "0.2.0",
1682
+ description: "The Whop CLI \u2014 build and manage Whop apps from your terminal. Human and agent friendly.",
1683
+ keywords: [
1684
+ "agent",
1685
+ "apps",
1686
+ "cli",
1687
+ "developer",
1688
+ "whop"
1689
+ ],
1690
+ homepage: "https://whop.com/developers/",
1691
+ bugs: "https://github.com/whopio/whop-public-cli/issues",
1692
+ license: "MIT",
1693
+ repository: {
1694
+ type: "git",
1695
+ url: "git+https://github.com/whopio/whop-public-cli.git"
1696
+ },
1697
+ bin: {
1698
+ whop: "dist/index.js",
1699
+ "whop-cli": "dist/index.js"
1700
+ },
1701
+ files: [
1702
+ "dist"
1703
+ ],
1704
+ type: "module",
1705
+ publishConfig: {
1706
+ access: "public"
1707
+ },
1708
+ scripts: {
1709
+ build: "tsx scripts/sync-spec.ts && pnpm run clean && tsup",
1710
+ "build:binary": "tsx scripts/build-binary.ts",
1711
+ clean: "rm -rf dist",
1712
+ dev: "tsx scripts/sync-spec.ts && tsx src/index.ts",
1713
+ start: "node dist/index.js",
1714
+ "check-types": "tsx scripts/sync-spec.ts && tsc --noEmit",
1715
+ lint: "oxlint .",
1716
+ "lint:fix": "oxlint --fix --fix-suggestions && oxfmt",
1717
+ "ci:lint": "oxlint -f github .",
1718
+ format: "oxfmt",
1719
+ "sync-spec": "tsx scripts/sync-spec.ts",
1720
+ test: "tsx --test scripts/*.test.ts"
1721
+ },
1722
+ dependencies: {
1723
+ "@clack/prompts": "^1.5.1",
1724
+ "@napi-rs/keyring": "^1.3.0",
1725
+ "@whop/sdk": "^0.0.40",
1726
+ chalk: "5.4.1",
1727
+ yaml: "2.8.0"
1728
+ },
1729
+ devDependencies: {
1730
+ "@types/node": "25.3.5",
1731
+ incur: "github:whopio/incur#5ca60d5",
1732
+ tsup: "8.5.0",
1733
+ tsx: "4.19.4",
1734
+ typescript: "5.9.3"
1735
+ },
1736
+ engines: {
1737
+ node: ">=22"
1738
+ },
1739
+ packageManager: "pnpm@10.23.0"
1740
+ };
1741
+
1742
+ // src/lib/update/check.ts
1743
+ import fs from "fs";
1744
+ import path from "path";
1745
+ import { spawn } from "child_process";
1746
+
1747
+ // src/lib/colorize-output.ts
1748
+ var SECTION_HEADERS = /* @__PURE__ */ new Set([
1749
+ "Usage",
1750
+ "Arguments",
1751
+ "Options",
1752
+ "Examples",
1753
+ "Environment Variables",
1754
+ "Global Options",
1755
+ "Integrations",
1756
+ "Commands",
1757
+ "Aliases"
1758
+ ]);
1759
+ var FORMAT_FLAGS = ["--json", "--format", "--full-output", "--schema", "--llms", "--llms-full", "--mcp", "--token-count", "--token-limit", "--token-offset"];
1760
+ function hasStructuredOutputFlag(argv2) {
1761
+ return argv2.some((a) => FORMAT_FLAGS.includes(a) || a.startsWith("--format="));
1762
+ }
1763
+ function shouldColorize(argv2) {
1764
+ if (!process.stdout.isTTY) return false;
1765
+ return !hasStructuredOutputFlag(argv2);
1766
+ }
1767
+ function paintFlag(flag) {
1768
+ return flag.replace(/(<[^>]+>)/g, (m) => c.muted(m)).replace(/(--[\w-]+|-[\w])/g, (m) => c.flag(m));
1769
+ }
1770
+ var COMMAND_ROW = /^(\s+)(whop\s+\S.*?)(\s{2,}#\s.*)?$/;
1771
+ function highlightUrls(text3) {
1772
+ return text3.replace(/https?:\/\/[^\s)]+/g, (m) => c.link(m));
1773
+ }
1774
+ function colorizeLine(line, section, nextLine) {
1775
+ const errMatch = line.match(/^(Error(?: \([^)]+\))?:)(.*)$/);
1776
+ if (errMatch) return { line: c.error(errMatch[1]) + highlightUrls(errMatch[2]), section };
1777
+ if (line.startsWith("Run `")) return { line: c.heading(line), section };
1778
+ const header = line.match(/^([A-Z][A-Za-z ]+):(.*)$/);
1779
+ if (header && SECTION_HEADERS.has(header[1])) {
1780
+ const rest = header[2].replace(/(whop[\w\s-]*)/g, (m) => c.command(m));
1781
+ return { line: c.heading(`${header[1]}:`) + rest, section: header[1] };
1782
+ }
1783
+ const cmd = line.match(COMMAND_ROW);
1784
+ if (cmd) {
1785
+ return { line: `${cmd[1]}${c.command(cmd[2])}${cmd[3] ? c.description(cmd[3]) : ""}`, section };
1786
+ }
1787
+ if (line.trim().endsWith(":") && nextLine !== void 0 && COMMAND_ROW.test(nextLine)) {
1788
+ return { line: c.heading(line), section };
1789
+ }
1790
+ if (line.trim() === "") return { line, section: null };
1791
+ if (section === "Options" || section === "Global Options" || section === "Environment Variables") {
1792
+ const m = line.match(/^(\s+)(\S.*?)(\s{2,})(.*)$/);
1793
+ if (m) return { line: `${m[1]}${paintFlag(m[2])}${m[3]}${c.description(m[4])}`, section };
1794
+ }
1795
+ if (section === "Commands" || section === "Integrations" || section === "Aliases") {
1796
+ const m = line.match(/^(\s+)(\S+)(\s{2,})(.*)$/);
1797
+ if (m) return { line: `${m[1]}${c.command(m[2])}${m[3]}${c.description(m[4])}`, section };
1798
+ }
1799
+ if (section === "Arguments") {
1800
+ const m = line.match(/^(\s+)(\S+)(\s{2,})(.*)$/);
1801
+ if (m) return { line: `${m[1]}${c.id(m[2])}${m[3]}${c.description(m[4])}`, section };
1802
+ }
1803
+ return { line: highlightUrls(line), section };
1804
+ }
1805
+ function colorizeOutput(text3) {
1806
+ let section = null;
1807
+ const lines = text3.split("\n");
1808
+ return lines.map((line, i) => {
1809
+ const result = colorizeLine(line, section, lines[i + 1]);
1810
+ section = result.section;
1811
+ return result.line;
1812
+ }).join("\n");
1813
+ }
1814
+
1815
+ // src/lib/update/check.ts
1816
+ var DEFAULT_MANIFEST_URL = "https://github.com/whopio/whop-public-cli/releases/latest/download/manifest.json";
1817
+ function manifestUrl(env = process.env) {
1818
+ return env.WHOP_CLI_MANIFEST_URL?.trim() || DEFAULT_MANIFEST_URL;
1819
+ }
1820
+ var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
1821
+ function cachePath(env) {
1822
+ return path.join(configDir(env), "update-check.json");
1823
+ }
1824
+ function readUpdateCache(env = process.env) {
1825
+ try {
1826
+ const parsed = JSON.parse(
1827
+ fs.readFileSync(cachePath(env), "utf8")
1828
+ );
1829
+ if (parsed != null && typeof parsed === "object" && !Array.isArray(parsed)) {
1830
+ return parsed;
1831
+ }
1832
+ } catch {
1833
+ }
1834
+ return {};
1835
+ }
1836
+ function writeUpdateCache(cache, env = process.env) {
1837
+ try {
1838
+ fs.mkdirSync(configDir(env), { recursive: true, mode: 448 });
1839
+ fs.writeFileSync(cachePath(env), `${JSON.stringify(cache, null, 2)}
1840
+ `, {
1841
+ mode: 384
1842
+ });
1843
+ } catch {
1844
+ }
1845
+ }
1846
+ function isNewerVersion(candidate, current) {
1847
+ const parse = (v) => v.replace(/^v/, "").split("-")[0].split(".").map((part) => Number.parseInt(part, 10) || 0);
1848
+ const a = parse(candidate);
1849
+ const b = parse(current);
1850
+ for (let i = 0; i < Math.max(a.length, b.length); i++) {
1851
+ if ((a[i] ?? 0) > (b[i] ?? 0)) return true;
1852
+ if ((a[i] ?? 0) < (b[i] ?? 0)) return false;
1853
+ }
1854
+ return false;
1855
+ }
1856
+ function upgradeCommandFor(channel) {
1857
+ switch (channel) {
1858
+ case "npm":
1859
+ return "npm install -g @whop/cli";
1860
+ case "brew":
1861
+ return "brew upgrade whop";
1862
+ default:
1863
+ return "whop upgrade";
1864
+ }
1865
+ }
1866
+ function updateCheckSuppressed(argv2, env = process.env, stderrIsTty = process.stderr.isTTY ?? false) {
1867
+ if (env.WHOP_CLI_NO_UPDATE_CHECK) return true;
1868
+ if (env.CI) return true;
1869
+ if (!stderrIsTty) return true;
1870
+ if (hasStructuredOutputFlag(argv2)) return true;
1871
+ const first = argv2[0];
1872
+ if (first === "upgrade" || first === "mcp" || first === "completions" || first?.startsWith("--")) {
1873
+ return true;
1874
+ }
1875
+ return false;
1876
+ }
1877
+ function spawnBackgroundCheck() {
1878
+ const args = detectChannel() === "standalone" || detectChannel() === "brew" ? ["upgrade", "--background"] : [process.argv[1], "upgrade", "--background"];
1879
+ try {
1880
+ spawn(process.execPath, args, {
1881
+ detached: true,
1882
+ stdio: "ignore"
1883
+ }).unref();
1884
+ } catch {
1885
+ }
1886
+ }
1887
+ function scheduleUpdateNotice(argv2, currentVersion, env = process.env) {
1888
+ const channel = detectChannel(env);
1889
+ if (channel === "dev") return;
1890
+ if (updateCheckSuppressed(argv2, env)) return;
1891
+ const cache = readUpdateCache(env);
1892
+ if (cache.updatedTo && cache.updatedTo === currentVersion) {
1893
+ writeUpdateCache({ ...cache, updatedTo: void 0 }, env);
1894
+ process.on("exit", () => {
1895
+ process.stderr.write(
1896
+ `
1897
+ whop was updated to v${currentVersion} automatically.
1898
+ `
1899
+ );
1900
+ });
1901
+ return;
1902
+ }
1903
+ if (cache.latestVersion && isNewerVersion(cache.latestVersion, currentVersion)) {
1904
+ const latest = cache.latestVersion;
1905
+ process.on("exit", () => {
1906
+ process.stderr.write(
1907
+ `
1908
+ A new version of whop is available: v${currentVersion} \u2192 v${latest}
1909
+ Run \`${upgradeCommandFor(channel)}\` to update.
1910
+ `
1911
+ );
1912
+ });
1913
+ }
1914
+ const lastChecked = cache.lastCheckedAt ? new Date(cache.lastCheckedAt).getTime() : 0;
1915
+ if (Date.now() - lastChecked > CHECK_INTERVAL_MS) {
1916
+ writeUpdateCache({ ...cache, lastCheckedAt: (/* @__PURE__ */ new Date()).toISOString() }, env);
1917
+ spawnBackgroundCheck();
1918
+ }
1919
+ }
1920
+
1921
+ // src/lib/update/self-update.ts
1922
+ import crypto from "crypto";
1923
+ import fs2 from "fs";
1924
+ import path2 from "path";
1925
+ var SelfUpdateError = class extends Error {
1926
+ constructor(code, message) {
1927
+ super(message);
1928
+ this.code = code;
1929
+ }
1930
+ };
1931
+ async function fetchManifest(env = process.env) {
1932
+ const url = manifestUrl(env);
1933
+ let response;
1934
+ try {
1935
+ response = await fetch(url, {
1936
+ signal: AbortSignal.timeout(1e4),
1937
+ redirect: "follow"
1938
+ });
1939
+ } catch {
1940
+ throw new SelfUpdateError(
1941
+ "MANIFEST_UNREACHABLE",
1942
+ `Could not reach the update manifest at ${url}.`
1943
+ );
1944
+ }
1945
+ if (!response.ok) {
1946
+ throw new SelfUpdateError(
1947
+ "MANIFEST_UNAVAILABLE",
1948
+ `Update manifest request failed with HTTP ${response.status}.`
1949
+ );
1950
+ }
1951
+ let parsed;
1952
+ try {
1953
+ parsed = await response.json();
1954
+ } catch {
1955
+ throw new SelfUpdateError(
1956
+ "MANIFEST_INVALID",
1957
+ "Update manifest is not valid JSON."
1958
+ );
1959
+ }
1960
+ const manifest = parsed;
1961
+ if (typeof manifest?.version !== "string" || manifest.assets == null || typeof manifest.assets !== "object") {
1962
+ throw new SelfUpdateError(
1963
+ "MANIFEST_INVALID",
1964
+ "Update manifest is missing version or assets."
1965
+ );
1966
+ }
1967
+ return manifest;
1968
+ }
1969
+ function assetForThisBinary(manifest) {
1970
+ if (!buildTarget) {
1971
+ throw new SelfUpdateError(
1972
+ "NOT_A_STANDALONE_BUILD",
1973
+ "This build has no compile target \u2014 self-update only applies to standalone binaries."
1974
+ );
1975
+ }
1976
+ const asset = manifest.assets[buildTarget];
1977
+ if (!asset?.url || !asset.sha256) {
1978
+ throw new SelfUpdateError(
1979
+ "NO_ASSET_FOR_TARGET",
1980
+ `The latest release has no binary for ${buildTarget}.`
1981
+ );
1982
+ }
1983
+ return { ...asset, target: buildTarget };
1984
+ }
1985
+ async function downloadAndSwap(asset, execPath = process.execPath) {
1986
+ let response;
1987
+ try {
1988
+ response = await fetch(asset.url, {
1989
+ signal: AbortSignal.timeout(12e4),
1990
+ redirect: "follow"
1991
+ });
1992
+ } catch {
1993
+ throw new SelfUpdateError(
1994
+ "DOWNLOAD_FAILED",
1995
+ `Could not download ${asset.url}.`
1996
+ );
1997
+ }
1998
+ if (!response.ok) {
1999
+ throw new SelfUpdateError(
2000
+ "DOWNLOAD_FAILED",
2001
+ `Binary download failed with HTTP ${response.status}.`
2002
+ );
2003
+ }
2004
+ const bytes = Buffer.from(await response.arrayBuffer());
2005
+ const digest = crypto.createHash("sha256").update(bytes).digest("hex");
2006
+ if (digest !== asset.sha256.toLowerCase()) {
2007
+ throw new SelfUpdateError(
2008
+ "CHECKSUM_MISMATCH",
2009
+ `Downloaded binary checksum ${digest} does not match the manifest \u2014 aborting.`
2010
+ );
2011
+ }
2012
+ const dir = path2.dirname(execPath);
2013
+ const tmp = path2.join(dir, `.${path2.basename(execPath)}.${process.pid}.new`);
2014
+ try {
2015
+ fs2.writeFileSync(tmp, bytes, { mode: 493 });
2016
+ fs2.renameSync(tmp, execPath);
2017
+ } catch (err) {
2018
+ try {
2019
+ fs2.rmSync(tmp, { force: true });
2020
+ } catch {
2021
+ }
2022
+ const code = err.code;
2023
+ if (code === "EACCES" || code === "EPERM" || code === "EROFS") {
2024
+ throw new SelfUpdateError(
2025
+ "PERMISSION_DENIED",
2026
+ `No write access to ${dir}. Re-run with elevated permissions (e.g. \`sudo whop upgrade\`) or reinstall.`
2027
+ );
2028
+ }
2029
+ throw err;
2030
+ }
2031
+ }
2032
+
2033
+ // src/lib/update/command.ts
2034
+ var upgradeOptions = external_exports.object({
2035
+ check: external_exports.boolean().optional().describe("Only check for a newer version, don't install it"),
2036
+ background: external_exports.boolean().optional().describe(
2037
+ "Internal: refresh the update cache silently (spawned by the automatic check)"
2038
+ )
2039
+ });
2040
+ var upgradeOutput = external_exports.object({
2041
+ status: external_exports.enum(["up-to-date", "update-available", "updated"]).describe("Result of the upgrade check"),
2042
+ current: external_exports.string().describe("The version currently running"),
2043
+ latest: external_exports.string().describe("The latest released version"),
2044
+ channel: external_exports.enum(["npm", "brew", "standalone", "dev"]).describe("How this CLI was installed"),
2045
+ upgradeCommand: external_exports.string().optional().describe("Run this shell command to install the available update")
2046
+ });
2047
+ async function runBackground(env) {
2048
+ const manifest = await fetchManifest(env);
2049
+ const cache = readUpdateCache(env);
2050
+ writeUpdateCache(
2051
+ {
2052
+ ...cache,
2053
+ lastCheckedAt: (/* @__PURE__ */ new Date()).toISOString(),
2054
+ latestVersion: manifest.version
2055
+ },
2056
+ env
2057
+ );
2058
+ if (detectChannel(env) === "standalone" && env.WHOP_CLI_AUTO_UPDATE !== "0" && isNewerVersion(manifest.version, package_default.version)) {
2059
+ await downloadAndSwap(assetForThisBinary(manifest));
2060
+ writeUpdateCache(
2061
+ {
2062
+ lastCheckedAt: (/* @__PURE__ */ new Date()).toISOString(),
2063
+ latestVersion: manifest.version,
2064
+ updatedTo: manifest.version
2065
+ },
2066
+ env
2067
+ );
2068
+ }
2069
+ }
2070
+ async function runUpgrade(c2, env = process.env) {
2071
+ if (c2.options.background) {
2072
+ try {
2073
+ await runBackground(env);
2074
+ } catch {
2075
+ }
2076
+ return c2.ok({
2077
+ status: "up-to-date",
2078
+ current: package_default.version,
2079
+ latest: package_default.version,
2080
+ channel: detectChannel(env)
2081
+ });
2082
+ }
2083
+ const channel = detectChannel(env);
2084
+ let manifest;
2085
+ try {
2086
+ manifest = await fetchManifest(env);
2087
+ } catch (err) {
2088
+ if (err instanceof SelfUpdateError) {
2089
+ return c2.error({ code: err.code, message: err.message, retryable: true });
2090
+ }
2091
+ throw err;
2092
+ }
2093
+ writeUpdateCache(
2094
+ {
2095
+ ...readUpdateCache(env),
2096
+ lastCheckedAt: (/* @__PURE__ */ new Date()).toISOString(),
2097
+ latestVersion: manifest.version
2098
+ },
2099
+ env
2100
+ );
2101
+ const base = { current: package_default.version, latest: manifest.version, channel };
2102
+ if (!isNewerVersion(manifest.version, package_default.version)) {
2103
+ return c2.ok({ status: "up-to-date", ...base });
2104
+ }
2105
+ if (channel === "npm" || channel === "brew") {
2106
+ return c2.ok({
2107
+ status: "update-available",
2108
+ ...base,
2109
+ upgradeCommand: upgradeCommandFor(channel)
2110
+ });
2111
+ }
2112
+ if (channel === "dev") {
2113
+ return c2.error({
2114
+ code: "DEV_BUILD",
2115
+ message: "Running from source \u2014 pull the latest instead of upgrading.",
2116
+ retryable: false
2117
+ });
2118
+ }
2119
+ if (c2.options.check) {
2120
+ return c2.ok(
2121
+ {
2122
+ status: "update-available",
2123
+ ...base,
2124
+ upgradeCommand: upgradeCommandFor(channel)
2125
+ },
2126
+ {
2127
+ cta: {
2128
+ description: `v${manifest.version} is available (you have v${package_default.version}). To update:`,
2129
+ commands: [
2130
+ { command: "upgrade", description: "Install the latest version" }
2131
+ ]
2132
+ }
2133
+ }
2134
+ );
2135
+ }
2136
+ try {
2137
+ await downloadAndSwap(assetForThisBinary(manifest));
2138
+ } catch (err) {
2139
+ if (err instanceof SelfUpdateError) {
2140
+ return c2.error({
2141
+ code: err.code,
2142
+ message: err.message,
2143
+ retryable: err.code !== "PERMISSION_DENIED"
2144
+ });
2145
+ }
2146
+ throw err;
2147
+ }
2148
+ return c2.ok({ status: "updated", ...base });
2149
+ }
2150
+
1538
2151
  // src/commands.ts
1539
2152
  var HANDWRITTEN_GROUPS = [
1540
2153
  {
@@ -1543,7 +2156,7 @@ var HANDWRITTEN_GROUPS = [
1543
2156
  section: "get-started",
1544
2157
  register: (cli2) => cli2.command("quickstart", {
1545
2158
  description: "Start selling \u2014 check your status and create what's missing",
1546
- hint: "In a terminal it guides you to your first sale. Agents: a read-only status check unless you pass --title/--price/--billing_period.",
2159
+ hint: "In a terminal it guides you to your first sale \u2014 including creating a business account if you don't have one. Agents: a read-only status check unless you pass --business_name/--title/--price/--billing_period.",
1547
2160
  options: quickstartOptions,
1548
2161
  output: quickstartOutput,
1549
2162
  examples: [
@@ -1555,6 +2168,15 @@ var HANDWRITTEN_GROUPS = [
1555
2168
  billing_period: "monthly"
1556
2169
  },
1557
2170
  description: "Create a $9.99/mo product non-interactively"
2171
+ },
2172
+ {
2173
+ options: {
2174
+ business_name: "My Business",
2175
+ title: "My Course",
2176
+ price: 9.99,
2177
+ billing_period: "one_time"
2178
+ },
2179
+ description: "No business account yet? Create it and the product in one run"
1558
2180
  }
1559
2181
  ],
1560
2182
  outputPolicy: "agent-only",
@@ -1579,6 +2201,24 @@ var HANDWRITTEN_GROUPS = [
1579
2201
  section: "commerce",
1580
2202
  register: (cli2) => cli2.command(buildCheckoutGroup())
1581
2203
  },
2204
+ {
2205
+ name: "upgrade",
2206
+ description: "Update the CLI to the latest version",
2207
+ section: "get-started",
2208
+ register: (cli2) => cli2.command("upgrade", {
2209
+ description: "Update the whop CLI to the latest version",
2210
+ options: upgradeOptions,
2211
+ output: upgradeOutput,
2212
+ examples: [
2213
+ { description: "Update to the latest version" },
2214
+ {
2215
+ options: { check: true },
2216
+ description: "Check for a newer version without installing"
2217
+ }
2218
+ ],
2219
+ run: (c2) => runUpgrade(c2)
2220
+ })
2221
+ },
1582
2222
  {
1583
2223
  name: "auth",
1584
2224
  description: "Manage authentication",
@@ -1635,69 +2275,6 @@ async function setupAgents(cli2) {
1635
2275
  }
1636
2276
  }
1637
2277
 
1638
- // package.json
1639
- var package_default = {
1640
- name: "@whop/cli",
1641
- version: "0.0.6",
1642
- description: "The Whop CLI \u2014 build and manage Whop apps from your terminal. Human and agent friendly.",
1643
- keywords: [
1644
- "agent",
1645
- "apps",
1646
- "cli",
1647
- "developer",
1648
- "whop"
1649
- ],
1650
- homepage: "https://whop.com/developers/",
1651
- bugs: "https://github.com/whopio/whop-sdk-ts/issues",
1652
- license: "MIT",
1653
- repository: {
1654
- type: "git",
1655
- url: "git+https://github.com/whopio/whop-sdk-ts.git",
1656
- directory: "packages/cli"
1657
- },
1658
- bin: {
1659
- whop: "dist/index.js",
1660
- "whop-cli": "dist/index.js"
1661
- },
1662
- files: [
1663
- "dist"
1664
- ],
1665
- type: "module",
1666
- publishConfig: {
1667
- access: "public"
1668
- },
1669
- scripts: {
1670
- build: "tsx scripts/sync-spec.ts && pnpm run clean && tsup",
1671
- clean: "rm -rf dist",
1672
- dev: "tsx scripts/sync-spec.ts && tsx src/index.ts",
1673
- start: "node dist/index.js",
1674
- "check-types": "tsx scripts/sync-spec.ts && tsc --noEmit",
1675
- lint: "oxlint .",
1676
- "lint:fix": "oxlint --fix --fix-suggestions && oxfmt",
1677
- "ci:lint": "oxlint -f github .",
1678
- format: "oxfmt",
1679
- "sync-spec": "tsx scripts/sync-spec.ts",
1680
- test: "tsx --test scripts/*.test.ts"
1681
- },
1682
- dependencies: {
1683
- "@clack/prompts": "^1.5.1",
1684
- "@napi-rs/keyring": "^1.3.0",
1685
- "@whop/sdk": "^0.0.40",
1686
- chalk: "5.4.1"
1687
- },
1688
- devDependencies: {
1689
- "@types/node": "25.3.5",
1690
- incur: "github:whopio/incur#5ca60d5",
1691
- tsup: "8.5.0",
1692
- tsx: "4.19.4",
1693
- typescript: "5.9.3"
1694
- },
1695
- engines: {
1696
- node: ">=22"
1697
- },
1698
- packageManager: "pnpm@10.23.0"
1699
- };
1700
-
1701
2278
  // src/lib/renderer.ts
1702
2279
  var MAX_CELL_WIDTH = 40;
1703
2280
  function isPlainObject(value) {
@@ -1782,8 +2359,8 @@ var cli = Cli_exports.create("whop", {
1782
2359
  }
1783
2360
  });
1784
2361
  var spec = (tag) => filterSpecByTag(native_spec_default, tag);
1785
- var fetch = createWhopFetch();
1786
- var isAuthExempt = (cmd) => !cmd || cmd === "login" || cmd === "logout" || cmd === "completions" || cmd.startsWith("auth") || cmd.startsWith("mcp");
2362
+ var fetch2 = createWhopFetch();
2363
+ var isAuthExempt = (cmd) => !cmd || cmd === "login" || cmd === "logout" || cmd === "completions" || cmd === "upgrade" || cmd.startsWith("auth") || cmd.startsWith("mcp");
1787
2364
  cli.use(async (c2, next) => {
1788
2365
  if (isAuthExempt(c2.command)) return next();
1789
2366
  if (getActiveProfile()) return next();
@@ -1823,7 +2400,7 @@ cli.use(async (c2, next) => {
1823
2400
  });
1824
2401
  registerHandwrittenGroups(cli);
1825
2402
  for (const { name, tag } of API_GROUPS) {
1826
- cli.command(name, { fetch, openapi: spec(tag) });
2403
+ cli.command(name, { fetch: fetch2, openapi: spec(tag) });
1827
2404
  }
1828
2405
  var cli_default = cli;
1829
2406
 
@@ -1860,6 +2437,13 @@ var api_structure_default = [
1860
2437
  "Referrals"
1861
2438
  ]
1862
2439
  },
2440
+ {
2441
+ group: "Tracking",
2442
+ tags: [
2443
+ "People",
2444
+ "Events"
2445
+ ]
2446
+ },
1863
2447
  {
1864
2448
  group: "Ads",
1865
2449
  tags: [
@@ -1997,73 +2581,9 @@ function buildGroupedHelp(version, description) {
1997
2581
  return lines.join("\n");
1998
2582
  }
1999
2583
 
2000
- // src/lib/colorize-output.ts
2001
- var SECTION_HEADERS = /* @__PURE__ */ new Set([
2002
- "Usage",
2003
- "Arguments",
2004
- "Options",
2005
- "Examples",
2006
- "Environment Variables",
2007
- "Global Options",
2008
- "Integrations",
2009
- "Commands",
2010
- "Aliases"
2011
- ]);
2012
- var FORMAT_FLAGS = ["--json", "--format", "--full-output", "--schema", "--llms", "--llms-full", "--mcp", "--token-count", "--token-limit", "--token-offset"];
2013
- function shouldColorize(argv2) {
2014
- if (!process.stdout.isTTY) return false;
2015
- return !argv2.some((a) => FORMAT_FLAGS.includes(a) || a.startsWith("--format="));
2016
- }
2017
- function paintFlag(flag) {
2018
- return flag.replace(/(<[^>]+>)/g, (m) => c.muted(m)).replace(/(--[\w-]+|-[\w])/g, (m) => c.flag(m));
2019
- }
2020
- var COMMAND_ROW = /^(\s+)(whop\s+\S.*?)(\s{2,}#\s.*)?$/;
2021
- function highlightUrls(text3) {
2022
- return text3.replace(/https?:\/\/[^\s)]+/g, (m) => c.link(m));
2023
- }
2024
- function colorizeLine(line, section, nextLine) {
2025
- const errMatch = line.match(/^(Error(?: \([^)]+\))?:)(.*)$/);
2026
- if (errMatch) return { line: c.error(errMatch[1]) + highlightUrls(errMatch[2]), section };
2027
- if (line.startsWith("Run `")) return { line: c.heading(line), section };
2028
- const header = line.match(/^([A-Z][A-Za-z ]+):(.*)$/);
2029
- if (header && SECTION_HEADERS.has(header[1])) {
2030
- const rest = header[2].replace(/(whop[\w\s-]*)/g, (m) => c.command(m));
2031
- return { line: c.heading(`${header[1]}:`) + rest, section: header[1] };
2032
- }
2033
- const cmd = line.match(COMMAND_ROW);
2034
- if (cmd) {
2035
- return { line: `${cmd[1]}${c.command(cmd[2])}${cmd[3] ? c.description(cmd[3]) : ""}`, section };
2036
- }
2037
- if (line.trim().endsWith(":") && nextLine !== void 0 && COMMAND_ROW.test(nextLine)) {
2038
- return { line: c.heading(line), section };
2039
- }
2040
- if (line.trim() === "") return { line, section: null };
2041
- if (section === "Options" || section === "Global Options" || section === "Environment Variables") {
2042
- const m = line.match(/^(\s+)(\S.*?)(\s{2,})(.*)$/);
2043
- if (m) return { line: `${m[1]}${paintFlag(m[2])}${m[3]}${c.description(m[4])}`, section };
2044
- }
2045
- if (section === "Commands" || section === "Integrations" || section === "Aliases") {
2046
- const m = line.match(/^(\s+)(\S+)(\s{2,})(.*)$/);
2047
- if (m) return { line: `${m[1]}${c.command(m[2])}${m[3]}${c.description(m[4])}`, section };
2048
- }
2049
- if (section === "Arguments") {
2050
- const m = line.match(/^(\s+)(\S+)(\s{2,})(.*)$/);
2051
- if (m) return { line: `${m[1]}${c.id(m[2])}${m[3]}${c.description(m[4])}`, section };
2052
- }
2053
- return { line: highlightUrls(line), section };
2054
- }
2055
- function colorizeOutput(text3) {
2056
- let section = null;
2057
- const lines = text3.split("\n");
2058
- return lines.map((line, i) => {
2059
- const result = colorizeLine(line, section, lines[i + 1]);
2060
- section = result.section;
2061
- return result.line;
2062
- }).join("\n");
2063
- }
2064
-
2065
2584
  // src/index.ts
2066
2585
  var argv = process.argv.slice(2);
2586
+ scheduleUpdateNotice(argv, package_default.version);
2067
2587
  async function serve(argv2) {
2068
2588
  if (shouldColorize(argv2)) {
2069
2589
  await cli_default.serve(argv2, {
@@ -2086,8 +2606,4 @@ if (argv.length === 0 && !getActiveProfile() && !process.env.WHOP_API_KEY) {
2086
2606
  } else {
2087
2607
  await serve(argv);
2088
2608
  }
2089
- var index_default = cli_default;
2090
- export {
2091
- index_default as default
2092
- };
2093
2609
  //# sourceMappingURL=index.js.map