percher 0.5.16 → 0.5.18

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.
@@ -105969,6 +105969,9 @@ class AccountResource {
105969
105969
  listTokens() {
105970
105970
  return this.http.get("/account/tokens");
105971
105971
  }
105972
+ createToken(input) {
105973
+ return this.http.post("/account/tokens", input);
105974
+ }
105972
105975
  revokeToken(id) {
105973
105976
  return this.http.delete(`/account/tokens/${encodeURIComponent(id)}`);
105974
105977
  }
@@ -108049,6 +108052,7 @@ function buildTarball(fileBuffers) {
108049
108052
  fileCount: fileBuffers.length,
108050
108053
  topFiles,
108051
108054
  topEntries,
108055
+ topLevelEntries: [...entrySizes.keys()],
108052
108056
  contentHash
108053
108057
  };
108054
108058
  }
@@ -114369,6 +114373,74 @@ function solvePow(nonce, difficulty, maxIterations = 50000000) {
114369
114373
  return null;
114370
114374
  }
114371
114375
 
114376
+ // ../core/dist/bundle-completeness.js
114377
+ var import_cross_spawn2 = __toESM(require_cross_spawn(), 1);
114378
+ var ARTIFACT_DIRS = new Set([
114379
+ "node_modules",
114380
+ ".git",
114381
+ "dist",
114382
+ "build",
114383
+ ".next",
114384
+ ".svelte-kit",
114385
+ "coverage",
114386
+ ".bun",
114387
+ "out",
114388
+ ".turbo",
114389
+ ".cache",
114390
+ ".vercel",
114391
+ ".netlify"
114392
+ ]);
114393
+ var ASSET_DIRS = new Set(["public", "static", "assets"]);
114394
+ var SEVERE_SHRINK_PCT = 60;
114395
+ function gitTrackedFiles(cwd) {
114396
+ try {
114397
+ const res = import_cross_spawn2.default.sync("git", ["ls-files", "-z"], { cwd, encoding: "utf8" });
114398
+ if (res.status !== 0 || typeof res.stdout !== "string")
114399
+ return null;
114400
+ const files = res.stdout.split("\x00").filter(Boolean);
114401
+ return files.length > 0 ? files : null;
114402
+ } catch {
114403
+ return null;
114404
+ }
114405
+ }
114406
+ function checkBundleCompleteness(opts) {
114407
+ const tracked = gitTrackedFiles(opts.cwd);
114408
+ if (!tracked)
114409
+ return null;
114410
+ const packedDirs = new Set(opts.topLevelEntries.filter((e) => e.endsWith("/")).map((e) => e.slice(0, -1)));
114411
+ const trackedDirs = new Set;
114412
+ for (const f of tracked) {
114413
+ const slash = f.indexOf("/");
114414
+ if (slash === -1)
114415
+ continue;
114416
+ const top = f.slice(0, slash);
114417
+ if (!ARTIFACT_DIRS.has(top))
114418
+ trackedDirs.add(top);
114419
+ }
114420
+ const excludedDirs = [...trackedDirs].filter((d) => !packedDirs.has(d)).sort();
114421
+ if (excludedDirs.length === 0)
114422
+ return null;
114423
+ const shrinkPct = Math.round((1 - opts.packedFileCount / tracked.length) * 100);
114424
+ const isStatic = opts.config.app.runtime === "static";
114425
+ const assetExcluded = excludedDirs.some((d) => ASSET_DIRS.has(d));
114426
+ let reason = null;
114427
+ if (assetExcluded)
114428
+ reason = "asset_dir_excluded";
114429
+ else if (isStatic)
114430
+ reason = "static_content_excluded";
114431
+ else if (shrinkPct >= SEVERE_SHRINK_PCT)
114432
+ reason = "severe_shrink";
114433
+ if (!reason)
114434
+ return null;
114435
+ return { excludedDirs, shrinkPct, reason };
114436
+ }
114437
+ function bundleCompletenessMessage(w, config2) {
114438
+ const label = config2.app.framework ? `${config2.app.framework} (${config2.app.runtime})` : config2.app.runtime;
114439
+ const dirs = w.excludedDirs.map((d) => `${d}/`).join(", ");
114440
+ const assetNote = w.reason === "asset_dir_excluded" ? " Those hold static assets — the deployed app will be missing them." : w.reason === "static_content_excluded" ? " A static app serves exactly these files, so the deployed site will be missing content." : "";
114441
+ return `Detected a ${label} app, but the upload is missing ${w.excludedDirs.length} git-tracked ` + `director${w.excludedDirs.length === 1 ? "y" : "ies"} (${dirs}) — the bundle has ~${w.shrinkPct}% ` + `fewer files than your repo tracks.${assetNote} This is almost always an over-broad ` + `.gitignore/.percherignore rule. Those are gitignore-style patterns: a bare \`name\` matches a ` + `\`name/\` directory at ANY depth, so anchor to the repo root with a leading slash (e.g. \`/build\`) ` + `when you mean only the top-level one. If the exclusion is intentional, re-run with --force.`;
114442
+ }
114443
+
114372
114444
  // ../core/dist/event-renderer.js
