@whop/cli 0.12.0 → 0.13.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 +508 -92
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
external_exports
|
|
6
6
|
} from "./chunk-KFCNNWPI.js";
|
|
7
7
|
|
|
8
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
8
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Cli.js
|
|
9
9
|
var Cli_exports = {};
|
|
10
10
|
__export(Cli_exports, {
|
|
11
11
|
collectSkillCommands: () => collectSkillCommands,
|
|
@@ -106,7 +106,7 @@ function extractSegmentPart(segment, segmentTokenStart, segmentTokenCount, targe
|
|
|
106
106
|
return segment.slice(charStart, charEnd);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
109
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/internal/helpers.js
|
|
110
110
|
function isRecord(value) {
|
|
111
111
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
112
112
|
}
|
|
@@ -154,7 +154,7 @@ function suggest(input, candidates) {
|
|
|
154
154
|
return best;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
157
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Completions.js
|
|
158
158
|
function register(shell, name) {
|
|
159
159
|
switch (shell) {
|
|
160
160
|
case "bash":
|
|
@@ -417,7 +417,7 @@ let _incur_complete_${id} = {|spans|
|
|
|
417
417
|
}`;
|
|
418
418
|
}
|
|
419
419
|
|
|
420
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
420
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Errors.js
|
|
421
421
|
var BaseError = class extends Error {
|
|
422
422
|
name = "Incur.BaseError";
|
|
423
423
|
/** The short, human-readable error message (without details). */
|
|
@@ -491,7 +491,7 @@ function walk(error, fn) {
|
|
|
491
491
|
return current;
|
|
492
492
|
}
|
|
493
493
|
|
|
494
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
494
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Fetch.js
|
|
495
495
|
var reservedFlags = /* @__PURE__ */ new Set(["method", "body", "data", "header"]);
|
|
496
496
|
var reservedShort = { X: "method", d: "data", H: "header" };
|
|
497
497
|
function parseArgv(argv2) {
|
|
@@ -627,7 +627,7 @@ async function parseResponse(response) {
|
|
|
627
627
|
};
|
|
628
628
|
}
|
|
629
629
|
|
|
630
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
630
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Filter.js
|
|
631
631
|
function parse(expression) {
|
|
632
632
|
const paths = [];
|
|
633
633
|
const tokens = [];
|
|
@@ -1127,7 +1127,7 @@ function resolveOptions(options) {
|
|
|
1127
1127
|
};
|
|
1128
1128
|
}
|
|
1129
1129
|
|
|
1130
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
1130
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/internal/json.js
|
|
1131
1131
|
function stringify(value, space) {
|
|
1132
1132
|
return JSON.stringify(value, (_key, value2) => {
|
|
1133
1133
|
if (typeof value2 === "bigint")
|
|
@@ -1139,7 +1139,7 @@ function normalize(value) {
|
|
|
1139
1139
|
return JSON.parse(stringify(value));
|
|
1140
1140
|
}
|
|
1141
1141
|
|
|
1142
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
1142
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/internal/yaml.js
|
|
1143
1143
|
import { createRequire } from "module";
|
|
1144
1144
|
var cached;
|
|
1145
1145
|
async function load() {
|
|
@@ -1151,7 +1151,7 @@ function loadSync() {
|
|
|
1151
1151
|
return cached;
|
|
1152
1152
|
}
|
|
1153
1153
|
|
|
1154
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
1154
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Formatter.js
|
|
1155
1155
|
function format2(value, fmt = "toon") {
|
|
1156
1156
|
if (value == null)
|
|
1157
1157
|
return "";
|
|
@@ -1259,7 +1259,7 @@ ${String(val)}`;
|
|
|
1259
1259
|
return kvTable(obj);
|
|
1260
1260
|
}
|
|
1261
1261
|
|
|
1262
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
1262
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Parser.js
|
|
1263
1263
|
function parse2(argv2, options = {}) {
|
|
1264
1264
|
const { args: argsSchema, options: optionsSchema, alias, defaults } = options;
|
|
1265
1265
|
const optionNames = createOptionNames(optionsSchema, alias);
|
|
@@ -1676,7 +1676,7 @@ function defaultEnvSource() {
|
|
|
1676
1676
|
return {};
|
|
1677
1677
|
}
|
|
1678
1678
|
|
|
1679
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
1679
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/internal/command.js
|
|
1680
1680
|
var sentinel = Symbol.for("incur.sentinel");
|
|
1681
1681
|
async function execute(command, options) {
|
|
1682
1682
|
const { argv: argv2, inputOptions: inputOptions2, agent, format: format3, formatExplicit, name, path: path9, version, envSource = process.env, env: envSchema, globals = {}, vars: varsSchema, middlewares = [], request: request2 } = options;
|
|
@@ -1925,7 +1925,7 @@ function findBuiltinSubcommand(builtin, token) {
|
|
|
1925
1925
|
return builtin.subcommands?.find((sub) => sub.name === token || sub.aliases?.includes(token));
|
|
1926
1926
|
}
|
|
1927
1927
|
|
|
1928
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
1928
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Help.js
|
|
1929
1929
|
function formatRoot(name, options = {}) {
|
|
1930
1930
|
const { aliases, configFlag, description, globals, version, commands = [], root = false } = options;
|
|
1931
1931
|
const lines = [];
|
|
@@ -2211,7 +2211,7 @@ function redact(value) {
|
|
|
2211
2211
|
return `****${value.slice(-4)}`;
|
|
2212
2212
|
}
|
|
2213
2213
|
|
|
2214
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
2214
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/internal/cta.js
|
|
2215
2215
|
function formatCtaBlock(name, block) {
|
|
2216
2216
|
if (!block || block.commands.length === 0)
|
|
2217
2217
|
return void 0;
|
|
@@ -2234,7 +2234,7 @@ function formatCta(name, cta) {
|
|
|
2234
2234
|
return { command: cmd, ...cta.description ? { description: cta.description } : void 0 };
|
|
2235
2235
|
}
|
|
2236
2236
|
|
|
2237
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
2237
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/internal/pm.js
|
|
2238
2238
|
function detectRunner() {
|
|
2239
2239
|
const userAgent = process.env.npm_config_user_agent ?? "";
|
|
2240
2240
|
const execPath = process.env.npm_execpath ?? "";
|
|
@@ -2245,7 +2245,7 @@ function detectRunner() {
|
|
|
2245
2245
|
return "npx";
|
|
2246
2246
|
}
|
|
2247
2247
|
|
|
2248
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
2248
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Schema.js
|
|
2249
2249
|
function toJsonSchema(schema) {
|
|
2250
2250
|
const result = external_exports.toJSONSchema(schema, {
|
|
2251
2251
|
unrepresentable: "any",
|
|
@@ -2259,7 +2259,7 @@ function toJsonSchema(schema) {
|
|
|
2259
2259
|
return result;
|
|
2260
2260
|
}
|
|
2261
2261
|
|
|
2262
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
2262
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Mcp.js
|
|
2263
2263
|
async function serve(name, version, commands, options = {}) {
|
|
2264
2264
|
const stdio = importStdioModule();
|
|
2265
2265
|
const mcp = await import("./dist-2MZJLO2W.js");
|
|
@@ -2594,7 +2594,7 @@ function buildToolSchema(args, options) {
|
|
|
2594
2594
|
return { type: "object", properties };
|
|
2595
2595
|
}
|
|
2596
2596
|
|
|
2597
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
2597
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Openapi.js
|
|
2598
2598
|
var Openapi_exports = {};
|
|
2599
2599
|
__export(Openapi_exports, {
|
|
2600
2600
|
coerceIfNeeded: () => coerceIfNeeded,
|
|
@@ -2604,7 +2604,7 @@ __export(Openapi_exports, {
|
|
|
2604
2604
|
toZod: () => toZod
|
|
2605
2605
|
});
|
|
2606
2606
|
|
|
2607
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
2607
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/internal/dereference.js
|
|
2608
2608
|
function dereference(root) {
|
|
2609
2609
|
const cache = /* @__PURE__ */ new Map();
|
|
2610
2610
|
return walk2(root, root, cache);
|
|
@@ -2656,7 +2656,7 @@ function resolvePointer(root, pointer) {
|
|
|
2656
2656
|
return current;
|
|
2657
2657
|
}
|
|
2658
2658
|
|
|
2659
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
2659
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Openapi.js
|
|
2660
2660
|
function fromCli(cli2, options = {}) {
|
|
2661
2661
|
const commands = toCommands.get(cli2);
|
|
2662
2662
|
if (!commands)
|
|
@@ -3251,7 +3251,7 @@ function coerceIfNeeded(schema) {
|
|
|
3251
3251
|
return desc ? coerced.describe(desc) : coerced;
|
|
3252
3252
|
}
|
|
3253
3253
|
|
|
3254
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
3254
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/McpSource.js
|
|
3255
3255
|
var protocolVersion = "2025-06-18";
|
|
3256
3256
|
async function resolve2(source, options = {}) {
|
|
3257
3257
|
const session = sourceSession(source);
|
|
@@ -3418,7 +3418,7 @@ function resultValue(result) {
|
|
|
3418
3418
|
return textItems;
|
|
3419
3419
|
}
|
|
3420
3420
|
|
|
3421
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
3421
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Skill.js
|
|
3422
3422
|
import { createHash } from "crypto";
|
|
3423
3423
|
function index(name, commands, description) {
|
|
3424
3424
|
const lines = [`# ${name}`];
|
|
@@ -3662,7 +3662,7 @@ function resolveTypeName2(prop) {
|
|
|
3662
3662
|
return "unknown";
|
|
3663
3663
|
}
|
|
3664
3664
|
|
|
3665
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
3665
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/SyncMcp.js
|
|
3666
3666
|
import { execFile } from "child_process";
|
|
3667
3667
|
import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "fs";
|
|
3668
3668
|
import { homedir } from "os";
|
|
@@ -3847,13 +3847,13 @@ function exec(cmd, args) {
|
|
|
3847
3847
|
});
|
|
3848
3848
|
}
|
|
3849
3849
|
|
|
3850
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
3850
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/SyncSkills.js
|
|
3851
3851
|
import fsSync from "fs";
|
|
3852
3852
|
import fs2 from "fs/promises";
|
|
3853
3853
|
import os2 from "os";
|
|
3854
3854
|
import path2 from "path";
|
|
3855
3855
|
|
|
3856
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
3856
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/internal/agents.js
|
|
3857
3857
|
import * as fs from "fs";
|
|
3858
3858
|
import * as os from "os";
|
|
3859
3859
|
import * as path from "path";
|
|
@@ -4133,7 +4133,7 @@ function resolveParent(dir) {
|
|
|
4133
4133
|
}
|
|
4134
4134
|
}
|
|
4135
4135
|
|
|
4136
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
4136
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/SyncSkills.js
|
|
4137
4137
|
async function sync(name, commands, options = {}) {
|
|
4138
4138
|
const { depth = 1, description, global = true } = options;
|
|
4139
4139
|
const cwd = options.cwd ?? (global ? resolvePackageRoot() : process.cwd());
|
|
@@ -4146,13 +4146,17 @@ async function sync(name, commands, options = {}) {
|
|
|
4146
4146
|
const tmpDir = await fs2.mkdtemp(path2.join(os2.tmpdir(), `incur-skills-${name}-`));
|
|
4147
4147
|
try {
|
|
4148
4148
|
const skills = [];
|
|
4149
|
+
const generatedDirs = /* @__PURE__ */ new Map();
|
|
4149
4150
|
for (const file of files) {
|
|
4150
4151
|
const filePath = file.dir ? path2.join(tmpDir, file.dir, "SKILL.md") : path2.join(tmpDir, "SKILL.md");
|
|
4151
4152
|
await fs2.mkdir(path2.dirname(filePath), { recursive: true });
|
|
4152
4153
|
await fs2.writeFile(filePath, `${file.content}
|
|
4153
4154
|
`);
|
|
4154
4155
|
const meta = parseSkillFrontmatter(file.content);
|
|
4155
|
-
|
|
4156
|
+
const skillName = meta.name ?? (file.dir || name);
|
|
4157
|
+
skills.push({ name: skillName, description: meta.description });
|
|
4158
|
+
if (file.dir)
|
|
4159
|
+
generatedDirs.set(skillName, file.dir);
|
|
4156
4160
|
}
|
|
4157
4161
|
if (options.include) {
|
|
4158
4162
|
for (const pattern of options.include) {
|
|
@@ -4165,7 +4169,14 @@ async function sync(name, commands, options = {}) {
|
|
|
4165
4169
|
const dest = path2.join(tmpDir, skillName, "SKILL.md");
|
|
4166
4170
|
await fs2.mkdir(path2.dirname(dest), { recursive: true });
|
|
4167
4171
|
await fs2.writeFile(dest, content);
|
|
4168
|
-
|
|
4172
|
+
const generatedDir = generatedDirs.get(meta.name ?? skillName);
|
|
4173
|
+
if (generatedDir && generatedDir !== skillName)
|
|
4174
|
+
await fs2.rm(path2.join(tmpDir, generatedDir), { recursive: true, force: true });
|
|
4175
|
+
const existing = skills.find((s) => s.name === skillName);
|
|
4176
|
+
if (existing) {
|
|
4177
|
+
existing.description = meta.description;
|
|
4178
|
+
existing.external = true;
|
|
4179
|
+
} else
|
|
4169
4180
|
skills.push({ name: skillName, description: meta.description, external: true });
|
|
4170
4181
|
} catch {
|
|
4171
4182
|
}
|
|
@@ -4294,7 +4305,7 @@ function readHash(name) {
|
|
|
4294
4305
|
return readMeta(name)?.hash;
|
|
4295
4306
|
}
|
|
4296
4307
|
|
|
4297
|
-
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+
|
|
4308
|
+
// ../../node_modules/.pnpm/incur@https+++codeload.github.com+whopio+incur+tar.gz+585b28b5317c8b5aeb58acb034bea04ed4adc067/node_modules/incur/dist/Cli.js
|
|
4298
4309
|
var destructiveCommandHint = "Confirm with the user before executing this destructive command.";
|
|
4299
4310
|
function create(nameOrDefinition, definition) {
|
|
4300
4311
|
const name = typeof nameOrDefinition === "string" ? nameOrDefinition : nameOrDefinition.name;
|
|
@@ -16421,13 +16432,13 @@ var native_spec_default = {
|
|
|
16421
16432
|
},
|
|
16422
16433
|
"/events": {
|
|
16423
16434
|
get: {
|
|
16424
|
-
description: "Lists
|
|
16435
|
+
description: "Lists identity-linked events, most recent first. Pass identifier for one person's journey, or omit it to list events for an account within an explicit time range. Events are shaped like the POST /events intake: attribution in context, identity in user.",
|
|
16425
16436
|
operationId: "list",
|
|
16426
16437
|
parameters: [
|
|
16427
16438
|
{
|
|
16428
|
-
description: "
|
|
16439
|
+
description: "Any hard identifier of the person: a person ID (prsn_*), user ID, email, phone number, or a tracking cookie value (wuid, anonymous ID, fbp/fbc/ttp/ga). Omit to list recent events for the account.",
|
|
16429
16440
|
in: "query",
|
|
16430
|
-
name: "
|
|
16441
|
+
name: "identifier",
|
|
16431
16442
|
required: false,
|
|
16432
16443
|
schema: {
|
|
16433
16444
|
type: "string"
|
|
@@ -16443,7 +16454,7 @@ var native_spec_default = {
|
|
|
16443
16454
|
}
|
|
16444
16455
|
},
|
|
16445
16456
|
{
|
|
16446
|
-
description: "Start of the time range as an ISO 8601 timestamp. Required when
|
|
16457
|
+
description: "Start of the time range as an ISO 8601 timestamp. Required when identifier is omitted.",
|
|
16447
16458
|
in: "query",
|
|
16448
16459
|
name: "from",
|
|
16449
16460
|
required: false,
|
|
@@ -16453,7 +16464,7 @@ var native_spec_default = {
|
|
|
16453
16464
|
}
|
|
16454
16465
|
},
|
|
16455
16466
|
{
|
|
16456
|
-
description: "End of the time range as an ISO 8601 timestamp. Required when
|
|
16467
|
+
description: "End of the time range as an ISO 8601 timestamp. Required when identifier is omitted; otherwise defaults to now.",
|
|
16457
16468
|
in: "query",
|
|
16458
16469
|
name: "to",
|
|
16459
16470
|
required: false,
|
|
@@ -16645,6 +16656,195 @@ var native_spec_default = {
|
|
|
16645
16656
|
"null"
|
|
16646
16657
|
]
|
|
16647
16658
|
},
|
|
16659
|
+
related: {
|
|
16660
|
+
description: "Hydrated details for the records this event references. Only present keys resolved.",
|
|
16661
|
+
properties: {
|
|
16662
|
+
account: {
|
|
16663
|
+
properties: {
|
|
16664
|
+
id: {
|
|
16665
|
+
type: "string"
|
|
16666
|
+
},
|
|
16667
|
+
logo_url: {
|
|
16668
|
+
type: [
|
|
16669
|
+
"string",
|
|
16670
|
+
"null"
|
|
16671
|
+
]
|
|
16672
|
+
},
|
|
16673
|
+
route: {
|
|
16674
|
+
type: [
|
|
16675
|
+
"string",
|
|
16676
|
+
"null"
|
|
16677
|
+
]
|
|
16678
|
+
},
|
|
16679
|
+
title: {
|
|
16680
|
+
type: [
|
|
16681
|
+
"string",
|
|
16682
|
+
"null"
|
|
16683
|
+
]
|
|
16684
|
+
}
|
|
16685
|
+
},
|
|
16686
|
+
type: [
|
|
16687
|
+
"object",
|
|
16688
|
+
"null"
|
|
16689
|
+
]
|
|
16690
|
+
},
|
|
16691
|
+
app: {
|
|
16692
|
+
properties: {
|
|
16693
|
+
domain_id: {
|
|
16694
|
+
type: [
|
|
16695
|
+
"string",
|
|
16696
|
+
"null"
|
|
16697
|
+
]
|
|
16698
|
+
},
|
|
16699
|
+
icon_url: {
|
|
16700
|
+
type: [
|
|
16701
|
+
"string",
|
|
16702
|
+
"null"
|
|
16703
|
+
]
|
|
16704
|
+
},
|
|
16705
|
+
id: {
|
|
16706
|
+
type: "string"
|
|
16707
|
+
},
|
|
16708
|
+
title: {
|
|
16709
|
+
type: [
|
|
16710
|
+
"string",
|
|
16711
|
+
"null"
|
|
16712
|
+
]
|
|
16713
|
+
}
|
|
16714
|
+
},
|
|
16715
|
+
type: [
|
|
16716
|
+
"object",
|
|
16717
|
+
"null"
|
|
16718
|
+
]
|
|
16719
|
+
},
|
|
16720
|
+
payment: {
|
|
16721
|
+
properties: {
|
|
16722
|
+
card_brand: {
|
|
16723
|
+
type: [
|
|
16724
|
+
"string",
|
|
16725
|
+
"null"
|
|
16726
|
+
]
|
|
16727
|
+
},
|
|
16728
|
+
card_last4: {
|
|
16729
|
+
type: [
|
|
16730
|
+
"string",
|
|
16731
|
+
"null"
|
|
16732
|
+
]
|
|
16733
|
+
},
|
|
16734
|
+
id: {
|
|
16735
|
+
type: "string"
|
|
16736
|
+
},
|
|
16737
|
+
provider: {
|
|
16738
|
+
type: [
|
|
16739
|
+
"string",
|
|
16740
|
+
"null"
|
|
16741
|
+
]
|
|
16742
|
+
}
|
|
16743
|
+
},
|
|
16744
|
+
type: [
|
|
16745
|
+
"object",
|
|
16746
|
+
"null"
|
|
16747
|
+
]
|
|
16748
|
+
},
|
|
16749
|
+
plan: {
|
|
16750
|
+
properties: {
|
|
16751
|
+
billing_period: {
|
|
16752
|
+
type: [
|
|
16753
|
+
"integer",
|
|
16754
|
+
"null"
|
|
16755
|
+
]
|
|
16756
|
+
},
|
|
16757
|
+
currency: {
|
|
16758
|
+
type: [
|
|
16759
|
+
"string",
|
|
16760
|
+
"null"
|
|
16761
|
+
]
|
|
16762
|
+
},
|
|
16763
|
+
id: {
|
|
16764
|
+
type: "string"
|
|
16765
|
+
},
|
|
16766
|
+
initial_price: {
|
|
16767
|
+
type: [
|
|
16768
|
+
"number",
|
|
16769
|
+
"null"
|
|
16770
|
+
]
|
|
16771
|
+
},
|
|
16772
|
+
renewal_price: {
|
|
16773
|
+
type: [
|
|
16774
|
+
"number",
|
|
16775
|
+
"null"
|
|
16776
|
+
]
|
|
16777
|
+
},
|
|
16778
|
+
title: {
|
|
16779
|
+
type: [
|
|
16780
|
+
"string",
|
|
16781
|
+
"null"
|
|
16782
|
+
]
|
|
16783
|
+
}
|
|
16784
|
+
},
|
|
16785
|
+
type: [
|
|
16786
|
+
"object",
|
|
16787
|
+
"null"
|
|
16788
|
+
]
|
|
16789
|
+
},
|
|
16790
|
+
product: {
|
|
16791
|
+
properties: {
|
|
16792
|
+
id: {
|
|
16793
|
+
type: "string"
|
|
16794
|
+
},
|
|
16795
|
+
route: {
|
|
16796
|
+
type: [
|
|
16797
|
+
"string",
|
|
16798
|
+
"null"
|
|
16799
|
+
]
|
|
16800
|
+
},
|
|
16801
|
+
title: {
|
|
16802
|
+
type: [
|
|
16803
|
+
"string",
|
|
16804
|
+
"null"
|
|
16805
|
+
]
|
|
16806
|
+
}
|
|
16807
|
+
},
|
|
16808
|
+
type: [
|
|
16809
|
+
"object",
|
|
16810
|
+
"null"
|
|
16811
|
+
]
|
|
16812
|
+
},
|
|
16813
|
+
user: {
|
|
16814
|
+
properties: {
|
|
16815
|
+
avatar_url: {
|
|
16816
|
+
type: [
|
|
16817
|
+
"string",
|
|
16818
|
+
"null"
|
|
16819
|
+
]
|
|
16820
|
+
},
|
|
16821
|
+
id: {
|
|
16822
|
+
type: "string"
|
|
16823
|
+
},
|
|
16824
|
+
name: {
|
|
16825
|
+
type: [
|
|
16826
|
+
"string",
|
|
16827
|
+
"null"
|
|
16828
|
+
]
|
|
16829
|
+
},
|
|
16830
|
+
username: {
|
|
16831
|
+
type: [
|
|
16832
|
+
"string",
|
|
16833
|
+
"null"
|
|
16834
|
+
]
|
|
16835
|
+
}
|
|
16836
|
+
},
|
|
16837
|
+
type: [
|
|
16838
|
+
"object",
|
|
16839
|
+
"null"
|
|
16840
|
+
]
|
|
16841
|
+
}
|
|
16842
|
+
},
|
|
16843
|
+
type: [
|
|
16844
|
+
"object",
|
|
16845
|
+
"null"
|
|
16846
|
+
]
|
|
16847
|
+
},
|
|
16648
16848
|
total_usd_amount: {
|
|
16649
16849
|
type: [
|
|
16650
16850
|
"number",
|
|
@@ -16700,12 +16900,6 @@ var native_spec_default = {
|
|
|
16700
16900
|
"string",
|
|
16701
16901
|
"null"
|
|
16702
16902
|
]
|
|
16703
|
-
},
|
|
16704
|
-
state: {
|
|
16705
|
-
type: [
|
|
16706
|
-
"string",
|
|
16707
|
-
"null"
|
|
16708
|
-
]
|
|
16709
16903
|
}
|
|
16710
16904
|
},
|
|
16711
16905
|
type: [
|
|
@@ -20493,10 +20687,6 @@ var native_spec_default = {
|
|
|
20493
20687
|
description: "The payout currency. Defaults to usd.",
|
|
20494
20688
|
type: "string"
|
|
20495
20689
|
},
|
|
20496
|
-
idempotency_key: {
|
|
20497
|
-
description: "A client-generated key that makes retries safe. Retrying with the same key returns the original payout instead of creating a second one.",
|
|
20498
|
-
type: "string"
|
|
20499
|
-
},
|
|
20500
20690
|
payout_method_id: {
|
|
20501
20691
|
description: "The saved payout method to deliver to (a potk_ identifier).",
|
|
20502
20692
|
type: "string"
|
|
@@ -30526,6 +30716,13 @@ var native_spec_default = {
|
|
|
30526
30716
|
"null"
|
|
30527
30717
|
]
|
|
30528
30718
|
},
|
|
30719
|
+
cost_per_unique_click: {
|
|
30720
|
+
description: "Spend divided by unique clicks; null when there are no unique clicks.",
|
|
30721
|
+
type: [
|
|
30722
|
+
"number",
|
|
30723
|
+
"null"
|
|
30724
|
+
]
|
|
30725
|
+
},
|
|
30529
30726
|
cost_per_viewed_content: {
|
|
30530
30727
|
description: "Spend divided by attributed view-content events; null when they are not the goal and none are attributed.",
|
|
30531
30728
|
type: [
|
|
@@ -30795,7 +30992,7 @@ var native_spec_default = {
|
|
|
30795
30992
|
]
|
|
30796
30993
|
},
|
|
30797
30994
|
unique_clicks: {
|
|
30798
|
-
description: "
|
|
30995
|
+
description: "People who clicked, reported by the Whop pixel, counted once per person.",
|
|
30799
30996
|
type: "number"
|
|
30800
30997
|
},
|
|
30801
30998
|
updated_at: {
|
|
@@ -30826,6 +31023,7 @@ var native_spec_default = {
|
|
|
30826
31023
|
"click_through_rate",
|
|
30827
31024
|
"clicks",
|
|
30828
31025
|
"cost_per_click",
|
|
31026
|
+
"cost_per_unique_click",
|
|
30829
31027
|
"cost_per_lead",
|
|
30830
31028
|
"cost_per_mille",
|
|
30831
31029
|
"cost_per_purchase",
|
|
@@ -31038,6 +31236,13 @@ var native_spec_default = {
|
|
|
31038
31236
|
"null"
|
|
31039
31237
|
]
|
|
31040
31238
|
},
|
|
31239
|
+
cost_per_unique_click: {
|
|
31240
|
+
description: "Spend divided by unique clicks; null when there are no unique clicks.",
|
|
31241
|
+
type: [
|
|
31242
|
+
"number",
|
|
31243
|
+
"null"
|
|
31244
|
+
]
|
|
31245
|
+
},
|
|
31041
31246
|
cost_per_viewed_content: {
|
|
31042
31247
|
description: "Spend divided by attributed view-content events; null when they are not the goal and none are attributed.",
|
|
31043
31248
|
type: [
|
|
@@ -31262,7 +31467,7 @@ var native_spec_default = {
|
|
|
31262
31467
|
]
|
|
31263
31468
|
},
|
|
31264
31469
|
unique_clicks: {
|
|
31265
|
-
description: "
|
|
31470
|
+
description: "People who clicked, reported by the Whop pixel, counted once per person.",
|
|
31266
31471
|
type: "number"
|
|
31267
31472
|
},
|
|
31268
31473
|
updated_at: {
|
|
@@ -31282,6 +31487,7 @@ var native_spec_default = {
|
|
|
31282
31487
|
"click_through_rate",
|
|
31283
31488
|
"clicks",
|
|
31284
31489
|
"cost_per_click",
|
|
31490
|
+
"cost_per_unique_click",
|
|
31285
31491
|
"cost_per_lead",
|
|
31286
31492
|
"cost_per_mille",
|
|
31287
31493
|
"cost_per_purchase",
|
|
@@ -31595,6 +31801,13 @@ var native_spec_default = {
|
|
|
31595
31801
|
"null"
|
|
31596
31802
|
]
|
|
31597
31803
|
},
|
|
31804
|
+
cost_per_unique_click: {
|
|
31805
|
+
description: "Spend divided by unique clicks; null when there are no unique clicks.",
|
|
31806
|
+
type: [
|
|
31807
|
+
"number",
|
|
31808
|
+
"null"
|
|
31809
|
+
]
|
|
31810
|
+
},
|
|
31598
31811
|
cost_per_viewed_content: {
|
|
31599
31812
|
description: "Spend divided by attributed view-content events; null when they are not the goal and none are attributed.",
|
|
31600
31813
|
type: [
|
|
@@ -31886,7 +32099,7 @@ var native_spec_default = {
|
|
|
31886
32099
|
]
|
|
31887
32100
|
},
|
|
31888
32101
|
unique_clicks: {
|
|
31889
|
-
description: "
|
|
32102
|
+
description: "People who clicked, reported by the Whop pixel, counted once per person.",
|
|
31890
32103
|
type: "number"
|
|
31891
32104
|
},
|
|
31892
32105
|
updated_at: {
|
|
@@ -31906,6 +32119,7 @@ var native_spec_default = {
|
|
|
31906
32119
|
"click_through_rate",
|
|
31907
32120
|
"clicks",
|
|
31908
32121
|
"cost_per_click",
|
|
32122
|
+
"cost_per_unique_click",
|
|
31909
32123
|
"cost_per_lead",
|
|
31910
32124
|
"cost_per_mille",
|
|
31911
32125
|
"cost_per_purchase",
|
|
@@ -42155,7 +42369,13 @@ function openBrowser(url) {
|
|
|
42155
42369
|
if (process.platform === "darwin") {
|
|
42156
42370
|
execFile2("open", [url], ignore);
|
|
42157
42371
|
} else if (process.platform === "win32") {
|
|
42158
|
-
|
|
42372
|
+
const escaped = url.replace(/[&|<>^]/g, "^$&");
|
|
42373
|
+
execFile2(
|
|
42374
|
+
"cmd.exe",
|
|
42375
|
+
["/d", "/s", "/c", "start", '""', escaped],
|
|
42376
|
+
{ windowsVerbatimArguments: true },
|
|
42377
|
+
ignore
|
|
42378
|
+
);
|
|
42159
42379
|
} else {
|
|
42160
42380
|
execFile2("xdg-open", [url], ignore);
|
|
42161
42381
|
}
|
|
@@ -42223,7 +42443,7 @@ import { Whop } from "@whop/sdk";
|
|
|
42223
42443
|
// package.json
|
|
42224
42444
|
var package_default = {
|
|
42225
42445
|
name: "@whop/cli",
|
|
42226
|
-
version: "0.
|
|
42446
|
+
version: "0.13.0",
|
|
42227
42447
|
description: "The Whop CLI \u2014 build and manage Whop apps from your terminal. Human and agent friendly.",
|
|
42228
42448
|
keywords: [
|
|
42229
42449
|
"agent",
|
|
@@ -42282,7 +42502,7 @@ var package_default = {
|
|
|
42282
42502
|
devDependencies: {
|
|
42283
42503
|
"@types/node": "25.3.5",
|
|
42284
42504
|
fflate: "0.8.2",
|
|
42285
|
-
incur: "github:whopio/incur#
|
|
42505
|
+
incur: "github:whopio/incur#585b28b5317c8b5aeb58acb034bea04ed4adc067",
|
|
42286
42506
|
tsup: "8.5.0",
|
|
42287
42507
|
tsx: "4.19.4",
|
|
42288
42508
|
typescript: "5.9.3",
|
|
@@ -42426,11 +42646,23 @@ function writeConfig(config, env = process.env) {
|
|
|
42426
42646
|
import fs5 from "fs";
|
|
42427
42647
|
import path5 from "path";
|
|
42428
42648
|
import { createRequire as createRequire2 } from "module";
|
|
42649
|
+
import { execFileSync } from "child_process";
|
|
42650
|
+
import {
|
|
42651
|
+
createCipheriv,
|
|
42652
|
+
createDecipheriv,
|
|
42653
|
+
hkdfSync,
|
|
42654
|
+
randomBytes
|
|
42655
|
+
} from "crypto";
|
|
42656
|
+
|
|
42657
|
+
// src/lib/npx.ts
|
|
42658
|
+
function isNpx(selfUrl = import.meta.url) {
|
|
42659
|
+
return selfUrl.includes("/_npx/");
|
|
42660
|
+
}
|
|
42429
42661
|
|
|
42430
42662
|
// src/lib/build-info.ts
|
|
42431
42663
|
var buildChannel = true ? "npm" : "dev";
|
|
42432
42664
|
var buildTarget = typeof WHOP_CLI_TARGET === "string" ? WHOP_CLI_TARGET : null;
|
|
42433
|
-
var buildVersion = true ? "0.
|
|
42665
|
+
var buildVersion = true ? "0.13.0" : null;
|
|
42434
42666
|
function isHomebrewPath(execPath, env = process.env) {
|
|
42435
42667
|
if (/[/\\](Cellar|homebrew|linuxbrew)[/\\]/.test(execPath)) return true;
|
|
42436
42668
|
const prefix = env.HOMEBREW_PREFIX?.trim();
|
|
@@ -42446,6 +42678,7 @@ function detectChannel(env = process.env, execPath = process.execPath) {
|
|
|
42446
42678
|
|
|
42447
42679
|
// src/auth/secret-store.ts
|
|
42448
42680
|
var SERVICE = "whop-cli";
|
|
42681
|
+
var KEY_PEPPER = "whop-cli/secret-store/v3";
|
|
42449
42682
|
var keyringModule;
|
|
42450
42683
|
function loadKeyring() {
|
|
42451
42684
|
if (keyringModule === void 0) {
|
|
@@ -42487,37 +42720,135 @@ var keyringStore = {
|
|
|
42487
42720
|
}
|
|
42488
42721
|
}
|
|
42489
42722
|
};
|
|
42723
|
+
var cachedMachineId;
|
|
42724
|
+
function machineId(env) {
|
|
42725
|
+
const override = env.WHOP_CLI_MACHINE_ID?.trim();
|
|
42726
|
+
if (override) return override;
|
|
42727
|
+
if (cachedMachineId !== void 0) return cachedMachineId;
|
|
42728
|
+
cachedMachineId = detectMachineId();
|
|
42729
|
+
return cachedMachineId;
|
|
42730
|
+
}
|
|
42731
|
+
function detectMachineId() {
|
|
42732
|
+
try {
|
|
42733
|
+
if (process.platform === "darwin") {
|
|
42734
|
+
const out = execFileSync(
|
|
42735
|
+
"ioreg",
|
|
42736
|
+
["-rd1", "-c", "IOPlatformExpertDevice"],
|
|
42737
|
+
{ encoding: "utf8" }
|
|
42738
|
+
);
|
|
42739
|
+
return /"IOPlatformUUID"\s*=\s*"([^"]+)"/.exec(out)?.[1] ?? "";
|
|
42740
|
+
}
|
|
42741
|
+
if (process.platform === "linux") {
|
|
42742
|
+
for (const file of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
|
|
42743
|
+
try {
|
|
42744
|
+
const id = fs5.readFileSync(file, "utf8").trim();
|
|
42745
|
+
if (id) return id;
|
|
42746
|
+
} catch {
|
|
42747
|
+
}
|
|
42748
|
+
}
|
|
42749
|
+
return "";
|
|
42750
|
+
}
|
|
42751
|
+
if (process.platform === "win32") {
|
|
42752
|
+
const out = execFileSync(
|
|
42753
|
+
"reg",
|
|
42754
|
+
[
|
|
42755
|
+
"query",
|
|
42756
|
+
"HKLM\\SOFTWARE\\Microsoft\\Cryptography",
|
|
42757
|
+
"/v",
|
|
42758
|
+
"MachineGuid"
|
|
42759
|
+
],
|
|
42760
|
+
{ encoding: "utf8" }
|
|
42761
|
+
);
|
|
42762
|
+
return /MachineGuid\s+REG_SZ\s+([\w-]+)/.exec(out)?.[1] ?? "";
|
|
42763
|
+
}
|
|
42764
|
+
} catch {
|
|
42765
|
+
}
|
|
42766
|
+
return "";
|
|
42767
|
+
}
|
|
42768
|
+
function deriveKey(machine, salt) {
|
|
42769
|
+
const ikm = machine || "whop-cli/no-machine-id";
|
|
42770
|
+
return Buffer.from(hkdfSync("sha256", ikm, salt, KEY_PEPPER, 32));
|
|
42771
|
+
}
|
|
42772
|
+
function encryptValue(plaintext, machine) {
|
|
42773
|
+
const salt = randomBytes(16);
|
|
42774
|
+
const iv = randomBytes(12);
|
|
42775
|
+
const cipher = createCipheriv("aes-256-gcm", deriveKey(machine, salt), iv);
|
|
42776
|
+
const ciphertext = Buffer.concat([
|
|
42777
|
+
cipher.update(Buffer.from(plaintext, "utf8")),
|
|
42778
|
+
cipher.final()
|
|
42779
|
+
]);
|
|
42780
|
+
const payload = Buffer.concat([iv, ciphertext, cipher.getAuthTag()]);
|
|
42781
|
+
return `${salt.toString("base64")}-${payload.toString("base64")}`;
|
|
42782
|
+
}
|
|
42783
|
+
function decryptValue(stored, machine) {
|
|
42784
|
+
const dash = stored.indexOf("-");
|
|
42785
|
+
if (dash < 0) return null;
|
|
42786
|
+
const salt = Buffer.from(stored.slice(0, dash), "base64");
|
|
42787
|
+
const payload = Buffer.from(stored.slice(dash + 1), "base64");
|
|
42788
|
+
if (payload.length < 12 + 16) return null;
|
|
42789
|
+
const iv = payload.subarray(0, 12);
|
|
42790
|
+
const tag = payload.subarray(payload.length - 16);
|
|
42791
|
+
const ciphertext = payload.subarray(12, payload.length - 16);
|
|
42792
|
+
try {
|
|
42793
|
+
const decipher = createDecipheriv("aes-256-gcm", deriveKey(machine, salt), iv);
|
|
42794
|
+
decipher.setAuthTag(tag);
|
|
42795
|
+
return Buffer.concat([
|
|
42796
|
+
decipher.update(ciphertext),
|
|
42797
|
+
decipher.final()
|
|
42798
|
+
]).toString("utf8");
|
|
42799
|
+
} catch {
|
|
42800
|
+
return null;
|
|
42801
|
+
}
|
|
42802
|
+
}
|
|
42490
42803
|
function credentialsPath(env) {
|
|
42491
42804
|
return path5.join(configDir(env), "credentials.json");
|
|
42492
42805
|
}
|
|
42493
|
-
function
|
|
42806
|
+
function sanitizeStringMap(value) {
|
|
42807
|
+
if (value == null || typeof value !== "object" || Array.isArray(value)) {
|
|
42808
|
+
return {};
|
|
42809
|
+
}
|
|
42810
|
+
const out = {};
|
|
42811
|
+
for (const [key, val] of Object.entries(value)) {
|
|
42812
|
+
if (typeof val === "string") out[key] = val;
|
|
42813
|
+
}
|
|
42814
|
+
return out;
|
|
42815
|
+
}
|
|
42816
|
+
function readStoredFile(env) {
|
|
42494
42817
|
let raw;
|
|
42495
42818
|
try {
|
|
42496
42819
|
raw = fs5.readFileSync(credentialsPath(env), "utf8");
|
|
42497
42820
|
} catch {
|
|
42498
|
-
return {};
|
|
42821
|
+
return { legacy: false, secrets: {} };
|
|
42499
42822
|
}
|
|
42823
|
+
let parsed;
|
|
42500
42824
|
try {
|
|
42501
|
-
|
|
42502
|
-
if (parsed != null && typeof parsed === "object" && parsed.secrets != null && typeof parsed.secrets === "object" && !Array.isArray(parsed.secrets)) {
|
|
42503
|
-
const secrets = {};
|
|
42504
|
-
for (const [key, value] of Object.entries(parsed.secrets)) {
|
|
42505
|
-
if (typeof value === "string") secrets[key] = value;
|
|
42506
|
-
}
|
|
42507
|
-
return secrets;
|
|
42508
|
-
}
|
|
42825
|
+
parsed = JSON.parse(raw);
|
|
42509
42826
|
} catch {
|
|
42827
|
+
return { legacy: false, secrets: {} };
|
|
42510
42828
|
}
|
|
42511
|
-
|
|
42829
|
+
if (parsed == null || typeof parsed !== "object") {
|
|
42830
|
+
return { legacy: false, secrets: {} };
|
|
42831
|
+
}
|
|
42832
|
+
const obj = parsed;
|
|
42833
|
+
return { legacy: obj.version !== 3, secrets: sanitizeStringMap(obj.secrets) };
|
|
42834
|
+
}
|
|
42835
|
+
function toCiphertextMap(stored, env) {
|
|
42836
|
+
if (!stored.legacy) return { ...stored.secrets };
|
|
42837
|
+
const machine = machineId(env);
|
|
42838
|
+
const encrypted = {};
|
|
42839
|
+
for (const [name, value] of Object.entries(stored.secrets)) {
|
|
42840
|
+
encrypted[name] = encryptValue(value, machine);
|
|
42841
|
+
}
|
|
42842
|
+
return encrypted;
|
|
42512
42843
|
}
|
|
42513
|
-
function
|
|
42844
|
+
function writeStoredFile(secrets, env) {
|
|
42514
42845
|
const dir = configDir(env);
|
|
42515
42846
|
fs5.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
42516
42847
|
const file = credentialsPath(env);
|
|
42517
42848
|
const tmp = `${file}.${process.pid}.tmp`;
|
|
42518
42849
|
fs5.writeFileSync(
|
|
42519
42850
|
tmp,
|
|
42520
|
-
`${JSON.stringify({ version:
|
|
42851
|
+
`${JSON.stringify({ version: 3, secrets }, null, 2)}
|
|
42521
42852
|
`,
|
|
42522
42853
|
{ mode: 384 }
|
|
42523
42854
|
);
|
|
@@ -42530,56 +42861,91 @@ function writeCredentials(secrets, env) {
|
|
|
42530
42861
|
function fileStore(env) {
|
|
42531
42862
|
return {
|
|
42532
42863
|
set(name, secret) {
|
|
42533
|
-
const secrets =
|
|
42534
|
-
secrets[name] = secret;
|
|
42535
|
-
|
|
42864
|
+
const secrets = toCiphertextMap(readStoredFile(env), env);
|
|
42865
|
+
secrets[name] = encryptValue(secret, machineId(env));
|
|
42866
|
+
writeStoredFile(secrets, env);
|
|
42536
42867
|
return true;
|
|
42537
42868
|
},
|
|
42538
42869
|
get(name) {
|
|
42539
|
-
|
|
42870
|
+
const stored = readStoredFile(env);
|
|
42871
|
+
const value = stored.secrets[name];
|
|
42872
|
+
if (value == null) return null;
|
|
42873
|
+
return stored.legacy ? value : decryptValue(value, machineId(env));
|
|
42540
42874
|
},
|
|
42541
42875
|
delete(name) {
|
|
42542
42876
|
if (!fs5.existsSync(credentialsPath(env))) return;
|
|
42543
|
-
const secrets =
|
|
42877
|
+
const secrets = toCiphertextMap(readStoredFile(env), env);
|
|
42544
42878
|
delete secrets[name];
|
|
42545
|
-
|
|
42879
|
+
writeStoredFile(secrets, env);
|
|
42546
42880
|
}
|
|
42547
42881
|
};
|
|
42548
42882
|
}
|
|
42549
|
-
function
|
|
42883
|
+
function resolveStoreKinds(policy) {
|
|
42884
|
+
if (policy.forced === "keyring") return ["keyring"];
|
|
42885
|
+
if (policy.forced === "file") return ["file"];
|
|
42886
|
+
if (policy.isStandaloneBinary) return ["file"];
|
|
42887
|
+
if (policy.platform === "darwin" && policy.isNpx) return ["file"];
|
|
42888
|
+
return ["keyring", "file"];
|
|
42889
|
+
}
|
|
42890
|
+
function storeFor(kind, env) {
|
|
42891
|
+
return kind === "keyring" ? keyringStore : fileStore(env);
|
|
42892
|
+
}
|
|
42893
|
+
function storeKindsFor(env) {
|
|
42894
|
+
return resolveStoreKinds({
|
|
42895
|
+
platform: process.platform,
|
|
42896
|
+
isStandaloneBinary: buildTarget != null,
|
|
42897
|
+
isNpx: isNpx(),
|
|
42898
|
+
forced: env.WHOP_CLI_SECRET_STORE?.trim()
|
|
42899
|
+
});
|
|
42900
|
+
}
|
|
42901
|
+
function cleanupKindsFor(env) {
|
|
42550
42902
|
const forced = env.WHOP_CLI_SECRET_STORE?.trim();
|
|
42551
|
-
if (forced === "file") return [
|
|
42552
|
-
if (forced === "keyring") return [
|
|
42553
|
-
|
|
42554
|
-
|
|
42903
|
+
if (forced === "file") return ["file"];
|
|
42904
|
+
if (forced === "keyring") return ["keyring"];
|
|
42905
|
+
return ["keyring", "file"];
|
|
42906
|
+
}
|
|
42907
|
+
var secretCache = /* @__PURE__ */ new Map();
|
|
42908
|
+
function cacheKey(name, env) {
|
|
42909
|
+
return `${storeKindsFor(env)[0]} ${configDir(env)} ${name}`;
|
|
42555
42910
|
}
|
|
42556
42911
|
function setSecret(name, secret, env = process.env) {
|
|
42557
|
-
const
|
|
42558
|
-
|
|
42912
|
+
const winner = storeKindsFor(env).find(
|
|
42913
|
+
(kind) => storeFor(kind, env).set(name, secret)
|
|
42914
|
+
);
|
|
42559
42915
|
if (!winner) {
|
|
42560
42916
|
throw new Error(
|
|
42561
|
-
"WHOP_CLI_SECRET_STORE=keyring but the OS
|
|
42917
|
+
"WHOP_CLI_SECRET_STORE=keyring but the OS keystore is unavailable"
|
|
42562
42918
|
);
|
|
42563
42919
|
}
|
|
42564
|
-
for (const
|
|
42565
|
-
if (
|
|
42920
|
+
for (const kind of cleanupKindsFor(env)) {
|
|
42921
|
+
if (kind !== winner) storeFor(kind, env).delete(name);
|
|
42566
42922
|
}
|
|
42923
|
+
secretCache.set(cacheKey(name, env), secret);
|
|
42567
42924
|
}
|
|
42568
42925
|
function getSecret(name, env = process.env) {
|
|
42569
|
-
|
|
42570
|
-
|
|
42571
|
-
|
|
42926
|
+
const key = cacheKey(name, env);
|
|
42927
|
+
const cached2 = secretCache.get(key);
|
|
42928
|
+
if (cached2 !== void 0) return cached2;
|
|
42929
|
+
let result = null;
|
|
42930
|
+
for (const kind of storeKindsFor(env)) {
|
|
42931
|
+
const secret = storeFor(kind, env).get(name);
|
|
42932
|
+
if (secret != null) {
|
|
42933
|
+
result = secret;
|
|
42934
|
+
break;
|
|
42935
|
+
}
|
|
42572
42936
|
}
|
|
42573
|
-
|
|
42937
|
+
secretCache.set(key, result);
|
|
42938
|
+
return result;
|
|
42574
42939
|
}
|
|
42575
42940
|
function deleteSecret(name, env = process.env) {
|
|
42576
|
-
for (const
|
|
42577
|
-
|
|
42941
|
+
for (const kind of cleanupKindsFor(env)) {
|
|
42942
|
+
storeFor(kind, env).delete(name);
|
|
42578
42943
|
}
|
|
42944
|
+
secretCache.set(cacheKey(name, env), null);
|
|
42579
42945
|
}
|
|
42580
42946
|
|
|
42581
42947
|
// src/auth/oauth.ts
|
|
42582
|
-
import { createHash as createHash2, randomBytes } from "crypto";
|
|
42948
|
+
import { createHash as createHash2, randomBytes as randomBytes2 } from "crypto";
|
|
42583
42949
|
|
|
42584
42950
|
// src/auth/callback-server.ts
|
|
42585
42951
|
import { createServer } from "http";
|
|
@@ -43011,15 +43377,15 @@ var CLI_CLIENT_ID = "app_IoPWUwtO8c2gGA";
|
|
|
43011
43377
|
var CLI_REDIRECT_URI = "http://localhost:13337/callback";
|
|
43012
43378
|
var CLI_SCOPES = [...WHOP_SCOPES];
|
|
43013
43379
|
function generatePKCE() {
|
|
43014
|
-
const verifier =
|
|
43380
|
+
const verifier = randomBytes2(32).toString("base64url");
|
|
43015
43381
|
const challenge = createHash2("sha256").update(verifier).digest("base64url");
|
|
43016
43382
|
return { verifier, challenge };
|
|
43017
43383
|
}
|
|
43018
43384
|
function generateState() {
|
|
43019
|
-
return
|
|
43385
|
+
return randomBytes2(16).toString("base64url");
|
|
43020
43386
|
}
|
|
43021
43387
|
function generateNonce() {
|
|
43022
|
-
return
|
|
43388
|
+
return randomBytes2(16).toString("base64url");
|
|
43023
43389
|
}
|
|
43024
43390
|
async function requestToken(params) {
|
|
43025
43391
|
const res = await whopFetch(`${oauthBaseUrl()}/oauth/token`, {
|
|
@@ -48283,6 +48649,52 @@ function render(data) {
|
|
|
48283
48649
|
return null;
|
|
48284
48650
|
}
|
|
48285
48651
|
|
|
48652
|
+
// src/lib/shipped-skills.ts
|
|
48653
|
+
import { mkdirSync as mkdirSync5, mkdtempSync as mkdtempSync4, rmSync as rmSync5, writeFileSync as writeFileSync5 } from "fs";
|
|
48654
|
+
import { tmpdir as tmpdir4 } from "os";
|
|
48655
|
+
import { join as join11 } from "path";
|
|
48656
|
+
|
|
48657
|
+
// src/api/shipped-skills.json
|
|
48658
|
+
var shipped_skills_default = {
|
|
48659
|
+
"whop-accounts": '---\nname: whop-accounts\ndescription: "A business on Whop: profile, wallet, capabilities, settings. Run `whop accounts --help` for usage details."\nrequires_bin: whop\ncommand: whop accounts\n---\n\nAn Account represents a person or business on Whop that can have its own profile, wallet, and account-scoped settings. Use accounts for customers, creators, merchants, sellers, or connected businesses your integration supports.\n\nUse the Accounts API to create accounts, list accounts visible to your credentials, retrieve or update an account, and retrieve the account associated with the current API key.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop accounts list` | List Accounts |\n| `whop accounts create` | Create Account |\n| `whop accounts me` | Retrieve Requesting Account |\n| `whop accounts get` | Retrieve Account |\n| `whop accounts update` | Update Account |\n| `whop accounts llc` | Register LLC |\n| `whop accounts preferences` | Retrieve Account Preferences |\n| `whop accounts update-preferences` | Update Account Preferences |\n| `whop accounts recommend_actions` | List Recommended Actions |\n\nRun `whop accounts <command> --help` for options, or `whop accounts <command> --schema` for full argument details.\n',
|
|
48660
|
+
"whop-users": '---\nname: whop-users\ndescription: "A person on Whop: profile and connected identities. Run `whop users --help` for usage details."\nrequires_bin: whop\ncommand: whop users\n---\n\nA User represents a person on Whop. Users have a public profile and can buy products, join accounts, and access experiences.\n\nUse the Users API to search for users, retrieve or update profiles, and check whether a user has access to an account, product, or experience.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop users list` | List Users |\n| `whop users me` | Update Current User |\n| `whop users get` | Retrieve User |\n| `whop users update` | Update User |\n| `whop users access` | Check User Access |\n| `whop users recommend_actions` | List Recommended Actions |\n\nRun `whop users <command> --help` for options, or `whop users <command> --schema` for full argument details.\n',
|
|
48661
|
+
"whop-stats": "---\nname: whop-stats\ndescription: Aggregated financial, audience, and traffic reporting. Run `whop stats --help` for usage details.\nrequires_bin: whop\ncommand: whop stats\n---\n\nStats represent aggregated activity for an account over time. They help you understand revenue, transactions, disputes, members, referrals, and advertising performance across reporting periods like days, weeks, or months.\n\nUse the Stats API to list available metrics and their filterable properties, then retrieve time-series values for a date range.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop stats list` | List Metrics |\n| `whop stats get` | Retrieve Metric |\n\nRun `whop stats <command> --help` for options, or `whop stats <command> --schema` for full argument details.\n",
|
|
48662
|
+
"whop-ledgers": "---\nname: whop-ledgers\ndescription: The activity feed behind an account or user's balance. Run `whop ledgers --help` for usage details.\nrequires_bin: whop\ncommand: whop ledgers\n---\n\nA Ledger Activity row is a single financial event on an account's ledger \u2014 a payment, withdrawal, refund, transfer, on-chain deposit, swap, or card transaction. Each row is derived from the underlying ledger lines and carries a typed `resource` and `source` so you can present and link the event without extra lookups.\n\nUse Ledger Activity to build a statement or transaction feed for an account or user. Reconcile against your own records with `amount` (signed, in the currency's smallest precision units) and `posted_at`, and use `available_at` to know when inflows became withdrawable.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop ledgers list` | List Financial Activity |\n| `whop ledgers report` | Get Financial Report |\n\nRun `whop ledgers <command> --help` for options, or `whop ledgers <command> --schema` for full argument details.\n",
|
|
48663
|
+
"whop-payouts": "---\nname: whop-payouts\ndescription: Send money from a balance to a bank or wallet. Run `whop payouts --help` for usage details.\nrequires_bin: whop\ncommand: whop payouts\n---\n\nPayouts represent money sent from an account or user balance to an external destination, such as a bank account, wallet, or other saved payout method.\n\nUse the Payouts API to create payouts from stablecoin accounts, list payout history for accounts or users, monitor payout statuses, and show expected arrival details for funds leaving Whop.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop payouts list` | List Payouts |\n| `whop payouts create` | Create Payout |\n| `whop payouts methods` | List Payout Methods |\n| `whop payouts create-method` | Create Payout Method |\n\nRun `whop payouts <command> --help` for options, or `whop payouts <command> --schema` for full argument details.\n",
|
|
48664
|
+
"whop-cards": "---\nname: whop-cards\ndescription: Issue cards that spend from a balance. Run `whop cards --help` for usage details.\nrequires_bin: whop\ncommand: whop cards\n---\n\nCards represent Whop-issued virtual payment cards that spend from an account or user balance. Cards can be assigned to cardholders and configured with spending limits for controlled spending.\n\nUse the Cards API to issue cards, list cards for an account or user, and retrieve active card details such as the card number and CVC.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop cards list` | List Cards |\n| `whop cards create` | Create Card |\n| `whop cards get` | Retrieve Card |\n| `whop cards update` | Update Card |\n\nRun `whop cards <command> --help` for options, or `whop cards <command> --schema` for full argument details.\n",
|
|
48665
|
+
"whop-transfers": "---\nname: whop-transfers\ndescription: Move funds between Whop accounts and users. Run `whop transfers --help` for usage details.\nrequires_bin: whop\ncommand: whop transfers\n---\n\nTransfers move value between identities on Whop. They are used for account-to-account money movement, user payouts inside Whop, crypto transfers, and claim links depending on the destination type.\n\nUse the Transfers API to create a transfer, list previous transfers, and retrieve a transfer by ID when reconciling money movement between accounts or users.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop transfers list` | List Transfers |\n| `whop transfers create` | Create Transfer |\n| `whop transfers get` | Retrieve Transfer |\n\nRun `whop transfers <command> --help` for options, or `whop transfers <command> --schema` for full argument details.\n",
|
|
48666
|
+
"whop-deposits": "---\nname: whop-deposits\ndescription: Add funds to a balance. Run `whop deposits --help` for usage details.\nrequires_bin: whop\ncommand: whop deposits\n---\n\nDeposits describe ways to add funds to an account balance, including hosted deposit pages, bank deposit instructions, and supported crypto wallet addresses.\n\nUse the Deposits API to create deposit instructions for an account.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop deposits create` | Create Deposit |\n\nRun `whop deposits <command> --help` for options, or `whop deposits <command> --schema` for full argument details.\n",
|
|
48667
|
+
"whop-swaps": "---\nname: whop-swaps\ndescription: Convert a balance between currencies. Run `whop swaps --help` for usage details.\nrequires_bin: whop\ncommand: whop swaps\n---\n\nSwaps convert value between supported tokens, chains, or wallet destinations for an account. A swap quote describes the expected output, fees, and approval requirements before you create the swap.\n\nUse the Swaps API to quote a conversion, create the swap, list recent swaps, and retrieve status until the transaction completes.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop swaps status` | List Swaps |\n| `whop swaps create` | Create Swap |\n| `whop swaps quote` | Create Swap Quote |\n| `whop swaps get` | Retrieve Swap |\n\nRun `whop swaps <command> --help` for options, or `whop swaps <command> --schema` for full argument details.\n",
|
|
48668
|
+
"whop-verifications": "---\nname: whop-verifications\ndescription: Legal identity required before payouts and card issuing. Run `whop verifications --help` for usage details.\nrequires_bin: whop\ncommand: whop verifications\n---\n\nA Verification represents a legal identity for a person or business. Accounts and users complete verification when Whop needs to confirm who they are before enabling payouts or compliance-sensitive workflows.\n\nUse the Verifications API to start or resume a hosted verification session, check review status, and submit requested details or documents. If `requested_information` contains items, submit answers with [Update Verification](https://docs.whop.com/api-reference/beta/verifications/update-verification).\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop verifications list` | List Verifications |\n| `whop verifications create` | Create Verification |\n| `whop verifications get` | Retrieve Verification |\n| `whop verifications update` | Update Verification |\n\nRun `whop verifications <command> --help` for options, or `whop verifications <command> --schema` for full argument details.\n\n## Steps that finish in the browser\n\nSome commands respond with a URL the user must open in a browser to finish the flow (`authorize_url`, `session_url`, `deposit_url`) \u2014 the CLI cannot complete that step itself. When a response contains one of these fields, or the CLI prints \"Action required: open this link in the user's browser\", open that link in the user's browser for them, tell them what to complete there, then re-run the matching `get`/`list` command to confirm the step finished.\n",
|
|
48669
|
+
"whop-products": "---\nname: whop-products\ndescription: The things you sell. Each owns plans and a store page. Run `whop products --help` for usage details.\nrequires_bin: whop\ncommand: whop products\n---\n\nA Product is a digital good or service sold on Whop. Products may contain plans for pricing and/or experiences for content delivery.\n\nUse the Products API to create products, list products visible to your credentials, retrieve product details, update product metadata or merchandising fields, and delete products that should no longer be sold.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop products list` | List Products |\n| `whop products create` | Create Product |\n| `whop products delete` | Delete Product |\n| `whop products get` | Retrieve Product |\n| `whop products update` | Update Product |\n\nRun `whop products <command> --help` for options, or `whop products <command> --schema` for full argument details.\n",
|
|
48670
|
+
"whop-plans": '---\nname: whop-plans\ndescription: "Pricing for a product: one-time, recurring, trials, stock. Run `whop plans --help` for usage details."\nrequires_bin: whop\ncommand: whop plans\n---\n\nA Plan defines how customers buy a product. It controls pricing, billing cadence, availability, tax behavior, checkout fields, and purchase visibility.\n\nUse the Plans API to create plans for products, list existing plans, retrieve or update plan configuration, calculate tax for checkout, and delete plans that should no longer be offered.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop plans list` | List Plans |\n| `whop plans create` | Create Plan |\n| `whop plans delete` | Delete Plan |\n| `whop plans get` | Retrieve Plan |\n| `whop plans update` | Update Plan |\n| `whop plans calculate_tax` | Calculate Tax |\n\nRun `whop plans <command> --help` for options, or `whop plans <command> --schema` for full argument details.\n',
|
|
48671
|
+
"whop-checkout-configurations": "---\nname: whop-checkout-configurations\ndescription: Turn a plan into a shareable, prefilled checkout link. Run `whop checkout-configurations --help` for usage details.\nrequires_bin: whop\ncommand: whop checkout-configurations\n---\n\nA Checkout Configuration is a reusable checkout link owned by an account. In `payment` mode it sells a specific plan; in `setup` mode it collects and saves payment details without charging. Each configuration can also override which payment methods are accepted and how 3D Secure is enforced for that checkout.\n\nUse the Checkout Configurations API to create checkout links for an existing or inline plan, list configurations for an account, retrieve the configuration behind a checkout URL, and delete links that should no longer be used.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop checkout-configurations list` | List checkout configurations |\n| `whop checkout-configurations create` | Create a checkout configuration |\n| `whop checkout-configurations delete` | Delete a checkout configuration |\n| `whop checkout-configurations get` | Retrieve a checkout configuration |\n\nRun `whop checkout-configurations <command> --help` for options, or `whop checkout-configurations <command> --schema` for full argument details.\n",
|
|
48672
|
+
"whop-partners": "---\nname: whop-partners\ndescription: The users and businesses you referred to Whop, and what you earn from them. Run `whop partners --help` for usage details.\nrequires_bin: whop\ncommand: whop partners\n---\n\nThe Partners API covers your Whop partner activity: the users you referred onto Whop, the businesses you referred and the earnings generated from their processing volume, and the partner leaderboard.\n\nUse it to enroll as a Whop partner, list the users you referred, list your referred businesses and review their earnings, and see the partner leaderboard.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop partners create` | Enroll as a Whop partner |\n| `whop partners list` | List referred businesses |\n| `whop partners get` | Retrieve a referred business |\n| `whop partners earnings` | List referred business earnings |\n| `whop partners leaderboard` | Retrieve the leaderboard |\n| `whop partners referred_users` | List the users the caller referred |\n\nRun `whop partners <command> --help` for options, or `whop partners <command> --schema` for full argument details.\n",
|
|
48673
|
+
"whop-bounties": "---\nname: whop-bounties\ndescription: Paid tasks with reviewed submissions and escrowed rewards. Run `whop bounties --help` for usage details.\nrequires_bin: whop\ncommand: whop bounties\n---\n\nA Bounty is a paid task posted by an account or user. The reward is held in escrow when the bounty publishes, workers submit proof of completed work, and each accepted submission is paid out until every winner slot fills.\n\nUse the Bounties API to create and publish a bounty, list an account's bounties for reporting or dashboards, list the bounties a user can work or has participated in, and retrieve a single bounty by ID.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop bounties list` | List Bounties |\n| `whop bounties create` | Create Bounty |\n| `whop bounties get` | Retrieve Bounty |\n| `whop bounties update` | Update Bounty |\n\nRun `whop bounties <command> --help` for options, or `whop bounties <command> --schema` for full argument details.\n",
|
|
48674
|
+
"whop-bounty-submissions": "---\nname: whop-bounty-submissions\ndescription: Work submitted to a bounty, from attempt to payout. Run `whop bounty-submissions --help` for usage details.\nrequires_bin: whop\ncommand: whop bounty-submissions\n---\n\nA Bounty Submission is one worker's attempt on a bounty. It starts as an in-progress attempt, enters the review queue when proof is submitted, and ends approved (paid from the bounty's escrowed pool) or denied.\n\nUse the Bounty Submissions API to submit proof of completed work to a bounty, list the submissions you authored, and review the submissions on your bounties \u2014 across every bounty or narrowed to one.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop bounty-submissions list` | List Bounty Submissions |\n| `whop bounty-submissions create` | Create Bounty Submission |\n\nRun `whop bounty-submissions <command> --help` for options, or `whop bounty-submissions <command> --schema` for full argument details.\n",
|
|
48675
|
+
"whop-people": "---\nname: whop-people\ndescription: Visitors and customers of an account, aggregated from pixel events. Run `whop people --help` for usage details.\nrequires_bin: whop\ncommand: whop people\n---\n\nA Person represents a visitor or customer of an account, assembled from [pixel events](https://docs.whop.com/api-reference/beta/events/event) and purchase activity \u2014 ad clicks, storefront visits, and checkouts.\n\nUse the People API to list the people of an account and retrieve a single person.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop people list` | List People |\n| `whop people get` | Retrieve Person |\n\nRun `whop people <command> --help` for options, or `whop people <command> --schema` for full argument details.\n",
|
|
48676
|
+
"whop-events": "---\nname: whop-events\ndescription: Conversion and engagement events tracked for attribution. Run `whop events --help` for usage details.\nrequires_bin: whop\ncommand: whop events\n---\n\nAn Event records conversion or engagement activity for an account, such as page views, purchases, or leads. Each event ties the action to the [person](https://docs.whop.com/api-reference/beta/people/person) who took it, so activity can be attributed to the ads and links that drove it.\n\nUse the Events API to send new tracking events, list recent identity-linked events for an account, and inspect the events recorded for a person.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop events list` | List Events |\n| `whop events create` | Create Event |\n\nRun `whop events <command> --help` for options, or `whop events <command> --schema` for full argument details.\n",
|
|
48677
|
+
"whop-ads": '---\nname: whop-ads\ndescription: "The creative: copy, assets, and destination URL. Run `whop ads --help` for usage details."\nrequires_bin: whop\ncommand: whop ads\n---\n\nAn Ad is the individual creative unit delivered by an [ad group](https://docs.whop.com/api-reference/beta/ad-groups/ad-group). It holds the copy, creative assets, and destination URL for one ad.\n\nUse the Ads API to list ads for an account, create ads inside ad groups, retrieve or update creative details, delete ads that should stop running, and pause or resume delivery.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop ads list` | List Ads |\n| `whop ads create` | Create an Ad |\n| `whop ads delete` | Delete an Ad |\n| `whop ads get` | Retrieve an Ad |\n| `whop ads update` | Update an Ad |\n| `whop ads pause` | Pause an Ad |\n| `whop ads unpause` | Unpause an Ad |\n\nRun `whop ads <command> --help` for options, or `whop ads <command> --schema` for full argument details.\n\n## Launch playbook \u2014 from nothing to a live ad\n\nThree commands take you from nothing to a launchable ad: generate a creative, create the campaign + ad group + ad in one request, then flip the campaign to active. Structured flags (`--ad_group`, `--creatives`, `--ads_payment_methods`) take JSON strings.\n\n### One-time setup\n\n1. **Auth** \u2014 `whop login` (OAuth). First-time billing setup requires a user login; an API key can only reorder already-configured payment methods. If a command fails with a scope error saying your login predates the scope, run `whop login` again.\n2. **Facebook page** \u2014 `whop social-accounts list` must show a `"platform": "facebook"` entry. Three ways to get one:\n - **Already connected** \u2014 use its `sacc_` id as-is.\n - **Link a Meta Business account** \u2014 `whop social-accounts connect --platform meta_business --scopes \'["advertise"]\' --redirect_url <url>`, then send the user to the returned `authorize_url`.\n - **No page at all** \u2014 have Whop create one for the account: `whop social-accounts create --platform facebook`.\n3. **Ads payment method** \u2014 check with `whop accounts preferences <account_id>` (your `biz_` ID, from `whop accounts me`). If `ads_payment_methods` is null, configure balance billing:\n\n ```sh\n whop accounts update-preferences <account_id> --ads_payment_methods \'{"primary": {"type": "platform_balance"}}\'\n ```\n\n Only launching needs this \u2014 drafts work without. Fund the balance with `whop deposits create --amount 50` (returns a hosted deposit page URL).\n\n### 1. Generate a creative\n\n```sh\nwhop media generate --type image --prompt "A running club jogging across a bridge at sunrise, warm light" --wait\n```\n\n`--wait` blocks until the asset is terminal and returns `file.id` \u2014 use that as the creative. Billed from the balance (`amount_charged`); a failed generation auto-refunds, so adjust the prompt and retry. Video: `--type video` plus optional `--duration_seconds` (5/10/15), `--resolution` (480p\u20134k), and up to 4 `--reference_media` file IDs (first one seeds the opening frame).\n\n### 2. Create the whole tree as a draft \u2014 one request\n\n```sh\nwhop ads create \\\n --title "Run club launch ad" \\\n --primary_texts "Join 10,000 runners chasing their next PR together." \\\n --headlines "Find your stride" \\\n --call_to_action sign_up \\\n --url "https://whop.com/your-store-page" \\\n --creatives \'[{"id": "file_XXXXXXXX"}]\' \\\n --social_accounts \'[{"id": "sacc_XXXXXXXX"}]\' \\\n --ad_group \'{\n "title": "US broad",\n "conversion_location": "website",\n "regions": {"include": {"countries": ["US"]}},\n "ad_campaign": {"title": "Run club growth", "platform": "meta", "objective": "sales", "status": "draft", "budget_amount": 25, "budget_optimization": "ad_campaign"}\n }\'\n```\n\nField rules:\n\n| Field | Rule |\n|-------|------|\n| `creatives` | One entry with no `format` is required (the base asset). `square`/`vertical`/`horizontal` are optional crops on top. |\n| `url` | Required for website ads. A whop.com store page works as-is; an external page needs the Whop pixel installed. |\n| Budget | Default to CBO: `budget_amount` on the campaign with `budget_optimization: "ad_campaign"` (the network shifts spend to the best ad group). Per-ad-group `budget_amount` (ABO) is the manual alternative. One level owns it \u2014 never both. |\n| Targeting | Omit `demographics`/`placements`/`devices` for automatic optimization. `regions` uses ISO 3166 (`"US"`, `"US-CA"`). |\n| `lead_form` | Only with an instant-form `conversion_location`. |\n\nReuse existing containers by passing `--ad_group_id adgrp_x` instead of `--ad_group`, or `"ad_campaign_id": "adcamp_x"` inside `--ad_group` instead of the inline `ad_campaign`.\n\n### 3. Launch\n\n`"status": "draft"` above kept money out of it. Review, then launch \u2014 this is when spend starts and the payment method is enforced:\n\n```sh\nwhop ad-campaigns update adcamp_XXXXXXXX --status active\n```\n\n(Ready to spend immediately? Omit `"status": "draft"` and the one-shot create launches directly.)\n\n### 4. Monitor\n\n```sh\nwhop ads get ad_XXXXXXXX\n```\n\n`delivery_status` is the live state (a brief `in_review` for moderation is normal); `issues[]` carries a human-readable `message` for anything the network rejected asynchronously. Control delivery with `pause`/`unpause` on ads, ad groups, or campaigns. Edit copy or creatives with `whop ads update` \u2014 sending `creatives` replaces the whole set, so include the base entry.\n',
|
|
48678
|
+
"whop-ad-campaigns": "---\nname: whop-ad-campaigns\ndescription: Platform, objective, and budget for a set of ads. Run `whop ad-campaigns --help` for usage details.\nrequires_bin: whop\ncommand: whop ad-campaigns\n---\n\nAn Ad Campaign is the top-level container for paid ads on an ad network. It sets the platform, objective, and budget strategy shared by its [ad groups](https://docs.whop.com/api-reference/beta/ad-groups/ad-group) and ads.\n\nUse the Ad Campaigns API to create campaigns, list campaigns for an account, retrieve or update campaign settings, and pause or resume campaign delivery.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop ad-campaigns list` | List Ad Campaigns |\n| `whop ad-campaigns create` | Create an Ad Campaign |\n| `whop ad-campaigns delete` | Delete an Ad Campaign |\n| `whop ad-campaigns get` | Retrieve an Ad Campaign |\n| `whop ad-campaigns update` | Update an Ad Campaign |\n| `whop ad-campaigns pause` | Pause an Ad Campaign |\n| `whop ad-campaigns retry_payment` | Retry a Failed Ad Campaign Payment |\n| `whop ad-campaigns unpause` | Unpause an Ad Campaign |\n\nRun `whop ad-campaigns <command> --help` for options, or `whop ad-campaigns <command> --schema` for full argument details.\n",
|
|
48679
|
+
"whop-ad-groups": "---\nname: whop-ad-groups\ndescription: Audience, placements, and schedule within a campaign. Run `whop ad-groups --help` for usage details.\nrequires_bin: whop\ncommand: whop ad-groups\n---\n\nAn Ad Group sits inside an [ad campaign](https://docs.whop.com/api-reference/beta/ad-campaigns/ad-campaign) and controls delivery for [ads](https://docs.whop.com/api-reference/beta/ads/ad). It sets the audience, placements, schedule, budget, and optimization goal for its ads.\n\nUse the Ad Groups API to create ad groups in campaigns, list or retrieve targeting and delivery settings, update budgets or targeting, delete groups that should stop running, and pause or resume delivery. It can also search the ad platform's targeting taxonomy for options to target and estimate how many people a draft targeting spec can reach.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop ad-groups list` | List Ad Groups |\n| `whop ad-groups create` | Create an Ad Group |\n| `whop ad-groups estimate_reach` | Estimate Ad Group Reach |\n| `whop ad-groups targeting_options` | Search Targeting Options |\n| `whop ad-groups delete` | Delete an Ad Group |\n| `whop ad-groups get` | Retrieve an Ad Group |\n| `whop ad-groups update` | Update an Ad Group |\n| `whop ad-groups pause` | Pause an Ad Group |\n| `whop ad-groups unpause` | Unpause an Ad Group |\n\nRun `whop ad-groups <command> --help` for options, or `whop ad-groups <command> --schema` for full argument details.\n",
|
|
48680
|
+
"whop-audiences": "---\nname: whop-audiences\ndescription: Reusable targeting lists for ad groups. Run `whop audiences --help` for usage details.\nrequires_bin: whop\ncommand: whop audiences\n---\n\nAn Audience represents a customer list uploaded to Whop for ad targeting. Audiences belong to an account and sync to supported ad platforms as custom audiences.\n\nUse the Audiences API to create audiences from CSV uploads, monitor processing status, and list or delete audiences for an account. Created audiences are usable for targeting after processing reaches `ready` or `partial`.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop audiences list` | List Audiences |\n| `whop audiences create` | Create Audience |\n| `whop audiences delete` | Delete Audience |\n\nRun `whop audiences <command> --help` for options, or `whop audiences <command> --schema` for full argument details.\n",
|
|
48681
|
+
"whop-media": "---\nname: whop-media\ndescription: AI-generated assets, billed from a balance, attachable wherever files are accepted. Run `whop media --help` for usage details.\nrequires_bin: whop\ncommand: whop media\n---\n\nA Media Asset is an AI-generated image or video created from a prompt and billed from an account balance. When generation finishes, the asset includes a file that can be attached anywhere Whop accepts files.\n\nUse the Media API to start a generation job and retrieve the asset while it processes or after it is ready.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop media generate` | Generate Media Asset |\n| `whop media get` | Retrieve Media Asset |\n\nRun `whop media <command> --help` for options, or `whop media <command> --schema` for full argument details.\n\n## Steps that finish in the browser\n\nSome commands respond with a URL the user must open in a browser to finish the flow (`authorize_url`, `session_url`, `deposit_url`) \u2014 the CLI cannot complete that step itself. When a response contains one of these fields, or the CLI prints \"Action required: open this link in the user's browser\", open that link in the user's browser for them, tell them what to complete there, then re-run the matching `get`/`list` command to confirm the step finished.\n",
|
|
48682
|
+
"whop-social-accounts": "---\nname: whop-social-accounts\ndescription: Connected Facebook and Instagram accounts that run ads. Run `whop social-accounts --help` for usage details.\nrequires_bin: whop\ncommand: whop social-accounts\n---\n\nA Social Account represents an external profile connected to a Whop account or user, such as a Facebook page or Instagram account. Connecting a social account lets Whop run [ads](https://docs.whop.com/api-reference/beta/ads/ad) under that profile's identity and promote its existing posts.\n\nUse the Social Accounts API to list connected accounts, create a Whop-managed Facebook page, start an OAuth connection, disconnect a social account, and list a connected profile's posts or a Facebook page's lead forms.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop social-accounts list` | List Social Accounts |\n| `whop social-accounts create` | Create a Social Account |\n| `whop social-accounts connect` | Connect a Social Account |\n| `whop social-accounts delete` | Delete a Social Account |\n| `whop social-accounts lead_forms` | List Social Account Lead Forms |\n| `whop social-accounts posts` | List Social Account Posts |\n\nRun `whop social-accounts <command> --help` for options, or `whop social-accounts <command> --schema` for full argument details.\n\n## Steps that finish in the browser\n\nSome commands respond with a URL the user must open in a browser to finish the flow (`authorize_url`, `session_url`, `deposit_url`) \u2014 the CLI cannot complete that step itself. When a response contains one of these fields, or the CLI prints \"Action required: open this link in the user's browser\", open that link in the user's browser for them, tell them what to complete there, then re-run the matching `get`/`list` command to confirm the step finished.\n",
|
|
48683
|
+
"whop-apps": '---\nname: whop-apps\ndescription: "Apps you build on Whop: metadata, hosted builds, runtime logs. Run `whop apps --help` for usage details."\nrequires_bin: whop\ncommand: whop apps\n---\n\nAn App is software you build on Whop. It can be a hosted web app served at `<route>.whop.app` or an API integration installed as an experience, and it belongs to the account that owns its credentials, settings, builds, and runtime logs.\n\nUse the Apps API to manage app configuration and, for hosted apps, read server runtime logs for console output, uncaught exceptions, and failed requests. Logs are retained for 7 days and can be filtered by build, level, time window, and message text.\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `whop apps logs` | List App Logs |\n\nRun `whop apps <command> --help` for options, or `whop apps <command> --schema` for full argument details.\n'
|
|
48684
|
+
};
|
|
48685
|
+
|
|
48686
|
+
// src/lib/shipped-skills.ts
|
|
48687
|
+
function materializeShippedSkills() {
|
|
48688
|
+
const root = mkdtempSync4(join11(tmpdir4(), "whop-cli-skills-"));
|
|
48689
|
+
for (const [name, content] of Object.entries(shipped_skills_default)) {
|
|
48690
|
+
const dir = join11(root, name);
|
|
48691
|
+
mkdirSync5(dir);
|
|
48692
|
+
writeFileSync5(join11(dir, "SKILL.md"), content);
|
|
48693
|
+
}
|
|
48694
|
+
process.on("exit", () => rmSync5(root, { recursive: true, force: true }));
|
|
48695
|
+
return root;
|
|
48696
|
+
}
|
|
48697
|
+
|
|
48286
48698
|
// src/lib/update/check.ts
|
|
48287
48699
|
import fs6 from "fs";
|
|
48288
48700
|
import path6 from "path";
|
|
@@ -48755,6 +49167,7 @@ async function runUpgrade(c2, env = process.env) {
|
|
|
48755
49167
|
}
|
|
48756
49168
|
|
|
48757
49169
|
// src/cli.ts
|
|
49170
|
+
var shippedSkillsDir = process.argv.includes("skills") && !process.argv.includes("--no-global") ? materializeShippedSkills() : void 0;
|
|
48758
49171
|
var cli = Cli_exports.create("whop", {
|
|
48759
49172
|
version: package_default.version,
|
|
48760
49173
|
description: "Build and manage Whop apps from your terminal.",
|
|
@@ -48762,9 +49175,12 @@ var cli = Cli_exports.create("whop", {
|
|
|
48762
49175
|
sync: {
|
|
48763
49176
|
// Shipped skill files generated by scripts/sync-spec.ts from the
|
|
48764
49177
|
// spec's own tag copy (x-whop-summary + description, authored in
|
|
48765
|
-
// backend/openapi/v1/tags.yml)
|
|
48766
|
-
//
|
|
48767
|
-
|
|
49178
|
+
// backend/openapi/v1/tags.yml), bundled into the build and written to
|
|
49179
|
+
// a temp dir at runtime so standalone binaries and npx runs get them
|
|
49180
|
+
// too. A matching directory name overrides the auto-generated skill
|
|
49181
|
+
// for that command group.
|
|
49182
|
+
cwd: shippedSkillsDir,
|
|
49183
|
+
include: shippedSkillsDir ? ["*"] : ["skills/*"],
|
|
48768
49184
|
suggestions: [
|
|
48769
49185
|
"choose or create my Whop business account",
|
|
48770
49186
|
"show my Whop business accounts",
|