114373
114445
  function renderDeployEvent(event) {
114374
114446
  if (event.stage === "queue") {
@@ -114802,6 +114874,12 @@ function classifyPublishApiError(err, input) {
114802
114874
  const auth = matchAuthError(err);
114803
114875
  if (auth)
114804
114876
  return buildResult(auth, input);
114877
+ const tooLarge = matchInlinePublishTooLarge(err);
114878
+ if (tooLarge)
114879
+ return buildResult(tooLarge, input);
114880
+ const repoMissingConfig = matchRepoMissingConfig(err);
114881
+ if (repoMissingConfig)
114882
+ return buildResult(repoMissingConfig, input);
114805
114883
  const retryLimit = matchRetryLimitReached(err, input);
114806
114884
  if (retryLimit)
114807
114885
  return buildResult(retryLimit, input);
@@ -115086,6 +115164,40 @@ function matchDailyQuotaExceeded(err, input) {
115086
115164
  summary: `Daily ${kind}-deploy quota reached (${used}/${limit}). Resets ${resetAt}.`
115087
115165
  };
115088
115166
  }
115167
+ function matchInlinePublishTooLarge(err) {
115168
+ if (err.code !== "INLINE_PUBLISH_TOO_LARGE")
115169
+ return null;
115170
+ return {
115171
+ title: "Inline source too large",
115172
+ explanation: err.message,
115173
+ suggestion: "Inline publishing is for small, text-generated apps. Publish a larger or on-disk app another way: on-disk project → the local `bunx percher publish` CLI (or `npx -y @percher/mcp`); public repo → percher_publish_from_git; private repo → connect it via the GitHub App, then percher_deploy.",
115174
+ recovery: recoveryAsk({
115175
+ prompt: `${err.message} Publish by source instead: on-disk → local \`bunx percher publish\` / \`npx -y @percher/mcp\`; public repo → percher_publish_from_git; private repo → connect via the GitHub App, then percher_deploy.`,
115176
+ options: [
115177
+ "publish on-disk (bunx percher publish / npx @percher/mcp)",
115178
+ "public repo (percher_publish_from_git)",
115179
+ "private repo (GitHub App + percher_deploy)"
115180
+ ],
115181
+ reasonCode: "unknown"
115182
+ }),
115183
+ summary: `Inline source too large: ${err.message}`
115184
+ };
115185
+ }
115186
+ function matchRepoMissingConfig(err) {
115187
+ if (err.code !== "REPO_MISSING_CONFIG")
115188
+ return null;
115189
+ return {
115190
+ title: "Repo has no percher.toml",
115191
+ explanation: err.message,
115192
+ suggestion: "Add a percher.toml (with [app] name + runtime) to the repo root and push, then retry — or publish the source inline with percher_publish instead.",
115193
+ recovery: recoveryAsk({
115194
+ prompt: `${err.message} Add a percher.toml to the repo root (then retry percher_publish_from_git), or publish the source inline with percher_publish.`,
115195
+ options: ["add percher.toml to the repo", "publish inline (percher_publish)"],
115196
+ reasonCode: "config_missing"
115197
+ }),
115198
+ summary: `Repo missing percher.toml: ${err.message}`
115199
+ };
115200
+ }
115089
115201
  function matchGenericClientError(err) {
115090
115202
  if (err.status < 400 || err.status >= 500)
115091
115203
  return null;
@@ -115344,7 +115456,7 @@ ${bullets}`,
115344
115456
  error: {
115345
115457
  title: "Repository too large",
115346
115458
  explanation: `The project is ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB, which exceeds the 500 MB limit.`,
115347
- suggestion: `Add large files/folders to .gitignore or .percherignore. Biggest: ${formatBiggestEntries(tarball.topEntries)}`
115459
+ suggestion: `Add large files/folders to .gitignore or .percherignore (gitignore-style — anchor with a leading / for top-level only, e.g. /assets). Biggest: ${formatBiggestEntries(tarball.topEntries)}`
115348
115460
  },
115349
115461
  recovery: recoveryAsk({
115350
115462
  prompt: `Repository is ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB, which exceeds the 500 MB upload limit. Add large files/folders to .gitignore or .percherignore (biggest: ${formatBiggestEntries(tarball.topEntries)}) and try again.`,
@@ -115356,7 +115468,33 @@ ${bullets}`,
115356
115468
  };
115357
115469
  }
115358
115470
  if (!input.force && (tarball.fileCount > SUSPICIOUS_FILES || tarball.bytes > SUSPICIOUS_BYTES)) {
115359
- ctx.status(`Warning: ${tarball.fileCount} files, ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB — auto-continuing (MCP mode). Biggest: ${formatBiggestEntries(tarball.topEntries)}. Trim the upload by adding large items to .gitignore or .percherignore.`);
115471
+ ctx.status(`Warning: ${tarball.fileCount} files, ${(tarball.bytes / 1024 / 1024).toFixed(1)} MB — auto-continuing (MCP mode). Biggest: ${formatBiggestEntries(tarball.topEntries)}. Trim the upload by adding large items to .gitignore or .percherignore (gitignore-style patterns — anchor with a leading / for top-level only, e.g. /assets).`);
115472
+ }
115473
+ if (!input.force) {
115474
+ const completeness = checkBundleCompleteness({
115475
+ cwd: ctx.cwd,
115476
+ config: config2,
115477
+ topLevelEntries: tarball.topLevelEntries,
115478
+ packedFileCount: tarball.fileCount
115479
+ });
115480
+ if (completeness) {
115481
+ const message = bundleCompletenessMessage(completeness, config2);
115482
+ const excluded = completeness.excludedDirs.map((d) => `${d}/`).join(", ");
115483
+ return {
115484
+ status: "failed",
115485
+ fileCount: tarball.fileCount,
115486
+ bytes: tarball.bytes,
115487
+ error: {
115488
+ title: "Bundle is missing git-tracked files",
115489
+ explanation: message,
115490
+ suggestion: "Fix the .gitignore/.percherignore pattern that excluded it, or re-run with --force if intentional."
115491
+ },
115492
+ recovery: recoveryAsk({ prompt: message, reasonCode: "unknown" }),
115493
+ summary: `Upload is missing git-tracked dir(s): ${excluded} (~${completeness.shrinkPct}% fewer files than tracked). Re-run with --force if intentional.`,
115494
+ configPath: tomlPathFor2(ctx.cwd),
115495
+ bundle: { fileCount: tarball.fileCount, bytes: tarball.bytes }
115496
+ };
115497
+ }
115360
115498
  }
115361
115499
  emitPreflight(ctx, config2, {
115362
115500
  fileCount: tarball.fileCount,
@@ -116610,10 +116748,10 @@ function updateLocalTomlName(cwd, oldName, newName) {
116610
116748
  import { mkdtempSync, writeFileSync as writeFileSync10 } from "node:fs";
116611
116749
  import { tmpdir } from "node:os";
116612
116750
  import { join as join27 } from "node:path";
116613
- var import_cross_spawn2 = __toESM(require_cross_spawn(), 1);
116751
+ var import_cross_spawn3 = __toESM(require_cross_spawn(), 1);
116614
116752
  function runProcessExit(cmd, args, opts = {}) {
116615
116753
  return new Promise((resolve11, reject) => {
116616
- const child = import_cross_spawn2.default(cmd, args, {
116754
+ const child = import_cross_spawn3.default(cmd, args, {
116617
116755
  cwd: opts.cwd,
116618
116756
  stdio: opts.inherit ? "inherit" : "ignore"
116619
116757
  });
@@ -117039,6 +117177,34 @@ function summarize2(verdict, health) {
117039
117177
  }
117040
117178
  return "API responded but reported a non-ok status";
117041
117179
  }
117180
+ // ../core/dist/commands/token.js
117181
+ var tokenCreateInputSchema = exports_external.object({
117182
+ name: exports_external.string().trim().min(1).max(80).describe("Human label for the token (shown in the list)."),
117183
+ scope: exports_external.enum(["deploy", "env", "read", "full"]).default("full").describe("Least-privilege scope: deploy (publish/rollback/logs), env (set/read env), read (GETs only), or full (account-wide). Prefer the narrowest that works for CI/agents."),
117184
+ app: exports_external.string().trim().min(1).optional().describe("Bind the token to a single app by name. Omit for all of your apps."),
117185
+ ttlDays: exports_external.number().int().positive().max(365).optional().describe("Token lifetime in days (server default ≈ 90).")
117186
+ });
117187
+ var tokenRevokeInputSchema = exports_external.object({
117188
+ id: exports_external.string().min(1).describe("Token id from `percher token list`.")
117189
+ });
117190
+ async function tokenCreate(ctx, input) {
117191
+ ctx.status("Minting token…");
117192
+ return ctx.client.account.createToken({
117193
+ name: input.name,
117194
+ scope: input.scope,
117195
+ app: input.app,
117196
+ ttlDays: input.ttlDays
117197
+ });
117198
+ }
117199
+ async function tokenList(ctx) {
117200
+ ctx.status("Loading tokens…");
117201
+ const { tokens } = await ctx.client.account.listTokens();
117202
+ return tokens;
117203
+ }
117204
+ async function tokenRevoke(ctx, input) {
117205
+ ctx.status("Revoking token…");
117206
+ await ctx.client.account.revokeToken(input.id);
117207
+ }
117042
117208
  // ../core/dist/commands/transfers.js
117043
117209
  function resolveApp5(ctx, app) {
117044
117210
  const name = app ?? readPercherTomlAppName(ctx.cwd);
@@ -119168,18 +119334,91 @@ async function renderHumanStatus(ctx, result) {
119168
119334
  }
119169
119335
  }
119170
119336
 
119171
- // src/commands/transfers.ts
119337
+ // src/commands/token.ts
119172
119338
  var import_picocolors14 = __toESM(require_picocolors(), 1);
119339
+ var VALID_SCOPES = ["deploy", "env", "read", "full"];
119340
+ function scopeLabel(scopes, appName) {
119341
+ const s = scopes && scopes.length > 0 ? scopes.join("+") : "full";
119342
+ return appName ? `${s} · ${appName}` : `${s} · all apps`;
119343
+ }
119344
+ function registerTokenCommands(cli, ctx) {
119345
+ cli.command("token [action] [arg]", "Manage API tokens: create | list | revoke").option("--scope <scope>", "(create) deploy | env | read | full (default: full)").option("--app <name>", "(create) bind the token to a single app").option("--ttl-days <n>", "(create) token lifetime in days").action(async (action, arg, options) => {
119346
+ if (!ctx.client.token) {
119347
+ await writeLine(ctx, `${import_picocolors14.default.red("✗")} Not logged in. Run: percher login`);
119348
+ throw new SilentExitError;
119349
+ }
119350
+ if (action === "create") {
119351
+ if (!arg) {
119352
+ await writeLine(ctx, `${import_picocolors14.default.red("✗")} A name is required. Usage: percher token create <name> [--scope deploy] [--app <name>]`);
119353
+ throw new SilentExitError;
119354
+ }
119355
+ const scope = options.scope ?? "full";
119356
+ if (!VALID_SCOPES.includes(scope)) {
119357
+ await writeLine(ctx, `${import_picocolors14.default.red("✗")} Invalid --scope "${options.scope}". Use one of: ${VALID_SCOPES.join(", ")}.`);
119358
+ throw new SilentExitError;
119359
+ }
119360
+ const ttlDays = options.ttlDays !== undefined ? Number(options.ttlDays) : undefined;
119361
+ if (ttlDays !== undefined && (!Number.isInteger(ttlDays) || ttlDays <= 0)) {
119362
+ await writeLine(ctx, `${import_picocolors14.default.red("✗")} --ttl-days must be a positive whole number.`);
119363
+ throw new SilentExitError;
119364
+ }
119365
+ const created = await tokenCreate(ctx, {
119366
+ name: arg,
119367
+ scope,
119368
+ app: options.app,
119369
+ ttlDays
119370
+ });
119371
+ await writeLine(ctx, `${import_picocolors14.default.green("✓")} Token created: ${import_picocolors14.default.bold(created.name)} ${import_picocolors14.default.dim(`(${scopeLabel(created.scopes, created.appName)})`)}`);
119372
+ await writeLine(ctx, "");
119373
+ await writeLine(ctx, ` ${import_picocolors14.default.bold(created.token)}`);
119374
+ await writeLine(ctx, import_picocolors14.default.yellow(" ↑ Store this now — the secret is shown only once and can't be retrieved."));
119375
+ await writeLine(ctx, "");
119376
+ await writeLine(ctx, import_picocolors14.default.dim(" Use it in CI / an agent:"));
119377
+ await writeLine(ctx, import_picocolors14.default.dim(` PERCHER_TOKEN=${created.token} bunx percher publish`));
119378
+ return;
119379
+ }
119380
+ if (action === "list") {
119381
+ const tokens = await tokenList(ctx);
119382
+ if (tokens.length === 0) {
119383
+ await writeLine(ctx, import_picocolors14.default.dim("No API tokens."));
119384
+ return;
119385
+ }
119386
+ for (const t of tokens) {
119387
+ const expires = t.expiresAt ? `expires ${new Date(t.expiresAt).toISOString().slice(0, 10)}` : "no expiry";
119388
+ await writeLine(ctx, `${import_picocolors14.default.bold(t.id)} ${t.name.padEnd(20)} ${import_picocolors14.default.dim(scopeLabel(t.scopes, t.appName))} ${import_picocolors14.default.dim(expires)}`);
119389
+ }
119390
+ await writeLine(ctx, "");
119391
+ await writeLine(ctx, import_picocolors14.default.dim("Revoke one with: percher token revoke <id>"));
119392
+ return;
119393
+ }
119394
+ if (action === "revoke") {
119395
+ if (!arg) {
119396
+ await writeLine(ctx, `${import_picocolors14.default.red("✗")} A token id is required. Usage: percher token revoke <id> (list ids with \`percher token list\`).`);
119397
+ throw new SilentExitError;
119398
+ }
119399
+ await tokenRevoke(ctx, { id: arg });
119400
+ await writeLine(ctx, `${import_picocolors14.default.green("✓")} Token revoked.`);
119401
+ return;
119402
+ }
119403
+ throw new Error(`Unknown token action "${action ?? ""}". Use: create | list | revoke.`);
119404
+ });
119405
+ cli.command("token create <name>", "Mint a scoped API token (the secret is shown once)").option("--scope <scope>", "deploy | env | read | full (default: full)").option("--app <name>", "Bind the token to a single app").option("--ttl-days <n>", "Token lifetime in days").action(async () => {});
119406
+ cli.command("token list", "List your API tokens with scope + bound app").action(async () => {});
119407
+ cli.command("token revoke <id>", "Revoke an API token by id").action(async () => {});
119408
+ }
119409
+
119410
+ // src/commands/transfers.ts
119411
+ var import_picocolors15 = __toESM(require_picocolors(), 1);
119173
119412
  function registerTransfersCommands(cli, ctx) {
119174
119413
  cli.command("transfer [emailOrTransferId]", "Transfer ownership of an app: `transfer <email>` initiates; `transfer --cancel <id>` cancels; `transfer --list` shows history").option("--app <name>", "App name (overrides percher.toml)").option("--cancel", "Cancel a pending transfer by id (positional arg is the transferId)").option("--list", "List the transfer history for this app").action(async (emailOrTransferId, options) => {
119175
119414
  if (options.list) {
119176
119415
  const rows = await transferListForApp(ctx, { app: options.app });
119177
119416
  if (rows.length === 0) {
119178
- await writeLine(ctx, import_picocolors14.default.dim("No transfers for this app."));
119417
+ await writeLine(ctx, import_picocolors15.default.dim("No transfers for this app."));
119179
119418
  return;
119180
119419
  }
119181
119420
  for (const r of rows) {
119182
- const status2 = r.status === "pending" ? import_picocolors14.default.yellow("pending") : r.status === "accepted" ? import_picocolors14.default.green("accepted") : import_picocolors14.default.dim(r.status);
119421
+ const status2 = r.status === "pending" ? import_picocolors15.default.yellow("pending") : r.status === "accepted" ? import_picocolors15.default.green("accepted") : import_picocolors15.default.dim(r.status);
119183
119422
  await writeLine(ctx, `${r.id} ${status2.padEnd(20)} → ${r.toEmail} (${r.createdAt})`);
119184
119423
  }
119185
119424
  return;
@@ -119192,7 +119431,7 @@ function registerTransfersCommands(cli, ctx) {
119192
119431
  app: options.app,
119193
119432
  transferId: emailOrTransferId
119194
119433
  });
119195
- await writeLine(ctx, `${import_picocolors14.default.green("✓")} Cancelled transfer ${emailOrTransferId}`);
119434
+ await writeLine(ctx, `${import_picocolors15.default.green("✓")} Cancelled transfer ${emailOrTransferId}`);
119196
119435
  return;
119197
119436
  }
119198
119437
  if (!emailOrTransferId) {
@@ -119202,17 +119441,17 @@ function registerTransfersCommands(cli, ctx) {
119202
119441
  app: options.app,
119203
119442
  email: emailOrTransferId
119204
119443
  });
119205
- await writeLine(ctx, `${import_picocolors14.default.green("✓")} Transfer initiated to ${initiated.toEmail} (id ${initiated.id})`);
119206
- await writeLine(ctx, import_picocolors14.default.dim(`Expires ${new Date(initiated.expiresAt).toLocaleDateString()}. The recipient must accept via 'percher transfers accept ${initiated.id}'.`));
119444
+ await writeLine(ctx, `${import_picocolors15.default.green("✓")} Transfer initiated to ${initiated.toEmail} (id ${initiated.id})`);
119445
+ await writeLine(ctx, import_picocolors15.default.dim(`Expires ${new Date(initiated.expiresAt).toLocaleDateString()}. The recipient must accept via 'percher transfers accept ${initiated.id}'.`));
119207
119446
  if (initiated.notes) {
119208
- await writeLine(ctx, import_picocolors14.default.yellow(` ⚠ ${initiated.notes}`));
119447
+ await writeLine(ctx, import_picocolors15.default.yellow(` ⚠ ${initiated.notes}`));
119209
119448
  }
119210
119449
  });
119211
119450
  cli.command("transfers [action] [transferId]", "Incoming ownership transfers: list (default) | accept <transferId> | decline <transferId>").action(async (action, transferId) => {
119212
119451
  if (action === undefined || action === "list") {
119213
119452
  const rows = await transfersIncoming(ctx, {});
119214
119453
  if (rows.length === 0) {
119215
- await writeLine(ctx, import_picocolors14.default.dim("No pending incoming transfers."));
119454
+ await writeLine(ctx, import_picocolors15.default.dim("No pending incoming transfers."));
119216
119455
  return;
119217
119456
  }
119218
119457
  for (const r of rows) {
@@ -119225,7 +119464,7 @@ function registerTransfersCommands(cli, ctx) {
119225
119464
  throw new Error("Usage: percher transfers accept <transferId>");
119226
119465
  }
119227
119466
  const accepted = await transfersAccept(ctx, { transferId });
119228
- await writeLine(ctx, `${import_picocolors14.default.green("✓")} You now own ${import_picocolors14.default.cyan(accepted.appName)}. Run 'percher open --app ${accepted.appName}' to see it.`);
119467
+ await writeLine(ctx, `${import_picocolors15.default.green("✓")} You now own ${import_picocolors15.default.cyan(accepted.appName)}. Run 'percher open --app ${accepted.appName}' to see it.`);
119229
119468
  return;
119230
119469
  }
119231
119470
  if (action === "decline") {
@@ -119233,7 +119472,7 @@ function registerTransfersCommands(cli, ctx) {
119233
119472
  throw new Error("Usage: percher transfers decline <transferId>");
119234
119473
  }
119235
119474
  await transfersDecline(ctx, { transferId });
119236
- await writeLine(ctx, `${import_picocolors14.default.green("✓")} Declined transfer ${transferId}.`);
119475
+ await writeLine(ctx, `${import_picocolors15.default.green("✓")} Declined transfer ${transferId}.`);
119237
119476
  return;
119238
119477
  }
119239
119478
  throw new Error(`Unknown transfers action "${action}". Use list | accept <id> | decline <id>.`);
@@ -119302,52 +119541,52 @@ async function createCliContext() {
119302
119541
  }
119303
119542
 
119304
119543
  // src/output.ts
119305
- var import_picocolors15 = __toESM(require_picocolors(), 1);
119544
+ var import_picocolors16 = __toESM(require_picocolors(), 1);
119306
119545
  async function renderError(stderr, error48) {
119307
119546
  const writer = stderr.getWriter();
119308
119547
  const encoder = new TextEncoder;
119309
119548
  const lines = [];
119310
119549
  if (error48 instanceof PercherTomlError) {
119311
- lines.push(`${import_picocolors15.default.red(`error (${error48.code}):`)} ${error48.message}`);
119550
+ lines.push(`${import_picocolors16.default.red(`error (${error48.code}):`)} ${error48.message}`);
119312
119551
  if (error48.tomlLine !== undefined) {
119313
- lines.push(import_picocolors15.default.dim(` at percher.toml line ${error48.tomlLine}`));
119552
+ lines.push(import_picocolors16.default.dim(` at percher.toml line ${error48.tomlLine}`));
119314
119553
  }
119315
119554
  for (const issue2 of error48.issues ?? []) {
119316
- lines.push(`${import_picocolors15.default.dim(" · ") + import_picocolors15.default.yellow(issue2.path.join("."))}: ${issue2.message}`);
119555
+ lines.push(`${import_picocolors16.default.dim(" · ") + import_picocolors16.default.yellow(issue2.path.join("."))}: ${issue2.message}`);
119317
119556
  }
119318
119557
  } else if (error48 instanceof SunsetError) {
119319
119558
  if (error48.gateCode === "platform_delete_gated") {
119320
- lines.push(`${import_picocolors15.default.yellow("Percher is shutting down — deletes are paused.")}`);
119559
+ lines.push(`${import_picocolors16.default.yellow("Percher is shutting down — deletes are paused.")}`);
119321
119560
  lines.push(error48.message);
119322
- lines.push(import_picocolors15.default.dim(` To delete and permanently forfeit your export window, confirm with your password in the dashboard: ${error48.dashboardUrl}`));
119323
- lines.push(import_picocolors15.default.dim(" The CLI cannot perform this delete during sunset — it must go through the dashboard."));
119561
+ lines.push(import_picocolors16.default.dim(` To delete and permanently forfeit your export window, confirm with your password in the dashboard: ${error48.dashboardUrl}`));
119562
+ lines.push(import_picocolors16.default.dim(" The CLI cannot perform this delete during sunset — it must go through the dashboard."));
119324
119563
  } else {
119325
- lines.push(`${import_picocolors15.default.yellow("Percher is in read-only mode ahead of shutdown.")}`);
119564
+ lines.push(`${import_picocolors16.default.yellow("Percher is in read-only mode ahead of shutdown.")}`);
119326
119565
  lines.push(error48.message);
119327
- lines.push(import_picocolors15.default.dim(` Your apps keep running. Export them any time from the dashboard: ${error48.dashboardUrl}`));
119566
+ lines.push(import_picocolors16.default.dim(` Your apps keep running. Export them any time from the dashboard: ${error48.dashboardUrl}`));
119328
119567
  }
119329
- lines.push(import_picocolors15.default.dim(` Final data deletion: ${error48.finalDeletionDate}`));
119568
+ lines.push(import_picocolors16.default.dim(` Final data deletion: ${error48.finalDeletionDate}`));
119330
119569
  } else if (error48 instanceof PercherApiError) {
119331
119570
  if (error48.status === 502 || error48.status === 503) {
119332
- lines.push(`${import_picocolors15.default.red("error:")} Percher API is temporarily unavailable (HTTP ${error48.status}). Try again in a few seconds.`);
119571
+ lines.push(`${import_picocolors16.default.red("error:")} Percher API is temporarily unavailable (HTTP ${error48.status}). Try again in a few seconds.`);
119333
119572
  } else {
119334
- lines.push(`${import_picocolors15.default.red("error:")} ${error48.message}`);
119335
- lines.push(import_picocolors15.default.dim(` ${error48.code} (HTTP ${error48.status})`));
119573
+ lines.push(`${import_picocolors16.default.red("error:")} ${error48.message}`);
119574
+ lines.push(import_picocolors16.default.dim(` ${error48.code} (HTTP ${error48.status})`));
119336
119575
  }
119337
119576
  if (error48.requestId)
119338
- lines.push(import_picocolors15.default.dim(` request: ${error48.requestId}`));
119577
+ lines.push(import_picocolors16.default.dim(` request: ${error48.requestId}`));
119339
119578
  } else if (error48 instanceof PercherCoreError) {
119340
- lines.push(`${import_picocolors15.default.red(`error (${error48.code}):`)} ${error48.message}`);
119579
+ lines.push(`${import_picocolors16.default.red(`error (${error48.code}):`)} ${error48.message}`);
119341
119580
  if (error48.hint)
119342
- lines.push(import_picocolors15.default.dim(` ${error48.hint}`));
119581
+ lines.push(import_picocolors16.default.dim(` ${error48.hint}`));
119343
119582
  } else if (error48 instanceof Error) {
119344
- lines.push(`${import_picocolors15.default.red("unexpected error:")} ${error48.message}`);
119583
+ lines.push(`${import_picocolors16.default.red("unexpected error:")} ${error48.message}`);
119345
119584
  if (error48.stack)
119346
- lines.push(import_picocolors15.default.dim(error48.stack.split(`
119585
+ lines.push(import_picocolors16.default.dim(error48.stack.split(`
119347
119586
  `).slice(1, 4).join(`
119348
119587
  `)));
119349
119588
  } else {
119350
- lines.push(`${import_picocolors15.default.red("unexpected error:")} ${String(error48)}`);
119589
+ lines.push(`${import_picocolors16.default.red("unexpected error:")} ${String(error48)}`);
119351
119590
  }
119352
119591
  try {
119353
119592
  await writer.write(encoder.encode(`${lines.join(`
@@ -119360,7 +119599,7 @@ async function renderError(stderr, error48) {
119360
119599
  // package.json
119361
119600
  var package_default = {
119362
119601
  name: "percher",
119363
- version: "0.5.16",
119602
+ version: "0.5.18",
119364
119603
  description: "CLI for the Percher hosting platform — publish apps with one command",
119365
119604
  type: "module",
119366
119605
  bin: {
@@ -119384,9 +119623,9 @@ var package_default = {
119384
119623
  typecheck: "tsc --noEmit"
119385
119624
  },
119386
119625
  dependencies: {
119387
- "@percher/client": "^0.2.16",
119388
- "@percher/core": "^0.4.18",
119389
- "@percher/toml": "^0.1.5",
119626
+ "@percher/client": "^0.2.18",
119627
+ "@percher/core": "^0.4.21",
119628
+ "@percher/toml": "^0.1.7",
119390
119629
  cac: "^7.0.0",
119391
119630
  picocolors: "^1.1.1"
119392
119631
  },
@@ -119457,7 +119696,7 @@ async function showTelemetryNotice() {
119457
119696
  }
119458
119697
 
119459
119698
  // src/version-check.ts
119460
- var import_picocolors16 = __toESM(require_picocolors(), 1);
119699
+ var import_picocolors17 = __toESM(require_picocolors(), 1);
119461
119700
  async function checkForUpdates() {
119462
119701
  try {
119463
119702
  const res = await fetch("https://registry.npmjs.org/percher/latest", {
@@ -119468,9 +119707,9 @@ async function checkForUpdates() {
119468
119707
  const data2 = await res.json();
119469
119708
  const latest = data2.version;
119470
119709
  if (latest && latest !== VERSION) {
119471
- console.error(import_picocolors16.default.yellow(`
119710
+ console.error(import_picocolors17.default.yellow(`
119472
119711
  Update available: ${VERSION} → ${latest}`));
119473
- console.error(import_picocolors16.default.dim(`Run: bunx percher@latest
119712
+ console.error(import_picocolors17.default.dim(`Run: bunx percher@latest
119474
119713
  `));
119475
119714
  }
119476
119715
  } catch {}
@@ -119491,6 +119730,7 @@ async function run(argv, ctxOverride) {
119491
119730
  registerMigrateCommands(cli, ctx);
119492
119731
  registerSharingCommands(cli, ctx);
119493
119732
  registerStatusCommands(cli, ctx);
119733
+ registerTokenCommands(cli, ctx);
119494
119734
  registerTransfersCommands(cli, ctx);
119495
119735
  registerAdminCommands(cli, ctx);
119496
119736
  cli.help();
package/dist/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "percher",
3
- "version": "0.5.16",
4
- "description": "CLI for the Percher hosting platform \u2014 publish apps with one command",
3
+ "version": "0.5.18",
4
+ "description": "CLI for the Percher hosting platform — publish apps with one command",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "percher": "./dist/bin/percher.js"
@@ -24,9 +24,9 @@
24
24
  "typecheck": "tsc --noEmit"
25
25
  },
26
26
  "dependencies": {
27
- "@percher/client": "^0.2.16",
28
- "@percher/core": "^0.4.18",
29
- "@percher/toml": "^0.1.5",
27
+ "@percher/client": "^0.2.18",
28
+ "@percher/core": "^0.4.21",
29
+ "@percher/toml": "^0.1.7",
30
30
  "cac": "^7.0.0",
31
31
  "picocolors": "^1.1.1"
32
32
  },
@@ -0,0 +1,4 @@
1
+ import type { Context } from "@percher/core";
2
+ import type { CAC } from "cac";
3
+ export declare function registerTokenCommands(cli: CAC, ctx: Context): void;
4
+ //# sourceMappingURL=token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../../src/commands/token.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAY/B,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAwHlE"}
@@ -0,0 +1,97 @@
1
+ import * as core from "@percher/core";
2
+ import pc from "picocolors";
3
+ import { SilentExitError, writeLine } from "../cli-utils";
4
+ const VALID_SCOPES = ["deploy", "env", "read", "full"];
5
+ function scopeLabel(scopes, appName) {
6
+ const s = scopes && scopes.length > 0 ? scopes.join("+") : "full";
7
+ return appName ? `${s} · ${appName}` : `${s} · all apps`;
8
+ }
9
+ export function registerTokenCommands(cli, ctx) {
10
+ // cac matches commands by single first-token equality, so `token create
11
+ // <name>` routes here with action="create". `[arg]` is the token label for
12
+ // create and the token id for revoke.
13
+ cli
14
+ .command("token [action] [arg]", "Manage API tokens: create | list | revoke")
15
+ .option("--scope <scope>", "(create) deploy | env | read | full (default: full)")
16
+ .option("--app <name>", "(create) bind the token to a single app")
17
+ .option("--ttl-days <n>", "(create) token lifetime in days")
18
+ .action(async (action, arg, options) => {
19
+ if (!ctx.client.token) {
20
+ await writeLine(ctx, `${pc.red("✗")} Not logged in. Run: percher login`);
21
+ throw new SilentExitError();
22
+ }
23
+ if (action === "create") {
24
+ if (!arg) {
25
+ await writeLine(ctx, `${pc.red("✗")} A name is required. Usage: percher token create <name> [--scope deploy] [--app <name>]`);
26
+ throw new SilentExitError();
27
+ }
28
+ const scope = (options.scope ?? "full");
29
+ if (!VALID_SCOPES.includes(scope)) {
30
+ await writeLine(ctx, `${pc.red("✗")} Invalid --scope "${options.scope}". Use one of: ${VALID_SCOPES.join(", ")}.`);
31
+ throw new SilentExitError();
32
+ }
33
+ const ttlDays = options.ttlDays !== undefined ? Number(options.ttlDays) : undefined;
34
+ if (ttlDays !== undefined && (!Number.isInteger(ttlDays) || ttlDays <= 0)) {
35
+ await writeLine(ctx, `${pc.red("✗")} --ttl-days must be a positive whole number.`);
36
+ throw new SilentExitError();
37
+ }
38
+ const created = await core.tokenCreate(ctx, {
39
+ name: arg,
40
+ scope,
41
+ app: options.app,
42
+ ttlDays,
43
+ });
44
+ await writeLine(ctx, `${pc.green("✓")} Token created: ${pc.bold(created.name)} ${pc.dim(`(${scopeLabel(created.scopes, created.appName)})`)}`);
45
+ await writeLine(ctx, "");
46
+ await writeLine(ctx, ` ${pc.bold(created.token)}`);
47
+ await writeLine(ctx, pc.yellow(" ↑ Store this now — the secret is shown only once and can't be retrieved."));
48
+ await writeLine(ctx, "");
49
+ await writeLine(ctx, pc.dim(" Use it in CI / an agent:"));
50
+ await writeLine(ctx, pc.dim(` PERCHER_TOKEN=${created.token} bunx percher publish`));
51
+ return;
52
+ }
53
+ if (action === "list") {
54
+ const tokens = await core.tokenList(ctx);
55
+ if (tokens.length === 0) {
56
+ await writeLine(ctx, pc.dim("No API tokens."));
57
+ return;
58
+ }
59
+ for (const t of tokens) {
60
+ const expires = t.expiresAt
61
+ ? `expires ${new Date(t.expiresAt).toISOString().slice(0, 10)}`
62
+ : "no expiry";
63
+ await writeLine(ctx, `${pc.bold(t.id)} ${t.name.padEnd(20)} ${pc.dim(scopeLabel(t.scopes, t.appName))} ${pc.dim(expires)}`);
64
+ }
65
+ await writeLine(ctx, "");
66
+ await writeLine(ctx, pc.dim("Revoke one with: percher token revoke <id>"));
67
+ return;
68
+ }
69
+ if (action === "revoke") {
70
+ if (!arg) {
71
+ await writeLine(ctx, `${pc.red("✗")} A token id is required. Usage: percher token revoke <id> (list ids with \`percher token list\`).`);
72
+ throw new SilentExitError();
73
+ }
74
+ await core.tokenRevoke(ctx, { id: arg });
75
+ await writeLine(ctx, `${pc.green("✓")} Token revoked.`);
76
+ return;
77
+ }
78
+ throw new Error(`Unknown token action "${action ?? ""}". Use: create | list | revoke.`);
79
+ });
80
+ // Help-only registrations (unreachable — cac falls through to the parent
81
+ // `token [action] ...`), so `--help` surfaces each subcommand.
82
+ cli
83
+ .command("token create <name>", "Mint a scoped API token (the secret is shown once)")
84
+ .option("--scope <scope>", "deploy | env | read | full (default: full)")
85
+ .option("--app <name>", "Bind the token to a single app")
86
+ .option("--ttl-days <n>", "Token lifetime in days")
87
+ .action(async () => {
88
+ /* Unreachable — handled by `token [action] ...`. */
89
+ });
90
+ cli.command("token list", "List your API tokens with scope + bound app").action(async () => {
91
+ /* Unreachable — handled by `token [action] ...`. */
92
+ });
93
+ cli.command("token revoke <id>", "Revoke an API token by id").action(async () => {
94
+ /* Unreachable — handled by `token [action] ...`. */
95
+ });
96
+ }
97
+ //# sourceMappingURL=token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.js","sourceRoot":"","sources":["../../../src/commands/token.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAqB7C,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAoEhF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAsB7C,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAqEhF"}
package/dist/src/index.js CHANGED
@@ -12,6 +12,7 @@ import { registerGithubCommands } from "./commands/github";
12
12
  import { registerMigrateCommands } from "./commands/migrate";
13
13
  import { registerSharingCommands } from "./commands/sharing";
14
14
  import { registerStatusCommands } from "./commands/status";
15
+ import { registerTokenCommands } from "./commands/token";
15
16
  import { registerTransfersCommands } from "./commands/transfers";
16
17
  import { createCliContext } from "./context";
17
18
  import { renderError } from "./output";
@@ -31,6 +32,7 @@ export async function run(argv, ctxOverride) {
31
32
  registerMigrateCommands(cli, ctx);
32
33
  registerSharingCommands(cli, ctx);
33
34
  registerStatusCommands(cli, ctx);
35
+ registerTokenCommands(cli, ctx);
34
36
  registerTransfersCommands(cli, ctx);
35
37
  registerAdminCommands(cli, ctx);
36
38
  cli.help();
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc,EAAE,WAAqB;IAC7D,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;IAC3B,MAAM,GAAG,GAAG,WAAW,IAAI,CAAC,MAAM,gBAAgB,EAAE,CAAC,CAAC;IAEtD,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC/B,uBAAuB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACxC,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9B,sBAAsB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACjC,oBAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IACrC,oBAAoB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC/B,uBAAuB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAClC,sBAAsB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACjC,uBAAuB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAClC,uBAAuB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAClC,sBAAsB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACjC,yBAAyB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACpC,qBAAqB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAEhC,GAAG,CAAC,IAAI,EAAE,CAAC;IACX,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAErB,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IAElC,IAAI,CAAC;QACH,MAAM,mBAAmB,EAAE,CAAC;QAC5B,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,mEAAmE;QACnE,4DAA4D;QAC5D,4DAA4D;QAC5D,+DAA+D;QAC/D,mEAAmE;QACnE,iEAAiE;QACjE,gEAAgE;QAChE,+DAA+D;QAC/D,gEAAgE;QAChE,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;YACvB,MAAM,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAChC,CAAC;aAAM,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YAC3D,2DAA2D;YAC3D,GAAG,CAAC,UAAU,EAAE,CAAC;QACnB,CAAC;aAAM,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrC,6DAA6D;YAC7D,wDAAwD;QAC1D,CAAC;aAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;YAChE,2DAA2D;YAC3D,iEAAiE;YACjE,+DAA+D;QACjE,CAAC;aAAM,CAAC;YACN,gEAAgE;YAChE,gEAAgE;YAChE,MAAM,mBAAmB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YAC1C,MAAM,IAAI,eAAe,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;QACD,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC/B,MAAM,eAAe,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,yDAAyD;QACzD,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;YACnC,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YACtC,OAAO,GAAG,CAAC,QAAQ,CAAC;QACtB,CAAC;QACD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;QACxE,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACtC,MAAM,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACnC,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "percher",
3
- "version": "0.5.16",
4
- "description": "CLI for the Percher hosting platform \u2014 publish apps with one command",
3
+ "version": "0.5.18",
4
+ "description": "CLI for the Percher hosting platform — publish apps with one command",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "percher": "./dist/bin/percher.js"
@@ -24,9 +24,9 @@
24
24
  "typecheck": "tsc --noEmit"
25
25
  },
26
26
  "dependencies": {
27
- "@percher/client": "^0.2.16",
28
- "@percher/core": "^0.4.18",
29
- "@percher/toml": "^0.1.5",
27
+ "@percher/client": "^0.2.18",
28
+ "@percher/core": "^0.4.21",
29
+ "@percher/toml": "^0.1.7",
30
30
  "cac": "^7.0.0",
31
31
  "picocolors": "^1.1.1"
32
32
  },