@antasphere/slideless 0.13.7 → 0.13.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bin.js +1236 -429
  2. package/package.json +4 -4
package/dist/bin.js CHANGED
@@ -3032,7 +3032,7 @@ var require_commander = __commonJS({
3032
3032
  // src/bin.ts
3033
3033
  import { createInterface } from "node:readline/promises";
3034
3034
 
3035
- // ../../node_modules/.pnpm/@antasphere+cli-core@0.5.0/node_modules/@antasphere/cli-core/dist/config.js
3035
+ // ../../node_modules/.pnpm/@antasphere+cli-core@0.6.0/node_modules/@antasphere/cli-core/dist/config.js
3036
3036
  import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3037
3037
  import { dirname, join } from "node:path";
3038
3038
  var HUB_TOOL = "hub";
@@ -3099,8 +3099,13 @@ function redactKey(key) {
3099
3099
  return "****";
3100
3100
  return `${key.slice(0, 13)}\u2026${key.slice(-4)}`;
3101
3101
  }
3102
- function lookupConnectKey(profile, hubProfileName) {
3103
- return profile?.connectKeys?.[hubProfileName]?.apiKey;
3102
+ function cachedConnectKey(profile, hubProfileName, hubEmail) {
3103
+ const entry = profile?.connectKeys?.[hubProfileName];
3104
+ const hub = hubEmail?.trim().toLowerCase();
3105
+ const minted = entry?.email?.trim().toLowerCase();
3106
+ if (!hub || !minted || hub !== minted)
3107
+ return void 0;
3108
+ return entry?.apiKey;
3104
3109
  }
3105
3110
  function storeConnectKey(env, tool, profileName, hubProfileName, entry, opts = {}) {
3106
3111
  const config2 = loadConfig(env, tool);
@@ -3131,7 +3136,7 @@ function removeConnectKey(env, tool, profileName, hubProfileName) {
3131
3136
  return true;
3132
3137
  }
3133
3138
 
3134
- // ../../node_modules/.pnpm/@antasphere+cli-core@0.5.0/node_modules/@antasphere/cli-core/dist/io.js
3139
+ // ../../node_modules/.pnpm/@antasphere+cli-core@0.6.0/node_modules/@antasphere/cli-core/dist/io.js
3135
3140
  async function ask(io, question) {
3136
3141
  if (!io.prompt) {
3137
3142
  throw new Error("This command is interactive \u2014 no prompt available (pass the value as a flag).");
@@ -3146,7 +3151,7 @@ function printJson(io, value) {
3146
3151
  `);
3147
3152
  }
3148
3153
 
3149
- // ../../node_modules/.pnpm/@antasphere+cli-core@0.5.0/node_modules/@antasphere/cli-core/dist/resolve.js
3154
+ // ../../node_modules/.pnpm/@antasphere+cli-core@0.6.0/node_modules/@antasphere/cli-core/dist/resolve.js
3150
3155
  var CliUsageError = class extends Error {
3151
3156
  exitCode;
3152
3157
  constructor(message, opts = {}) {
@@ -3251,7 +3256,7 @@ function resolveApiKey(opts) {
3251
3256
  return firstSet(opts.flag, opts.env[opts.envVar], opts.profile?.apiKey);
3252
3257
  }
3253
3258
 
3254
- // ../../node_modules/.pnpm/@antasphere+cli-core@0.5.0/node_modules/@antasphere/cli-core/dist/auth.js
3259
+ // ../../node_modules/.pnpm/@antasphere+cli-core@0.6.0/node_modules/@antasphere/cli-core/dist/auth.js
3255
3260
  var CliAuthError = class extends Error {
3256
3261
  status;
3257
3262
  code;
@@ -3306,7 +3311,7 @@ var CliAuthClient = class {
3306
3311
  }
3307
3312
  };
3308
3313
 
3309
- // ../../node_modules/.pnpm/@antasphere+cli-core@0.5.0/node_modules/@antasphere/cli-core/dist/connect.js
3314
+ // ../../node_modules/.pnpm/@antasphere+cli-core@0.6.0/node_modules/@antasphere/cli-core/dist/connect.js
3310
3315
  var CliConnectError = class extends CliAuthError {
3311
3316
  stage;
3312
3317
  constructor(stage, status, code, message, details) {
@@ -3393,7 +3398,7 @@ var CliConnectClient = class {
3393
3398
  }
3394
3399
  };
3395
3400
 
3396
- // ../../node_modules/.pnpm/@antasphere+cli-core@0.5.0/node_modules/@antasphere/cli-core/dist/connect-on-demand.js
3401
+ // ../../node_modules/.pnpm/@antasphere+cli-core@0.6.0/node_modules/@antasphere/cli-core/dist/connect-on-demand.js
3397
3402
  async function probeToolInstance(toolBaseUrl, fetchImpl) {
3398
3403
  const f = fetchImpl ?? globalThis.fetch.bind(globalThis);
3399
3404
  try {
@@ -3416,8 +3421,15 @@ async function probeToolInstance(toolBaseUrl, fetchImpl) {
3416
3421
  return null;
3417
3422
  }
3418
3423
  }
3419
- function activeHubProfile(env) {
3420
- return resolveProfile(loadConfig(env, HUB_TOOL), void 0);
3424
+ var HUB_URL_ENV = "ANTASPHERE_URL";
3425
+ function selectHubProfile(env, opts = {}) {
3426
+ const config2 = loadConfig(env, HUB_TOOL);
3427
+ const apiUrl = firstSet(env[HUB_URL_ENV]);
3428
+ if (apiUrl) {
3429
+ const { name, profile } = selectProfile({ config: config2, apiUrl, cloudUrl: opts.cloudUrl });
3430
+ return { name, profile };
3431
+ }
3432
+ return resolveProfile(config2, void 0);
3421
3433
  }
3422
3434
  function defaultMissingHubLogin(tool) {
3423
3435
  const envVar = `${tool.replace(/-/g, "_").toUpperCase()}_API_KEY`;
@@ -3438,11 +3450,11 @@ async function connectOnDemand(opts) {
3438
3450
  const toolBaseUrl = normalizeUrl(opts.toolBaseUrl);
3439
3451
  const messages = opts.messages ?? {};
3440
3452
  const { profileName } = opts;
3441
- const hub = activeHubProfile(opts.env);
3453
+ const hub = selectHubProfile(opts.env, { cloudUrl: opts.hubCloudUrl });
3442
3454
  const existing = loadConfig(opts.env, opts.tool).profiles[profileName];
3443
3455
  const { place, at } = placeOf(existing, toolBaseUrl, opts.cloudUrl);
3444
3456
  if (opts.cached !== false && place === "here" && hub.name) {
3445
- const cachedKey = lookupConnectKey(existing, hub.name);
3457
+ const cachedKey = cachedConnectKey(existing, hub.name, hub.profile?.email);
3446
3458
  if (cachedKey)
3447
3459
  return { outcome: "connected", key: cachedKey, cached: true };
3448
3460
  }
@@ -3450,7 +3462,7 @@ async function connectOnDemand(opts) {
3450
3462
  if (!probe?.cloud)
3451
3463
  return { outcome: "not_cloud" };
3452
3464
  const hubKey = firstSet(hub.profile?.apiKey);
3453
- const hubBaseUrl = firstSet(hub.profile?.baseUrl);
3465
+ const hubBaseUrl = firstSet(hub.profile?.baseUrl, opts.hubCloudUrl);
3454
3466
  if (!hubKey || !hubBaseUrl || !hub.name) {
3455
3467
  throw new CliUsageError(messages.missingHubLogin ?? defaultMissingHubLogin(opts.tool));
3456
3468
  }
@@ -3496,7 +3508,7 @@ async function connectOnDemand(opts) {
3496
3508
  }
3497
3509
  async function refreshConnectKey(opts) {
3498
3510
  assertToolNamespace(opts.tool);
3499
- const hub = activeHubProfile(opts.env);
3511
+ const hub = selectHubProfile(opts.env, { cloudUrl: opts.hubCloudUrl });
3500
3512
  const existing = loadConfig(opts.env, opts.tool).profiles[opts.profileName];
3501
3513
  const { place } = placeOf(existing, normalizeUrl(opts.toolBaseUrl), opts.cloudUrl);
3502
3514
  if (hub.name && place === "here")
@@ -3504,7 +3516,7 @@ async function refreshConnectKey(opts) {
3504
3516
  return connectOnDemand({ ...opts, cached: false });
3505
3517
  }
3506
3518
 
3507
- // ../../node_modules/.pnpm/@antasphere+cli-core@0.5.0/node_modules/@antasphere/cli-core/dist/migrate.js
3519
+ // ../../node_modules/.pnpm/@antasphere+cli-core@0.6.0/node_modules/@antasphere/cli-core/dist/migrate.js
3508
3520
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
3509
3521
  import { join as join2 } from "node:path";
3510
3522
  function migrateLegacyConfig(env, spec) {
@@ -3535,33 +3547,33 @@ function migrateLegacyConfig(env, spec) {
3535
3547
  return { migrated: true, from, to };
3536
3548
  }
3537
3549
 
3538
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/config.js
3550
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/config.js
3539
3551
  function createConfig(identity) {
3540
3552
  const TOOL = identity.tool;
3541
3553
  const LEGACY = { tool: TOOL, legacyDir: identity.legacyConfigDir };
3542
- function configPath2(env) {
3554
+ function configPath3(env) {
3543
3555
  return configPath(env, TOOL);
3544
3556
  }
3545
- function loadConfig3(env) {
3557
+ function loadConfig4(env) {
3546
3558
  try {
3547
3559
  migrateLegacyConfig(env, LEGACY);
3548
3560
  } catch {
3549
3561
  }
3550
3562
  return loadConfig(env, TOOL);
3551
3563
  }
3552
- function saveConfig3(env, config2) {
3564
+ function saveConfig4(env, config2) {
3553
3565
  return saveConfig(env, TOOL, config2);
3554
3566
  }
3555
- function clearConfig2(env) {
3567
+ function clearConfig3(env) {
3556
3568
  clearConfig(env, TOOL);
3557
3569
  }
3558
- function removeConnectKey2(env, profileName, hubProfileName) {
3570
+ function removeConnectKey3(env, profileName, hubProfileName) {
3559
3571
  return removeConnectKey(env, TOOL, profileName, hubProfileName);
3560
3572
  }
3561
- return { configPath: configPath2, loadConfig: loadConfig3, saveConfig: saveConfig3, clearConfig: clearConfig2, removeConnectKey: removeConnectKey2 };
3573
+ return { configPath: configPath3, loadConfig: loadConfig4, saveConfig: saveConfig4, clearConfig: clearConfig3, removeConnectKey: removeConnectKey3 };
3562
3574
  }
3563
3575
 
3564
- // ../../node_modules/.pnpm/@antasphere+chassis-sdk@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-sdk/dist/index.js
3576
+ // ../../node_modules/.pnpm/@antasphere+chassis-sdk@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-sdk/dist/index.js
3565
3577
  var PlatformApiError = class extends Error {
3566
3578
  status;
3567
3579
  code;
@@ -3752,6 +3764,32 @@ var ChassisClient = class {
3752
3764
  ssoCliConnect(req) {
3753
3765
  return this.request("POST", "/sso/cli-connect", req);
3754
3766
  }
3767
+ /**
3768
+ * Public, CLOUD EDITION only (404 on oss): download the tool's own CLI
3769
+ * package (a gzipped tarball, `instance().cli` names it) on a hub-minted
3770
+ * exchange token, the same token and the same one-time rule as
3771
+ * ssoCliConnect. The token rides in the body and the client's API key is
3772
+ * NEVER sent: the route refuses a machine credential (403
3773
+ * `endpoint_not_allowed`). Raw Response so the caller can stream it; a
3774
+ * non-2xx answer throws PlatformApiError (401 `invalid_token`, 404
3775
+ * `cli_not_packaged`, 404 `not_found` on an instance without the route).
3776
+ */
3777
+ async downloadCliPackage(req) {
3778
+ const { authorization: _credential, ...headers } = this.baseHeaders();
3779
+ const res = await this.fetchImpl(`${this.baseUrl}/api/v1/cli/package`, {
3780
+ method: "POST",
3781
+ headers: { ...headers, "content-type": "application/json" },
3782
+ credentials: "same-origin",
3783
+ signal: this.signal("download"),
3784
+ // Browser-only field; cast keeps this isomorphic under a Node lib.
3785
+ cache: "no-store",
3786
+ body: JSON.stringify(req)
3787
+ });
3788
+ if (!res.ok) {
3789
+ await this.parse(res);
3790
+ }
3791
+ return res;
3792
+ }
3755
3793
  /**
3756
3794
  * CLOUD EDITION only (404 on oss); sessions only (machines 403 — the
3757
3795
  * path is unlisted in the scope allowlist): single logout. The server
@@ -3767,16 +3805,16 @@ var ChassisClient = class {
3767
3805
  members(params = {}) {
3768
3806
  return this.request("GET", this.pathWithQuery("/members", params));
3769
3807
  }
3770
- updateMember(id, patch) {
3771
- return this.request("PATCH", `/members/${encodeURIComponent(id)}`, patch);
3808
+ updateMember(id2, patch) {
3809
+ return this.request("PATCH", `/members/${encodeURIComponent(id2)}`, patch);
3772
3810
  }
3773
3811
  /**
3774
3812
  * Admin: delete a member's account (GDPR erasure). Sessions only — the
3775
3813
  * endpoint is unlisted in the machine scope allowlist, so API keys 403.
3776
3814
  * Files the member uploaded stay with the workspace.
3777
3815
  */
3778
- deleteMember(id) {
3779
- return this.request("DELETE", `/members/${encodeURIComponent(id)}`);
3816
+ deleteMember(id2) {
3817
+ return this.request("DELETE", `/members/${encodeURIComponent(id2)}`);
3780
3818
  }
3781
3819
  /**
3782
3820
  * Remove a member from the workspace (admin+, sessions only): the
@@ -3784,16 +3822,16 @@ var ChassisClient = class {
3784
3822
  * deleted; the account stays. Invited back, the person starts with none.
3785
3823
  * Refused `hub_managed` on a hub-origin workspace (removal is the hub's).
3786
3824
  */
3787
- removeMember(id) {
3788
- return this.request("POST", `/members/${encodeURIComponent(id)}/remove`);
3825
+ removeMember(id2) {
3826
+ return this.request("POST", `/members/${encodeURIComponent(id2)}/remove`);
3789
3827
  }
3790
3828
  /**
3791
3829
  * Owner: mint a one-time password reset link for a member (SMTP-free
3792
3830
  * recovery). Refused for a per-resource guest and for anyone who also belongs
3793
3831
  * to another workspace — the minted credential is global (PRDCT-1354).
3794
3832
  */
3795
- createMemberResetLink(id, opts = {}) {
3796
- return this.request("POST", `/members/${encodeURIComponent(id)}/reset-link`, void 0, idempotencyHeader(opts));
3833
+ createMemberResetLink(id2, opts = {}) {
3834
+ return this.request("POST", `/members/${encodeURIComponent(id2)}/reset-link`, void 0, idempotencyHeader(opts));
3797
3835
  }
3798
3836
  /**
3799
3837
  * Owner: mint a one-time email change link for a member (SMTP-free email
@@ -3801,8 +3839,8 @@ var ChassisClient = class {
3801
3839
  * it with the target member only. Same refusals as the reset link (guest
3802
3840
  * targets, cross-workspace targets), plus the cloud edition closure.
3803
3841
  */
3804
- createMemberChangeEmailLink(id, req, opts = {}) {
3805
- return this.request("POST", `/members/${encodeURIComponent(id)}/change-email-link`, req, idempotencyHeader(opts));
3842
+ createMemberChangeEmailLink(id2, req, opts = {}) {
3843
+ return this.request("POST", `/members/${encodeURIComponent(id2)}/change-email-link`, req, idempotencyHeader(opts));
3806
3844
  }
3807
3845
  // ── Projects ──────────────────────────────────────────────────────────────
3808
3846
  // A project is a subgroup of the workspace with its own members and three
@@ -3817,35 +3855,35 @@ var ChassisClient = class {
3817
3855
  createProject(req, opts = {}) {
3818
3856
  return this.request("POST", "/projects", req, idempotencyHeader(opts));
3819
3857
  }
3820
- project(id) {
3821
- return this.request("GET", `/projects/${encodeURIComponent(id)}`);
3858
+ project(id2) {
3859
+ return this.request("GET", `/projects/${encodeURIComponent(id2)}`);
3822
3860
  }
3823
- updateProject(id, patch) {
3824
- return this.request("PATCH", `/projects/${encodeURIComponent(id)}`, patch);
3861
+ updateProject(id2, patch) {
3862
+ return this.request("PATCH", `/projects/${encodeURIComponent(id2)}`, patch);
3825
3863
  }
3826
- archiveProject(id) {
3827
- return this.request("POST", `/projects/${encodeURIComponent(id)}/archive`);
3864
+ archiveProject(id2) {
3865
+ return this.request("POST", `/projects/${encodeURIComponent(id2)}/archive`);
3828
3866
  }
3829
- unarchiveProject(id) {
3830
- return this.request("POST", `/projects/${encodeURIComponent(id)}/unarchive`);
3867
+ unarchiveProject(id2) {
3868
+ return this.request("POST", `/projects/${encodeURIComponent(id2)}/unarchive`);
3831
3869
  }
3832
- projectMembers(id, params = {}) {
3833
- return this.request("GET", this.pathWithQuery(`/projects/${encodeURIComponent(id)}/members`, params));
3870
+ projectMembers(id2, params = {}) {
3871
+ return this.request("GET", this.pathWithQuery(`/projects/${encodeURIComponent(id2)}/members`, params));
3834
3872
  }
3835
3873
  /**
3836
3874
  * Adds one of the workspace's own active members, by user id or by email,
3837
3875
  * or one of its teams by `teamId`: exactly one of the three. A team entry
3838
3876
  * gives every member of the team the role.
3839
3877
  */
3840
- addProjectMember(id, req, opts = {}) {
3841
- return this.request("POST", `/projects/${encodeURIComponent(id)}/members`, req, idempotencyHeader(opts));
3878
+ addProjectMember(id2, req, opts = {}) {
3879
+ return this.request("POST", `/projects/${encodeURIComponent(id2)}/members`, req, idempotencyHeader(opts));
3842
3880
  }
3843
- setProjectMemberRole(id, userId, role) {
3844
- return this.request("PATCH", `/projects/${encodeURIComponent(id)}/members/${encodeURIComponent(userId)}`, { role });
3881
+ setProjectMemberRole(id2, userId, role) {
3882
+ return this.request("PATCH", `/projects/${encodeURIComponent(id2)}/members/${encodeURIComponent(userId)}`, { role });
3845
3883
  }
3846
3884
  /** A manager removes anyone; any member removes themselves. */
3847
- removeProjectMember(id, userId) {
3848
- return this.request("DELETE", `/projects/${encodeURIComponent(id)}/members/${encodeURIComponent(userId)}`);
3885
+ removeProjectMember(id2, userId) {
3886
+ return this.request("DELETE", `/projects/${encodeURIComponent(id2)}/members/${encodeURIComponent(userId)}`);
3849
3887
  }
3850
3888
  /** Changes the role a team holds on a project (manager). */
3851
3889
  setProjectTeamRole(projectId, teamId, role) {
@@ -3864,30 +3902,79 @@ var ChassisClient = class {
3864
3902
  teams(params = {}) {
3865
3903
  return this.request("GET", this.pathWithQuery("/teams", params));
3866
3904
  }
3867
- team(id) {
3868
- return this.request("GET", `/teams/${encodeURIComponent(id)}`);
3905
+ team(id2) {
3906
+ return this.request("GET", `/teams/${encodeURIComponent(id2)}`);
3869
3907
  }
3870
3908
  /** Owner or admin. The slug is derived from the name when absent. */
3871
3909
  createTeam(req, opts = {}) {
3872
3910
  return this.request("POST", "/teams", req, idempotencyHeader(opts));
3873
3911
  }
3874
- updateTeam(id, patch) {
3875
- return this.request("PATCH", `/teams/${encodeURIComponent(id)}`, patch);
3912
+ updateTeam(id2, patch) {
3913
+ return this.request("PATCH", `/teams/${encodeURIComponent(id2)}`, patch);
3876
3914
  }
3877
3915
  /** The memberships stay; answers the team's final snapshot. */
3878
- deleteTeam(id) {
3879
- return this.request("DELETE", `/teams/${encodeURIComponent(id)}`);
3916
+ deleteTeam(id2) {
3917
+ return this.request("DELETE", `/teams/${encodeURIComponent(id2)}`);
3880
3918
  }
3881
- teamMembers(id, params = {}) {
3882
- return this.request("GET", this.pathWithQuery(`/teams/${encodeURIComponent(id)}/members`, params));
3919
+ teamMembers(id2, params = {}) {
3920
+ return this.request("GET", this.pathWithQuery(`/teams/${encodeURIComponent(id2)}/members`, params));
3883
3921
  }
3884
3922
  /** Seats one of the workspace's own active members, by user id or by email. */
3885
- addTeamMember(id, req, opts = {}) {
3886
- return this.request("POST", `/teams/${encodeURIComponent(id)}/members`, req, idempotencyHeader(opts));
3923
+ addTeamMember(id2, req, opts = {}) {
3924
+ return this.request("POST", `/teams/${encodeURIComponent(id2)}/members`, req, idempotencyHeader(opts));
3887
3925
  }
3888
3926
  /** Unseats a member; the workspace membership stays. */
3889
- removeTeamMember(id, userId) {
3890
- return this.request("DELETE", `/teams/${encodeURIComponent(id)}/members/${encodeURIComponent(userId)}`);
3927
+ removeTeamMember(id2, userId) {
3928
+ return this.request("DELETE", `/teams/${encodeURIComponent(id2)}/members/${encodeURIComponent(userId)}`);
3929
+ }
3930
+ // ── Webhooks ──────────────────────────────────────────────────────────────
3931
+ // URLs the workspace registers to be told, by a signed POST, when one of the
3932
+ // tool's events happens. Owners and admins manage them (a guest gets 403
3933
+ // `guest_forbidden`, a member 403 `forbidden`); every non-guest member reads
3934
+ // the catalog. A machine credential needs the tool's webhooks scope (the
3935
+ // catalog: its read scope). The signing secret is in two answers only, the
3936
+ // create and the rotation, and never again.
3937
+ /** The workspace's endpoints, newest first. */
3938
+ webhooks(params = {}) {
3939
+ return this.request("GET", this.pathWithQuery("/webhooks", params));
3940
+ }
3941
+ /** The event catalog: every event type, its subjects and the JSON Schema of its data. */
3942
+ webhookEvents() {
3943
+ return this.request("GET", "/webhooks/events");
3944
+ }
3945
+ /** Owner or admin. The answer carries the signing secret (`whsec_…`), shown once. */
3946
+ createWebhook(req, opts = {}) {
3947
+ return this.request("POST", "/webhooks", req, idempotencyHeader(opts));
3948
+ }
3949
+ webhook(id2) {
3950
+ return this.request("GET", `/webhooks/${encodeURIComponent(id2)}`);
3951
+ }
3952
+ /** Only the fields named change; at least one is required. */
3953
+ updateWebhook(id2, req) {
3954
+ return this.request("PATCH", `/webhooks/${encodeURIComponent(id2)}`, req);
3955
+ }
3956
+ /** Deletes the endpoint and its delivery history; answers its final snapshot. */
3957
+ deleteWebhook(id2) {
3958
+ return this.request("DELETE", `/webhooks/${encodeURIComponent(id2)}`);
3959
+ }
3960
+ /** A new signing secret, shown once; the previous one signs until `previousSecretExpiresAt`. */
3961
+ rotateWebhookSecret(id2) {
3962
+ return this.request("POST", `/webhooks/${encodeURIComponent(id2)}/rotate-secret`);
3963
+ }
3964
+ /** Sends a signed `webhook.ping` now; the outcome is on the answered delivery. */
3965
+ testWebhook(id2) {
3966
+ return this.request("POST", `/webhooks/${encodeURIComponent(id2)}/test`);
3967
+ }
3968
+ /** An endpoint's deliveries, newest first, optionally by status. */
3969
+ webhookDeliveries(id2, params = {}) {
3970
+ return this.request("GET", this.pathWithQuery(`/webhooks/${encodeURIComponent(id2)}/deliveries`, params, { status: params.status }));
3971
+ }
3972
+ webhookDelivery(id2, deliveryId) {
3973
+ return this.request("GET", `/webhooks/${encodeURIComponent(id2)}/deliveries/${encodeURIComponent(deliveryId)}`);
3974
+ }
3975
+ /** Queues the same event again (same `eventId`, same payload) as a new delivery. */
3976
+ redeliverWebhook(id2, deliveryId) {
3977
+ return this.request("POST", `/webhooks/${encodeURIComponent(id2)}/deliveries/${encodeURIComponent(deliveryId)}/redeliver`);
3891
3978
  }
3892
3979
  // ── Demo passes ───────────────────────────────────────────────────────────
3893
3980
  // A link that signs one member in without a password, for a demonstration.
@@ -3911,8 +3998,8 @@ var ChassisClient = class {
3911
3998
  return this.request("POST", "/demo/passes", req);
3912
3999
  }
3913
4000
  /** Owner: revoke a pass; revoking a revoked pass answers it again. */
3914
- revokeDemoPass(id) {
3915
- return this.request("DELETE", `/demo/passes/${encodeURIComponent(id)}`);
4001
+ revokeDemoPass(id2) {
4002
+ return this.request("DELETE", `/demo/passes/${encodeURIComponent(id2)}`);
3916
4003
  }
3917
4004
  /**
3918
4005
  * Anyone holding a pass's secret: sign in as its person. Served by the
@@ -3947,8 +4034,8 @@ var ChassisClient = class {
3947
4034
  createApiKey(req, opts = {}) {
3948
4035
  return this.request("POST", "/api-keys", req, idempotencyHeader(opts));
3949
4036
  }
3950
- revokeApiKey(id) {
3951
- return this.request("DELETE", `/api-keys/${encodeURIComponent(id)}`);
4037
+ revokeApiKey(id2) {
4038
+ return this.request("DELETE", `/api-keys/${encodeURIComponent(id2)}`);
3952
4039
  }
3953
4040
  // ── Invitations ───────────────────────────────────────────────────────────
3954
4041
  invitations(params = {}) {
@@ -3958,8 +4045,8 @@ var ChassisClient = class {
3958
4045
  createInvitation(req, opts = {}) {
3959
4046
  return this.request("POST", "/invitations", req, idempotencyHeader(opts));
3960
4047
  }
3961
- revokeInvitation(id) {
3962
- return this.request("DELETE", `/invitations/${encodeURIComponent(id)}`);
4048
+ revokeInvitation(id2) {
4049
+ return this.request("DELETE", `/invitations/${encodeURIComponent(id2)}`);
3963
4050
  }
3964
4051
  /** Public: resolves an invitation token for the acceptance page. */
3965
4052
  lookupInvitation(token) {
@@ -4012,15 +4099,15 @@ var ChassisClient = class {
4012
4099
  });
4013
4100
  return this.parse(res);
4014
4101
  }
4015
- deleteFile(id) {
4016
- return this.request("DELETE", `/files/${encodeURIComponent(id)}`);
4102
+ deleteFile(id2) {
4103
+ return this.request("DELETE", `/files/${encodeURIComponent(id2)}`);
4017
4104
  }
4018
- file(id) {
4019
- return this.request("GET", `/files/${encodeURIComponent(id)}`);
4105
+ file(id2) {
4106
+ return this.request("GET", `/files/${encodeURIComponent(id2)}`);
4020
4107
  }
4021
4108
  /** URL of the streamed (Range-capable) content endpoint for a file. */
4022
- fileContentUrl(id) {
4023
- return `${this.baseUrl}/api/v1/files/${encodeURIComponent(id)}/content`;
4109
+ fileContentUrl(id2) {
4110
+ return `${this.baseUrl}/api/v1/files/${encodeURIComponent(id2)}/content`;
4024
4111
  }
4025
4112
  /**
4026
4113
  * Downloads a file's bytes with the client's own headers (credential and
@@ -4028,8 +4115,8 @@ var ChassisClient = class {
4028
4115
  * answer throws PlatformApiError like every other method. A browser anchor
4029
4116
  * on `fileContentUrl` cannot carry `X-Workspace-Id` (PRDCT-2426).
4030
4117
  */
4031
- async downloadFileContent(id) {
4032
- return this.rawDownload(this.fileContentUrl(id));
4118
+ async downloadFileContent(id2) {
4119
+ return this.rawDownload(this.fileContentUrl(id2));
4033
4120
  }
4034
4121
  /** The shared body of the streamed-download methods (the asset download's shape). */
4035
4122
  async rawDownload(url2) {
@@ -4074,14 +4161,30 @@ var ChassisClient = class {
4074
4161
  }
4075
4162
  };
4076
4163
 
4077
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/workspace.js
4164
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/identity.js
4165
+ var DEFAULT_HUB_URL = "https://account.antasphere.com";
4166
+ function cliIdentity(identity) {
4167
+ return {
4168
+ bin: identity.cli.bin,
4169
+ tool: identity.slug,
4170
+ legacyConfigDir: identity.cli.legacyConfigDir,
4171
+ displayName: identity.displayName,
4172
+ envPrefix: identity.cli.envPrefix,
4173
+ keyPrefix: identity.apiKeyPrefix,
4174
+ exportScope: identity.scopes.dataExport,
4175
+ webhooksScope: identity.scopes.webhooks,
4176
+ cloudUrl: identity.cloud.url
4177
+ };
4178
+ }
4179
+
4180
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/workspace.js
4078
4181
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
4079
4182
  function isWorkspaceId(value) {
4080
4183
  return UUID_RE.test(value);
4081
4184
  }
4082
4185
  function orgIdOf(w) {
4083
- const id = w.centralAccountId;
4084
- return typeof id === "string" && id ? id : null;
4186
+ const id2 = w.centralAccountId;
4187
+ return typeof id2 === "string" && id2 ? id2 : null;
4085
4188
  }
4086
4189
  function workspaceLines(workspaces) {
4087
4190
  if (workspaces.length === 0)
@@ -4181,7 +4284,7 @@ ${workspaceLines(me.workspaces)}`;
4181
4284
  };
4182
4285
  }
4183
4286
 
4184
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/context.js
4287
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/context.js
4185
4288
  var CliApiRefusal = class extends CliUsageError {
4186
4289
  status;
4187
4290
  constructor(message, status) {
@@ -4220,19 +4323,19 @@ function printJson2(io, value) {
4220
4323
  var appliedContexts = /* @__PURE__ */ new WeakMap();
4221
4324
  function createContext(input) {
4222
4325
  const { identity, createClient } = input;
4223
- const { loadConfig: loadConfig3, removeConnectKey: removeConnectKey2 } = input.config;
4326
+ const { loadConfig: loadConfig4, removeConnectKey: removeConnectKey3 } = input.config;
4224
4327
  const { describeSelection, explainRefusal, pickWorkspaceSelection } = input.workspace;
4225
4328
  const unknownHint = `run \`${identity.bin} profiles\` to list them.`;
4226
- function resolveProfile2(config2, requested) {
4329
+ function resolveProfile3(config2, requested) {
4227
4330
  const { name, profile } = selectProfile({ config: config2, requested, cloudUrl: identity.cloudUrl, unknownHint });
4228
4331
  return { name, profile };
4229
4332
  }
4230
- function profileUrl2(profile) {
4333
+ function profileUrl3(profile) {
4231
4334
  return profile?.baseUrl ?? identity.cloudUrl;
4232
4335
  }
4233
4336
  function resolveContext2(cmd, io) {
4234
4337
  const opts = cmd.optsWithGlobals();
4235
- const config2 = loadConfig3(io.env);
4338
+ const config2 = loadConfig4(io.env);
4236
4339
  const apiUrl = opts.apiUrl ?? opts.url ?? io.env[`${identity.envPrefix}_URL`];
4237
4340
  const selected = selectProfile({
4238
4341
  config: config2,
@@ -4249,7 +4352,7 @@ function createContext(input) {
4249
4352
  profile,
4250
4353
  cloudUrl: identity.cloudUrl
4251
4354
  });
4252
- const sameProfileInstance = sameInstance(profileUrl2(profile), baseUrl);
4355
+ const sameProfileInstance = sameInstance(profileUrl3(profile), baseUrl);
4253
4356
  let apiKey = resolveApiKey({
4254
4357
  flag: opts.apiKey ?? stdinApiKeys.get(io),
4255
4358
  env: io.env,
@@ -4258,10 +4361,9 @@ function createContext(input) {
4258
4361
  });
4259
4362
  let credentialSource = opts.apiKey !== void 0 || stdinApiKeys.get(io) !== void 0 ? "flag" : io.env[`${identity.envPrefix}_API_KEY`] ? "env" : apiKey ? "profile" : "none";
4260
4363
  if (!apiKey && sameProfileInstance) {
4261
- const hub = activeHubProfile(io.env);
4262
- if (hub.name && !cachedForAnotherAccount(profile, hub.name, hub.profile?.email)) {
4263
- apiKey = lookupConnectKey(profile, hub.name);
4264
- }
4364
+ const hub = selectHubProfile(io.env, { cloudUrl: DEFAULT_HUB_URL });
4365
+ if (hub.name)
4366
+ apiKey = cachedConnectKey(profile, hub.name, hub.profile?.email);
4265
4367
  if (apiKey)
4266
4368
  credentialSource = "hub-cache";
4267
4369
  }
@@ -4289,12 +4391,6 @@ function createContext(input) {
4289
4391
  }
4290
4392
  return ctx;
4291
4393
  }
4292
- function cachedForAnotherAccount(profile, slot, hubEmail) {
4293
- const cached2 = profile?.connectKeys?.[slot]?.email;
4294
- if (!cached2 || !hubEmail)
4295
- return false;
4296
- return cached2.toLowerCase() !== hubEmail.toLowerCase();
4297
- }
4298
4394
  const NO_KEY_MESSAGE = `An API key is required. Sign in (\`${identity.bin} login\`), pass --api-key, or set ${identity.envPrefix}_API_KEY.`;
4299
4395
  const MISSING_HUB_LOGIN_MESSAGE = `This ${identity.displayName} instance signs in through Antasphere. Run \`${identity.bin} login\` once (or \`antasphere login\`), then retry \u2014 or pass --api-key <${identity.keyPrefix}_\u2026> / set ${identity.envPrefix}_API_KEY.`;
4300
4396
  function connectOptions(ctx) {
@@ -4304,6 +4400,10 @@ function createContext(input) {
4304
4400
  toolBaseUrl: ctx.baseUrl,
4305
4401
  // A profile with no baseUrl of its own is at the cloud URL (cli-core 0.5.0).
4306
4402
  cloudUrl: identity.cloudUrl,
4403
+ // The same for a hub profile (cli-core 0.6.0, verifier round 1, F4):
4404
+ // one with no baseUrl is at the default hub, so ANTASPHERE_URL naming
4405
+ // that hub finds it, and the slot it names is the one this kit reads.
4406
+ hubCloudUrl: DEFAULT_HUB_URL,
4307
4407
  profileName: ctx.profileName ?? CLOUD_PROFILE,
4308
4408
  env: io.env,
4309
4409
  // Thread the injected fetch so the probe + exchange stay on the test
@@ -4330,9 +4430,10 @@ function createContext(input) {
4330
4430
  const outcome = await refreshConnectKey(connectOptions(ctx));
4331
4431
  if (outcome.outcome === "not_cloud")
4332
4432
  return res;
4433
+ ctx.io.err.write("The cached key was refused; signed in again through Antasphere.\n");
4434
+ healHubAddress(ctx, outcome);
4333
4435
  ctx.apiKey = outcome.key;
4334
4436
  ctx.credentialSource = "hub-exchange";
4335
- ctx.io.err.write("The cached key was refused; signed in again through Antasphere.\n");
4336
4437
  const headers = new Headers(init?.headers);
4337
4438
  headers.set("authorization", `Bearer ${outcome.key}`);
4338
4439
  return base(input2, { ...init, headers });
@@ -4348,9 +4449,9 @@ function createContext(input) {
4348
4449
  const selection = ctx.workspaceSelection;
4349
4450
  if (!selection || ctx.workspaceId !== void 0)
4350
4451
  return;
4351
- const id = isWorkspaceId(selection.value) ? selection.value : matchWorkspace((await ctx.client.me()).workspaces, selection.value).id;
4352
- ctx.client.setWorkspace(id);
4353
- ctx.workspaceId = id;
4452
+ const id2 = isWorkspaceId(selection.value) ? selection.value : matchWorkspace((await ctx.client.me()).workspaces, selection.value).id;
4453
+ ctx.client.setWorkspace(id2);
4454
+ ctx.workspaceId = id2;
4354
4455
  appliedContexts.set(ctx.io, ctx);
4355
4456
  }
4356
4457
  function workspaceSource(ctx) {
@@ -4387,26 +4488,49 @@ function createContext(input) {
4387
4488
  const noun = selection.kind === "org" ? "organization" : "workspace";
4388
4489
  return ` (looked in the ${noun} "${selection.value}", selected by ${describeSelection(selection)})`;
4389
4490
  }
4491
+ async function connect(ctx, overrides = {}) {
4492
+ const outcome = await connectOnDemand({ ...connectOptions(ctx), ...overrides });
4493
+ healHubAddress(ctx, outcome);
4494
+ return outcome;
4495
+ }
4496
+ function healHubAddress(ctx, outcome) {
4497
+ if (outcome.outcome !== "connected" || outcome.cached || !outcome.result)
4498
+ return;
4499
+ const answered = firstSet(outcome.result.user.email);
4500
+ if (!answered)
4501
+ return;
4502
+ const hub = selectHubProfile(ctx.io.env, { cloudUrl: DEFAULT_HUB_URL });
4503
+ const hubConfig = loadConfig(ctx.io.env, HUB_TOOL);
4504
+ const stored = hub.name ? hubConfig.profiles[hub.name] : void 0;
4505
+ const had = firstSet(stored?.email);
4506
+ if (!hub.name || !stored || had?.toLowerCase() === answered.toLowerCase())
4507
+ return;
4508
+ hubConfig.profiles[hub.name] = { ...stored, email: answered };
4509
+ saveConfig(ctx.io.env, HUB_TOOL, hubConfig);
4510
+ if (had) {
4511
+ ctx.io.err.write(`The Antasphere login's address is now ${answered}, replaced from ${had} (the hub's own answer).
4512
+ `);
4513
+ }
4514
+ }
4390
4515
  async function connectForKey(ctx) {
4391
4516
  const { io } = ctx;
4392
- const hub = activeHubProfile(io.env);
4517
+ const hub = selectHubProfile(io.env, { cloudUrl: DEFAULT_HUB_URL });
4393
4518
  if (ctx.profileName && hub.name) {
4394
- const profile = loadConfig3(io.env).profiles[ctx.profileName];
4395
- if (cachedForAnotherAccount(profile, hub.name, hub.profile?.email)) {
4396
- const stale = profile?.connectKeys?.[hub.name];
4397
- if (stale) {
4398
- io.err.write(`The ${identity.displayName} key cached for ${stale.email ?? "another Antasphere login"} is retired: the Antasphere login is now ${hub.profile?.email ?? "another account"}.
4399
- `);
4400
- const auth = new CliAuthClient({
4401
- baseUrl: profileUrl2(profile),
4402
- ...io.fetch ? { fetch: io.fetch } : {}
4403
- });
4404
- await auth.revoke(stale.apiKey).catch(() => void 0);
4405
- removeConnectKey2(io.env, ctx.profileName, hub.name);
4406
- }
4519
+ const profile = loadConfig4(io.env).profiles[ctx.profileName];
4520
+ const stale = profile?.connectKeys?.[hub.name];
4521
+ if (stale && !cachedConnectKey(profile, hub.name, hub.profile?.email)) {
4522
+ const hubEmail = firstSet(hub.profile?.email);
4523
+ io.err.write(`The ${identity.displayName} key cached for ${firstSet(stale.email) ?? "an unknown login"} is retired: ` + (hubEmail ? `the Antasphere login is now ${hubEmail}.
4524
+ ` : "the Antasphere login carries no address to match it with.\n"));
4525
+ const auth = new CliAuthClient({
4526
+ baseUrl: profileUrl3(profile),
4527
+ ...io.fetch ? { fetch: io.fetch } : {}
4528
+ });
4529
+ await auth.revoke(stale.apiKey).catch(() => void 0);
4530
+ removeConnectKey3(io.env, ctx.profileName, hub.name);
4407
4531
  }
4408
4532
  }
4409
- const outcome = await connectOnDemand(connectOptions(ctx));
4533
+ const outcome = await connect(ctx);
4410
4534
  if (outcome.outcome === "not_cloud") {
4411
4535
  throw new CliUsageError(NO_KEY_MESSAGE);
4412
4536
  }
@@ -4421,14 +4545,15 @@ function createContext(input) {
4421
4545
  return outcome.key;
4422
4546
  }
4423
4547
  return {
4424
- resolveProfile: resolveProfile2,
4548
+ resolveProfile: resolveProfile3,
4425
4549
  resolveContext: resolveContext2,
4426
4550
  requireApiKey: requireApiKey2,
4427
4551
  workspaceSource,
4428
4552
  explainWorkspaceRefusal,
4429
4553
  workspaceNotFoundHint,
4430
- profileUrl: profileUrl2,
4431
- connectOptions
4554
+ profileUrl: profileUrl3,
4555
+ connectOptions,
4556
+ connect
4432
4557
  };
4433
4558
  }
4434
4559
  async function drainPages(first, fetchPage) {
@@ -4475,7 +4600,7 @@ var {
4475
4600
  Help
4476
4601
  } = import_index.default;
4477
4602
 
4478
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/stdin.js
4603
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/stdin.js
4479
4604
  var claims = /* @__PURE__ */ new WeakMap();
4480
4605
  async function readAllStdin() {
4481
4606
  const chunks = [];
@@ -4496,9 +4621,8 @@ async function readSecretFromStdin(io, claimant) {
4496
4621
  return value;
4497
4622
  }
4498
4623
 
4499
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/auth.js
4500
- var HUB_URL_ENV = "ANTASPHERE_URL";
4501
- var DEFAULT_HUB_URL = "https://account.antasphere.com";
4624
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/auth.js
4625
+ var HUB_URL_ENV2 = "ANTASPHERE_URL";
4502
4626
  function describeCredential(source, profileName) {
4503
4627
  switch (source) {
4504
4628
  case "flag":
@@ -4530,10 +4654,10 @@ function organizationsLine(me) {
4530
4654
  `;
4531
4655
  }
4532
4656
  function registerAuthCommands(kit, program2, io) {
4533
- const { identity, createClient, clearConfig: clearConfig2, configPath: configPath2, connectOptions, loadConfig: loadConfig3, profileUrl: profileUrl2, removeConnectKey: removeConnectKey2, requireApiKey: requireApiKey2, resolveContext: resolveContext2, saveConfig: saveConfig3, workspaceSource } = kit;
4657
+ const { identity, createClient, clearConfig: clearConfig3, configPath: configPath3, connect, loadConfig: loadConfig4, profileUrl: profileUrl3, removeConnectKey: removeConnectKey3, requireApiKey: requireApiKey2, resolveContext: resolveContext2, saveConfig: saveConfig4, workspaceSource } = kit;
4534
4658
  const { describeSource } = kit.workspace;
4535
4659
  function saveProfileKey(profileName, baseUrl, apiKey, email3) {
4536
- const config3 = loadConfig3(io.env);
4660
+ const config3 = loadConfig4(io.env);
4537
4661
  const previous = config3.profiles[profileName];
4538
4662
  config3.profiles[profileName] = {
4539
4663
  ...previous,
@@ -4542,25 +4666,25 @@ function registerAuthCommands(kit, program2, io) {
4542
4666
  ...email3 ? { email: email3 } : {}
4543
4667
  };
4544
4668
  config3.activeProfile = profileName;
4545
- return saveConfig3(io.env, config3);
4669
+ return saveConfig4(io.env, config3);
4546
4670
  }
4547
4671
  function activate(profileName, baseUrl) {
4548
- const config3 = loadConfig3(io.env);
4672
+ const config3 = loadConfig4(io.env);
4549
4673
  config3.profiles[profileName] = { ...config3.profiles[profileName], baseUrl: normalizeUrl(baseUrl) };
4550
4674
  config3.activeProfile = profileName;
4551
- return saveConfig3(io.env, config3);
4675
+ return saveConfig4(io.env, config3);
4552
4676
  }
4553
4677
  async function hubLogin(opts) {
4554
4678
  const hubConfig = loadConfig(io.env, HUB_TOOL);
4555
4679
  const selected = selectProfile({
4556
4680
  config: hubConfig,
4557
- apiUrl: io.env[HUB_URL_ENV],
4681
+ apiUrl: io.env[HUB_URL_ENV2],
4558
4682
  cloudUrl: DEFAULT_HUB_URL
4559
4683
  });
4560
4684
  const profile = selected.name ?? CLOUD_PROFILE;
4561
4685
  const hubUrl = resolveBaseUrl({
4562
4686
  env: io.env,
4563
- envVar: HUB_URL_ENV,
4687
+ envVar: HUB_URL_ENV2,
4564
4688
  profile: selected.profile,
4565
4689
  cloudUrl: DEFAULT_HUB_URL
4566
4690
  });
@@ -4609,8 +4733,8 @@ function registerAuthCommands(kit, program2, io) {
4609
4733
  const profileName = ctx.profileName ?? CLOUD_PROFILE;
4610
4734
  const { baseUrl } = ctx;
4611
4735
  const saved = ctx.config.profiles[profileName];
4612
- if (saved && !sameInstance(profileUrl2(saved), baseUrl)) {
4613
- throw new CliUsageError(`Profile "${profileName}" is the instance ${profileUrl2(saved)}, and this login targets ${baseUrl}. Drop --profile to sign in on the profile of ${baseUrl}, or drop --api-url to sign in on "${profileName}".`);
4736
+ if (saved && !sameInstance(profileUrl3(saved), baseUrl)) {
4737
+ throw new CliUsageError(`Profile "${profileName}" is the instance ${profileUrl3(saved)}, and this login targets ${baseUrl}. Drop --profile to sign in on the profile of ${baseUrl}, or drop --api-url to sign in on "${profileName}".`);
4614
4738
  }
4615
4739
  const pasted = globals.apiKey ?? stdinApiKey(io);
4616
4740
  if (pasted !== void 0) {
@@ -4637,35 +4761,37 @@ ${organizationsLine(me2)}`);
4637
4761
  }
4638
4762
  const probe = await probeToolInstance(baseUrl, io.fetch);
4639
4763
  if (probe?.cloud) {
4640
- let hub = activeHubProfile(io.env);
4641
- const stored = hub.profile?.apiKey ? hub.profile.email : void 0;
4642
- const switching = Boolean(stored) && opts.email !== void 0 && opts.email.toLowerCase() !== stored.toLowerCase();
4764
+ let hub = selectHubProfile(io.env, { cloudUrl: DEFAULT_HUB_URL });
4765
+ const hasKey = Boolean(hub.profile?.apiKey);
4766
+ const stored = hasKey ? firstSet(hub.profile?.email) : void 0;
4767
+ const switching = hasKey && opts.email !== void 0 && (stored === void 0 || opts.email.toLowerCase() !== stored.toLowerCase());
4643
4768
  if (switching) {
4644
- io.err.write(`Replacing the Antasphere login ${stored} with ${opts.email}.
4769
+ io.err.write(stored ? `Replacing the Antasphere login ${stored} with ${opts.email}.
4770
+ ` : `Signing in as ${opts.email}: the stored Antasphere login carries no address.
4645
4771
  `);
4646
4772
  }
4647
4773
  if (!hub.profile?.apiKey || switching)
4648
4774
  await hubLogin(opts);
4649
- hub = activeHubProfile(io.env);
4650
- const stale = hub.name ? loadConfig3(io.env).profiles[profileName]?.connectKeys?.[hub.name] : void 0;
4775
+ hub = selectHubProfile(io.env, { cloudUrl: DEFAULT_HUB_URL });
4776
+ const stale = hub.name ? loadConfig4(io.env).profiles[profileName]?.connectKeys?.[hub.name] : void 0;
4651
4777
  if (stale && hub.name) {
4652
4778
  const auth = new CliAuthClient({
4653
- baseUrl: profileUrl2(loadConfig3(io.env).profiles[profileName]),
4779
+ baseUrl: profileUrl3(loadConfig4(io.env).profiles[profileName]),
4654
4780
  ...io.fetch ? { fetch: io.fetch } : {}
4655
4781
  });
4656
4782
  await auth.revoke(stale.apiKey).catch(() => void 0);
4657
- removeConnectKey2(io.env, profileName, hub.name);
4783
+ removeConnectKey3(io.env, profileName, hub.name);
4658
4784
  }
4659
4785
  let outcome;
4660
4786
  try {
4661
- outcome = await connectOnDemand({ ...connectOptions(ctx), profileName, cached: false });
4787
+ outcome = await connect(ctx, { profileName, cached: false });
4662
4788
  } catch (e) {
4663
4789
  if (!(e instanceof CliUsageError) || !/rejected/.test(e.message))
4664
4790
  throw e;
4665
4791
  io.err.write("The stored Antasphere login was rejected: signing in again.\n");
4666
4792
  await hubLogin(opts);
4667
- hub = activeHubProfile(io.env);
4668
- outcome = await connectOnDemand({ ...connectOptions(ctx), profileName, cached: false });
4793
+ hub = selectHubProfile(io.env, { cloudUrl: DEFAULT_HUB_URL });
4794
+ outcome = await connect(ctx, { profileName, cached: false });
4669
4795
  }
4670
4796
  if (outcome.outcome === "not_cloud") {
4671
4797
  throw new CliUsageError(`${baseUrl} stopped answering as an Antasphere-cloud instance; try again.`);
@@ -4709,11 +4835,11 @@ API key "${minted.keyName}" (${redactKey(minted.key)}) saved to profile "${profi
4709
4835
  ${organizationsLine(me)}`);
4710
4836
  });
4711
4837
  async function hubLogout() {
4712
- const hub = activeHubProfile(io.env);
4838
+ const hub = selectHubProfile(io.env, { cloudUrl: DEFAULT_HUB_URL });
4713
4839
  if (!hub.name || !hub.profile?.apiKey)
4714
4840
  return null;
4715
4841
  const auth = new CliAuthClient({
4716
- baseUrl: profileUrl2(hub.profile),
4842
+ baseUrl: hub.profile.baseUrl?.trim() || DEFAULT_HUB_URL,
4717
4843
  ...io.fetch ? { fetch: io.fetch } : {}
4718
4844
  });
4719
4845
  let revoked = false;
@@ -4737,7 +4863,7 @@ ${organizationsLine(me)}`);
4737
4863
  const ctx = resolveContext2(cmd, io);
4738
4864
  const profileName = ctx.profileName;
4739
4865
  const profile = profileName ? ctx.config.profiles[profileName] : void 0;
4740
- const hubLogin2 = activeHubProfile(io.env).profile;
4866
+ const hubLogin2 = selectHubProfile(io.env, { cloudUrl: DEFAULT_HUB_URL }).profile;
4741
4867
  if (!profileName || !profile) {
4742
4868
  if (hubLogin2?.apiKey) {
4743
4869
  if (opts.all) {
@@ -4752,7 +4878,7 @@ ${organizationsLine(me)}`);
4752
4878
  }
4753
4879
  throw new CliUsageError("No profile to log out of.");
4754
4880
  }
4755
- const baseUrl = profileUrl2(profile);
4881
+ const baseUrl = profileUrl3(profile);
4756
4882
  const auth = new CliAuthClient({ baseUrl, ...io.fetch ? { fetch: io.fetch } : {} });
4757
4883
  let revoked = 0;
4758
4884
  let refused = 0;
@@ -4776,16 +4902,16 @@ ${organizationsLine(me)}`);
4776
4902
  const slots = Object.entries(profile.connectKeys ?? {});
4777
4903
  for (const [slot, entry] of slots) {
4778
4904
  await revoke(entry.apiKey, `the key of the Antasphere login "${slot}"`);
4779
- removeConnectKey2(io.env, profileName, slot);
4905
+ removeConnectKey3(io.env, profileName, slot);
4780
4906
  }
4781
4907
  if (profile.apiKey)
4782
4908
  await revoke(profile.apiKey, "the profile key");
4783
- const config3 = loadConfig3(io.env);
4909
+ const config3 = loadConfig4(io.env);
4784
4910
  const current = config3.profiles[profileName];
4785
4911
  if (current) {
4786
4912
  delete current.apiKey;
4787
4913
  delete current.email;
4788
- saveConfig3(io.env, config3);
4914
+ saveConfig4(io.env, config3);
4789
4915
  }
4790
4916
  const ended = opts.all ? await hubLogout() : null;
4791
4917
  if (globals.json) {
@@ -4813,7 +4939,7 @@ ${organizationsLine(me)}`);
4813
4939
  await requireApiKey2(ctx);
4814
4940
  const me = await ctx.client.me();
4815
4941
  const source = workspaceSource(ctx);
4816
- const hub = activeHubProfile(io.env);
4942
+ const hub = selectHubProfile(io.env, { cloudUrl: DEFAULT_HUB_URL });
4817
4943
  const hubLine = hubLoginLine(ctx, hub.profile);
4818
4944
  if (ctx.json) {
4819
4945
  return printJson2(io, {
@@ -4861,7 +4987,7 @@ ${organizationsLine(me)}`);
4861
4987
  });
4862
4988
  program2.command("use <profile>").description("Switch the active profile (the instance the commands run against)").action(async (name, _opts, cmd) => {
4863
4989
  const globals = cmd.optsWithGlobals();
4864
- const config3 = loadConfig3(io.env);
4990
+ const config3 = loadConfig4(io.env);
4865
4991
  if (!config3.profiles[name]) {
4866
4992
  if (name !== CLOUD_PROFILE) {
4867
4993
  throw new CliUsageError(`Unknown profile "${name}" \u2014 run \`${identity.bin} profiles\`.`);
@@ -4869,16 +4995,16 @@ ${organizationsLine(me)}`);
4869
4995
  config3.profiles[name] = { baseUrl: normalizeUrl(identity.cloudUrl) };
4870
4996
  }
4871
4997
  config3.activeProfile = name;
4872
- saveConfig3(io.env, config3);
4998
+ saveConfig4(io.env, config3);
4873
4999
  if (globals.json)
4874
5000
  return printJson2(io, { activeProfile: name });
4875
- io.out.write(`Active profile: ${name} (${profileUrl2(config3.profiles[name])})
5001
+ io.out.write(`Active profile: ${name} (${profileUrl3(config3.profiles[name])})
4876
5002
  `);
4877
5003
  });
4878
5004
  program2.command("profiles").description("List the profiles (one per instance) and how each signs in").action(async (_opts, cmd) => {
4879
5005
  const globals = cmd.optsWithGlobals();
4880
- const config3 = loadConfig3(io.env);
4881
- const hub = activeHubProfile(io.env);
5006
+ const config3 = loadConfig4(io.env);
5007
+ const hub = selectHubProfile(io.env, { cloudUrl: DEFAULT_HUB_URL });
4882
5008
  const rows = Object.entries(config3.profiles);
4883
5009
  if (!config3.profiles[CLOUD_PROFILE])
4884
5010
  rows.unshift([CLOUD_PROFILE, { baseUrl: normalizeUrl(identity.cloudUrl) }]);
@@ -4890,8 +5016,9 @@ ${organizationsLine(me)}`);
4890
5016
  if (entry)
4891
5017
  return { kind: "hub", text: `via Antasphere${entry.email ? ` (${entry.email})` : ""}` };
4892
5018
  const others = Object.keys(p.connectKeys ?? {});
5019
+ const chosen = firstSet(io.env[HUB_URL_ENV2]) ? "not the one ANTASPHERE_URL names" : "not the active one";
4893
5020
  if (others.length > 0)
4894
- return { kind: "hub", text: `via Antasphere (login "${others.join('", "')}", not the active one)` };
5021
+ return { kind: "hub", text: `via Antasphere (login "${others.join('", "')}", ${chosen})` };
4895
5022
  return { kind: "none", text: "(not signed in)" };
4896
5023
  };
4897
5024
  if (globals.json) {
@@ -4903,7 +5030,7 @@ ${organizationsLine(me)}`);
4903
5030
  return [
4904
5031
  n,
4905
5032
  {
4906
- baseUrl: profileUrl2(p),
5033
+ baseUrl: profileUrl3(p),
4907
5034
  saved: Boolean(config3.profiles[n]),
4908
5035
  credential: cred.kind,
4909
5036
  apiKey: p.apiKey ? redactKey(p.apiKey) : null,
@@ -4914,20 +5041,20 @@ ${organizationsLine(me)}`);
4914
5041
  }))
4915
5042
  });
4916
5043
  }
4917
- io.out.write(table(rows.map(([n, p]) => [activeName === n ? "*" : " ", n, profileUrl2(p), credentialOf(p).text])));
5044
+ io.out.write(table(rows.map(([n, p]) => [activeName === n ? "*" : " ", n, profileUrl3(p), credentialOf(p).text])));
4918
5045
  });
4919
5046
  const config2 = program2.command("config").description("Inspect or reset the CLI config file");
4920
5047
  config2.command("show").description("Show the config path, active profile, and redacted keys").action(async (_opts, cmd) => {
4921
5048
  const globals = cmd.optsWithGlobals();
4922
- const cfg = loadConfig3(io.env);
4923
- const path = configPath2(io.env);
5049
+ const cfg = loadConfig4(io.env);
5050
+ const path = configPath3(io.env);
4924
5051
  const redacted = {
4925
5052
  path,
4926
5053
  activeProfile: cfg.activeProfile ?? null,
4927
5054
  profiles: Object.fromEntries(Object.entries(cfg.profiles).map(([n, p]) => [
4928
5055
  n,
4929
5056
  {
4930
- baseUrl: profileUrl2(p),
5057
+ baseUrl: profileUrl3(p),
4931
5058
  apiKey: p.apiKey ? redactKey(p.apiKey) : null,
4932
5059
  email: p.email ?? null,
4933
5060
  // Hub-connected keys (one per hub profile), redacted like the rest.
@@ -4944,14 +5071,14 @@ ${organizationsLine(me)}`);
4944
5071
  });
4945
5072
  config2.command("clear").description("Delete the config file (all profiles and stored keys)").action(async (_opts, cmd) => {
4946
5073
  const globals = cmd.optsWithGlobals();
4947
- clearConfig2(io.env);
5074
+ clearConfig3(io.env);
4948
5075
  if (globals.json)
4949
5076
  return printJson2(io, { cleared: true });
4950
5077
  io.out.write("Config cleared.\n");
4951
5078
  });
4952
5079
  }
4953
5080
 
4954
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/workspaces.js
5081
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/workspaces.js
4955
5082
  function registerWorkspaceCommands(kit, program2, io) {
4956
5083
  const { requireApiKey: requireApiKey2, resolveContext: resolveContext2, workspaceSource } = kit;
4957
5084
  const { describeSelection } = kit.workspace;
@@ -5023,7 +5150,7 @@ function registerWorkspaceCommands(kit, program2, io) {
5023
5150
  });
5024
5151
  }
5025
5152
 
5026
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/teams.js
5153
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/teams.js
5027
5154
  function explainTeamRefusal(e, ctx) {
5028
5155
  switch (e.code) {
5029
5156
  case "forbidden":
@@ -5227,7 +5354,7 @@ ${teamLines(team)}`);
5227
5354
  });
5228
5355
  }
5229
5356
 
5230
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/projects.js
5357
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/projects.js
5231
5358
  var ROLES = ["viewer", "editor", "manager"];
5232
5359
  function parseRole(value) {
5233
5360
  if (ROLES.includes(value))
@@ -5350,10 +5477,10 @@ function registerProjectCommands(kit, program2, io) {
5350
5477
  `);
5351
5478
  }
5352
5479
  });
5353
- projects.command("get <id>").description("Show one project, with your own role on it").action(async (id, _opts, cmd) => {
5480
+ projects.command("get <id>").description("Show one project, with your own role on it").action(async (id2, _opts, cmd) => {
5354
5481
  const ctx = resolveContext2(cmd, io);
5355
5482
  await requireApiKey2(ctx);
5356
- const project = await explained("project", () => ctx.client.project(id));
5483
+ const project = await explained("project", () => ctx.client.project(id2));
5357
5484
  if (ctx.json)
5358
5485
  return printJson2(io, project);
5359
5486
  io.out.write(projectLines(project));
@@ -5372,7 +5499,7 @@ function registerProjectCommands(kit, program2, io) {
5372
5499
  io.out.write(`Created project "${project.name}".
5373
5500
  ${projectLines(project)}`);
5374
5501
  });
5375
- projects.command("update <id>").description("Change a project's name, description or metadata (manager)").option("--name <name>", "rename the project").option("--description <text>", "replace the description").option("--clear-description", "remove the description", false).option("--metadata <json>", "replace the whole metadata object (a JSON object)").action(async (id, opts, cmd) => {
5502
+ projects.command("update <id>").description("Change a project's name, description or metadata (manager)").option("--name <name>", "rename the project").option("--description <text>", "replace the description").option("--clear-description", "remove the description", false).option("--metadata <json>", "replace the whole metadata object (a JSON object)").action(async (id2, opts, cmd) => {
5376
5503
  if (opts.description !== void 0 && opts.clearDescription) {
5377
5504
  throw new CliUsageError("Pass either --description <text> or --clear-description, not both.");
5378
5505
  }
@@ -5386,25 +5513,25 @@ ${projectLines(project)}`);
5386
5513
  }
5387
5514
  const ctx = resolveContext2(cmd, io);
5388
5515
  await requireApiKey2(ctx);
5389
- const project = await explained("project", () => ctx.client.updateProject(id, patch));
5516
+ const project = await explained("project", () => ctx.client.updateProject(id2, patch));
5390
5517
  if (ctx.json)
5391
5518
  return printJson2(io, project);
5392
5519
  io.out.write(`Updated project "${project.name}".
5393
5520
  ${projectLines(project)}`);
5394
5521
  });
5395
- projects.command("archive <id>").description("Archive a project: out of the default list and read-only (manager). Never deleted").action(async (id, _opts, cmd) => {
5522
+ projects.command("archive <id>").description("Archive a project: out of the default list and read-only (manager). Never deleted").action(async (id2, _opts, cmd) => {
5396
5523
  const ctx = resolveContext2(cmd, io);
5397
5524
  await requireApiKey2(ctx);
5398
- const project = await explained("project", () => ctx.client.archiveProject(id));
5525
+ const project = await explained("project", () => ctx.client.archiveProject(id2));
5399
5526
  if (ctx.json)
5400
5527
  return printJson2(io, project);
5401
5528
  io.out.write(`Archived "${project.name}". It is read-only and out of \`projects list\` until you unarchive it.
5402
5529
  `);
5403
5530
  });
5404
- projects.command("unarchive <id>").description("Bring an archived project back (manager)").action(async (id, _opts, cmd) => {
5531
+ projects.command("unarchive <id>").description("Bring an archived project back (manager)").action(async (id2, _opts, cmd) => {
5405
5532
  const ctx = resolveContext2(cmd, io);
5406
5533
  await requireApiKey2(ctx);
5407
- const project = await explained("project", () => ctx.client.unarchiveProject(id));
5534
+ const project = await explained("project", () => ctx.client.unarchiveProject(id2));
5408
5535
  if (ctx.json)
5409
5536
  return printJson2(io, project);
5410
5537
  io.out.write(`Unarchived "${project.name}". It is writable again.
@@ -5502,6 +5629,308 @@ ${projectLines(project)}`);
5502
5629
  });
5503
5630
  }
5504
5631
 
5632
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/webhooks.js
5633
+ function explainWebhookRefusal(e, lookup, identity) {
5634
+ switch (e.code) {
5635
+ case "forbidden":
5636
+ return e.status === 403 ? "Only an owner or an admin manages webhooks." : null;
5637
+ case "guest_forbidden":
5638
+ return "You are a guest of this workspace, and guests do not manage its webhooks.";
5639
+ case "not_found":
5640
+ if (lookup === "catalog")
5641
+ return null;
5642
+ return lookup === "delivery" ? "No such delivery." : "No such webhook in this workspace.";
5643
+ case "url_refused":
5644
+ case "demo_session":
5645
+ return e.message;
5646
+ case "unknown_event":
5647
+ return `${e.message}. The exact types are in \`webhooks events\`; a family is its first word plus \`.*\`.`;
5648
+ case "unknown_subject":
5649
+ return `${e.message}. The subject keys are in \`webhooks events\`.`;
5650
+ case "plan_required": {
5651
+ const url2 = e.details?.upgradeUrl;
5652
+ return typeof url2 === "string" && url2 ? `${e.message} \u2014 upgrade the plan at ${url2}` : e.message;
5653
+ }
5654
+ case "insufficient_scope":
5655
+ case "endpoint_not_allowed":
5656
+ if (lookup === "catalog")
5657
+ return null;
5658
+ return identity.webhooksScope ? `This key cannot manage webhooks: create one with the ${identity.webhooksScope} scope on the API keys page.` : `${identity.displayName} opens webhooks to no API key: manage them signed in, in the dashboard.`;
5659
+ default:
5660
+ return null;
5661
+ }
5662
+ }
5663
+ async function explained2(identity, lookup, run2) {
5664
+ try {
5665
+ return await run2();
5666
+ } catch (e) {
5667
+ if (e instanceof PlatformApiError) {
5668
+ const line = explainWebhookRefusal(e, lookup, identity);
5669
+ if (line)
5670
+ throw new CliApiRefusal(line, e.status);
5671
+ }
5672
+ throw e;
5673
+ }
5674
+ }
5675
+ async function allWebhooks(client) {
5676
+ const first = await client.webhooks();
5677
+ return drainPages({ rows: first.webhooks, nextCursor: first.nextCursor }, async (cursor) => {
5678
+ const page = await client.webhooks({ cursor });
5679
+ return { rows: page.webhooks, nextCursor: page.nextCursor };
5680
+ });
5681
+ }
5682
+ var collect = (value, previous) => [...previous, value];
5683
+ function parseWebhookFilters(values) {
5684
+ const filters = {};
5685
+ for (const value of values) {
5686
+ const at = value.indexOf("=");
5687
+ const subject = at > 0 ? value.slice(0, at).trim() : "";
5688
+ const id2 = at > 0 ? value.slice(at + 1).trim() : "";
5689
+ if (!subject || !id2) {
5690
+ throw new CliUsageError(`--filter takes <subject>=<id> (e.g. thing=<id>), not "${value}".`);
5691
+ }
5692
+ const ids = filters[subject] ??= [];
5693
+ if (!ids.includes(id2))
5694
+ ids.push(id2);
5695
+ }
5696
+ return filters;
5697
+ }
5698
+ var DELIVERY_STATUSES = ["pending", "delivered", "failed", "held"];
5699
+ function parseLimit(value) {
5700
+ const n = Number(value);
5701
+ if (!Number.isInteger(n) || n < 1 || n > 100) {
5702
+ throw new CliUsageError(`--limit takes a whole number from 1 to 100, not "${value}".`);
5703
+ }
5704
+ return n;
5705
+ }
5706
+ function fmtWhen(iso) {
5707
+ return `${iso.slice(0, 10)} ${iso.slice(11, 16)}`;
5708
+ }
5709
+ function fmtFilters(filters) {
5710
+ const keys = Object.keys(filters);
5711
+ return keys.length === 0 ? "none" : keys.map((k) => `${k}=${(filters[k] ?? []).join("|")}`).join(" ");
5712
+ }
5713
+ function lastDelivery(w) {
5714
+ return w.lastDeliveryStatus && w.lastDeliveryAt ? `${w.lastDeliveryStatus} ${fmtWhen(w.lastDeliveryAt)}` : "-";
5715
+ }
5716
+ function endpointLines(w) {
5717
+ return `${w.url}
5718
+ id: ${w.id}
5719
+ ` + (w.description ? ` description: ${w.description}
5720
+ ` : "") + ` events: ${w.events.join(", ")}
5721
+ filters: ${fmtFilters(w.filters)}
5722
+ enabled: ${w.enabled ? "yes" : "no"}
5723
+ ` + (w.disabledAt ? ` disabled: ${w.disabledAt}${w.disabledReason ? ` (${w.disabledReason})` : ""}
5724
+ ` : "") + ` failures: ${w.consecutiveFailures} in a row
5725
+ last: ${lastDelivery(w)}
5726
+ ` + (w.previousSecretExpiresAt ? ` old secret: signs until ${w.previousSecretExpiresAt}
5727
+ ` : "") + ` created: ${w.createdAt}
5728
+ `;
5729
+ }
5730
+ function deliveryLines(d) {
5731
+ return `Delivery ${d.id}
5732
+ event: ${d.eventType} (${d.eventId})
5733
+ status: ${d.status}
5734
+ attempt: ${d.attempt}
5735
+ HTTP code: ${d.lastStatusCode ?? "-"}
5736
+ ` + (d.lastError ? ` error: ${d.lastError}
5737
+ ` : "") + (d.nextAttemptAt ? ` next try: ${d.nextAttemptAt}
5738
+ ` : "") + (d.deliveredAt ? ` delivered: ${d.deliveredAt}
5739
+ ` : "") + ` created: ${d.createdAt}
5740
+ `;
5741
+ }
5742
+ function catalogLines(catalog) {
5743
+ if (catalog.events.length === 0)
5744
+ return "No event types.\n";
5745
+ let out = table([
5746
+ ["TYPE", "SUBJECTS", "DESCRIPTION"],
5747
+ ...catalog.events.map((e) => [e.type, e.subjects.join(",") || "-", e.description])
5748
+ ]);
5749
+ if (catalog.subjects.length > 0) {
5750
+ out += "\nSubjects (what --filter <subject>=<id> matches on):\n" + table(catalog.subjects.map((s) => [` ${s.key}`, `subjects.${s.field}`, s.description]));
5751
+ }
5752
+ return out;
5753
+ }
5754
+ function registerWebhookCommands(kit, program2, io) {
5755
+ const { requireApiKey: requireApiKey2, resolveContext: resolveContext2, identity } = kit;
5756
+ const scopeLine = identity.webhooksScope ? `A key needs the ${identity.webhooksScope} scope.` : `${identity.displayName} opens webhooks to no API key.`;
5757
+ const webhooks = program2.command("webhooks").description("The workspace's webhooks (signed POSTs to your URLs when an event happens)").addHelpText("after", `
5758
+ An owner or an admin manages the webhooks; every member reads the event catalog
5759
+ (\`webhooks events\`). ${scopeLine}
5760
+ The signing secret is printed once, at \`create\` and at \`rotate-secret\`: store it then.
5761
+ `);
5762
+ webhooks.command("list").description("List the workspace's webhook endpoints (every page)").action(async (_opts, cmd) => {
5763
+ const ctx = resolveContext2(cmd, io);
5764
+ await requireApiKey2(ctx);
5765
+ const rows = await explained2(identity, "webhook", () => allWebhooks(ctx.client));
5766
+ if (ctx.json)
5767
+ return printJson2(io, { webhooks: rows, nextCursor: null });
5768
+ if (rows.length === 0) {
5769
+ io.out.write("No webhooks.\n");
5770
+ return;
5771
+ }
5772
+ io.out.write(table([
5773
+ ["ID", "URL", "EVENTS", "ENABLED", "LAST DELIVERY", "FAILURES"],
5774
+ ...rows.map((w) => [
5775
+ w.id,
5776
+ w.url,
5777
+ w.events.join(","),
5778
+ w.enabled ? "yes" : "no",
5779
+ lastDelivery(w),
5780
+ String(w.consecutiveFailures)
5781
+ ])
5782
+ ]));
5783
+ });
5784
+ webhooks.command("events").description("The event catalog: every event type, the subjects it carries, what it means").action(async (_opts, cmd) => {
5785
+ const ctx = resolveContext2(cmd, io);
5786
+ await requireApiKey2(ctx);
5787
+ const catalog = await explained2(identity, "catalog", () => ctx.client.webhookEvents());
5788
+ if (ctx.json)
5789
+ return printJson2(io, catalog);
5790
+ io.out.write(catalogLines(catalog));
5791
+ });
5792
+ webhooks.command("create <url>").description("Register an endpoint (owner or admin); its signing secret is printed once").option("--event <type>", "an event type (thing.created), a family (thing.*) or everything (*); repeatable, at least one", collect, []).option("--description <text>", "what the endpoint is for").option("--filter <subject>=<id>", "only events about this subject id; repeatable (same subject: OR, different subjects: AND)", collect, []).option("--disabled", "register it switched off", false).action(async (url2, opts, cmd) => {
5793
+ if (opts.event.length === 0) {
5794
+ throw new CliUsageError("Name at least one event: --event <type> (e.g. --event thing.created), repeatable.");
5795
+ }
5796
+ const filters = parseWebhookFilters(opts.filter);
5797
+ const req = {
5798
+ url: url2,
5799
+ events: opts.event,
5800
+ ...opts.description !== void 0 ? { description: opts.description } : {},
5801
+ ...Object.keys(filters).length > 0 ? { filters } : {},
5802
+ ...opts.disabled ? { enabled: false } : {}
5803
+ };
5804
+ const ctx = resolveContext2(cmd, io);
5805
+ await requireApiKey2(ctx);
5806
+ const created = await explained2(identity, "webhook", () => ctx.client.createWebhook(req));
5807
+ if (ctx.json)
5808
+ return printJson2(io, created);
5809
+ io.out.write(`Created webhook ${created.id}.
5810
+ Its signing secret is shown this once, never again: store it now.
5811
+ ${created.secret}
5812
+ `);
5813
+ });
5814
+ webhooks.command("get <id>").description("Show one endpoint").action(async (id2, _opts, cmd) => {
5815
+ const ctx = resolveContext2(cmd, io);
5816
+ await requireApiKey2(ctx);
5817
+ const endpoint = await explained2(identity, "webhook", () => ctx.client.webhook(id2));
5818
+ if (ctx.json)
5819
+ return printJson2(io, endpoint);
5820
+ io.out.write(endpointLines(endpoint));
5821
+ });
5822
+ webhooks.command("update <id>").description("Change an endpoint (owner or admin); only what is passed changes").option("--endpoint-url <url>", "the new address the deliveries go to").option("--description <text>", "the new description").option("--event <type>", "replace the events with these; repeatable", collect, []).option("--filter <subject>=<id>", "replace the filters with these; repeatable", collect, []).option("--clear-filters", "remove every filter", false).option("--enable", "switch the endpoint on", false).option("--disable", "switch the endpoint off", false).action(async (id2, opts, cmd) => {
5823
+ if (opts.enable && opts.disable) {
5824
+ throw new CliUsageError("Pass --enable or --disable, not both.");
5825
+ }
5826
+ if (opts.clearFilters && opts.filter.length > 0) {
5827
+ throw new CliUsageError("Pass --filter or --clear-filters, not both.");
5828
+ }
5829
+ const req = {
5830
+ ...opts.endpointUrl !== void 0 ? { url: opts.endpointUrl } : {},
5831
+ ...opts.description !== void 0 ? { description: opts.description } : {},
5832
+ ...opts.event.length > 0 ? { events: opts.event } : {},
5833
+ ...opts.filter.length > 0 ? { filters: parseWebhookFilters(opts.filter) } : {},
5834
+ ...opts.clearFilters ? { filters: {} } : {},
5835
+ ...opts.enable ? { enabled: true } : {},
5836
+ ...opts.disable ? { enabled: false } : {}
5837
+ };
5838
+ if (Object.keys(req).length === 0) {
5839
+ throw new CliUsageError("Nothing to change \u2014 pass --endpoint-url, --description, --event, --filter, --clear-filters, --enable or --disable.");
5840
+ }
5841
+ const ctx = resolveContext2(cmd, io);
5842
+ await requireApiKey2(ctx);
5843
+ const updated = await explained2(identity, "webhook", () => ctx.client.updateWebhook(id2, req));
5844
+ if (ctx.json)
5845
+ return printJson2(io, updated);
5846
+ io.out.write(`Updated webhook ${updated.id}.
5847
+ ${endpointLines(updated)}`);
5848
+ });
5849
+ webhooks.command("delete <id>").description("Delete an endpoint and its delivery history (owner or admin)").action(async (id2, _opts, cmd) => {
5850
+ const ctx = resolveContext2(cmd, io);
5851
+ await requireApiKey2(ctx);
5852
+ const deleted = await explained2(identity, "webhook", () => ctx.client.deleteWebhook(id2));
5853
+ if (ctx.json)
5854
+ return printJson2(io, deleted);
5855
+ io.out.write(`Deleted webhook ${deleted.id} (${deleted.url}) and its delivery history.
5856
+ `);
5857
+ });
5858
+ webhooks.command("rotate-secret <id>").description("Replace an endpoint's signing secret (owner or admin); the new one is printed once").action(async (id2, _opts, cmd) => {
5859
+ const ctx = resolveContext2(cmd, io);
5860
+ await requireApiKey2(ctx);
5861
+ const rotated = await explained2(identity, "webhook", () => ctx.client.rotateWebhookSecret(id2));
5862
+ if (ctx.json)
5863
+ return printJson2(io, rotated);
5864
+ io.out.write(`New signing secret for webhook ${rotated.id}, shown this once, never again: store it now.
5865
+ ${rotated.secret}
5866
+ The previous secret keeps signing until ${rotated.previousSecretExpiresAt}.
5867
+ `);
5868
+ });
5869
+ webhooks.command("test <id>").description("Send a signed webhook.ping now and print its outcome (exit 1 when not delivered)").action(async (id2, _opts, cmd) => {
5870
+ const ctx = resolveContext2(cmd, io);
5871
+ await requireApiKey2(ctx);
5872
+ const { delivery } = await explained2(identity, "webhook", () => ctx.client.testWebhook(id2));
5873
+ if (ctx.json)
5874
+ printJson2(io, { delivery });
5875
+ else
5876
+ io.out.write(`Ping ${delivery.status}` + (delivery.lastStatusCode !== null ? `, HTTP ${delivery.lastStatusCode}` : "") + (delivery.lastError ? `: ${delivery.lastError}` : "") + ` (delivery ${delivery.id}).
5877
+ `);
5878
+ if (delivery.status !== "delivered") {
5879
+ throw new CliUsageError(`The ping was not delivered (${delivery.status}).`);
5880
+ }
5881
+ });
5882
+ webhooks.command("deliveries <id>").description("List one page of an endpoint's deliveries, newest first").option("--status <status>", `only these: ${DELIVERY_STATUSES.join(", ")}`).option("--limit <n>", "page size, 1 to 100 (server default 50)").option("--cursor <cursor>", "the next page, as the previous one printed it").action(async (id2, opts, cmd) => {
5883
+ if (opts.status !== void 0 && !DELIVERY_STATUSES.includes(opts.status)) {
5884
+ throw new CliUsageError(`--status takes one of ${DELIVERY_STATUSES.join(", ")}, not "${opts.status}".`);
5885
+ }
5886
+ const params = {
5887
+ ...opts.status !== void 0 ? { status: opts.status } : {},
5888
+ ...opts.limit !== void 0 ? { limit: parseLimit(opts.limit) } : {},
5889
+ ...opts.cursor !== void 0 ? { cursor: opts.cursor } : {}
5890
+ };
5891
+ const ctx = resolveContext2(cmd, io);
5892
+ await requireApiKey2(ctx);
5893
+ const page = await explained2(identity, "webhook", () => ctx.client.webhookDeliveries(id2, params));
5894
+ if (ctx.json)
5895
+ return printJson2(io, page);
5896
+ if (page.deliveries.length === 0) {
5897
+ io.out.write("No deliveries.\n");
5898
+ return;
5899
+ }
5900
+ io.out.write(table([
5901
+ ["ID", "EVENT", "STATUS", "ATTEMPT", "CODE", "CREATED"],
5902
+ ...page.deliveries.map((d) => [
5903
+ d.id,
5904
+ d.eventType,
5905
+ d.status,
5906
+ String(d.attempt),
5907
+ d.lastStatusCode !== null ? String(d.lastStatusCode) : "-",
5908
+ fmtWhen(d.createdAt)
5909
+ ])
5910
+ ]));
5911
+ if (page.nextCursor)
5912
+ io.out.write(`More: --cursor ${page.nextCursor}
5913
+ `);
5914
+ });
5915
+ webhooks.command("delivery <id> <deliveryId>").description("Show one delivery: its status, its latest attempt (--json: the payload as sent)").action(async (id2, deliveryId, _opts, cmd) => {
5916
+ const ctx = resolveContext2(cmd, io);
5917
+ await requireApiKey2(ctx);
5918
+ const delivery = await explained2(identity, "delivery", () => ctx.client.webhookDelivery(id2, deliveryId));
5919
+ if (ctx.json)
5920
+ return printJson2(io, delivery);
5921
+ io.out.write(deliveryLines(delivery));
5922
+ });
5923
+ webhooks.command("redeliver <id> <deliveryId>").description("Queue the same event again as a new delivery (same event id, same payload)").action(async (id2, deliveryId, _opts, cmd) => {
5924
+ const ctx = resolveContext2(cmd, io);
5925
+ await requireApiKey2(ctx);
5926
+ const delivery = await explained2(identity, "delivery", () => ctx.client.redeliverWebhook(id2, deliveryId));
5927
+ if (ctx.json)
5928
+ return printJson2(io, delivery);
5929
+ io.out.write(`Queued delivery ${delivery.id} of ${delivery.eventType} (event ${delivery.eventId}).
5930
+ `);
5931
+ });
5932
+ }
5933
+
5505
5934
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
5506
5935
  var external_exports = {};
5507
5936
  __export(external_exports, {
@@ -8594,42 +9023,42 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
8594
9023
  }
8595
9024
  doc.write(`const newResult = {};`);
8596
9025
  for (const key of normalized.keys) {
8597
- const id = ids[key];
9026
+ const id2 = ids[key];
8598
9027
  const k = esc(key);
8599
9028
  const schema = shape[key];
8600
9029
  const isOptionalIn = schema?._zod?.optin === "optional";
8601
9030
  const isOptionalOut = schema?._zod?.optout === "optional";
8602
- doc.write(`const ${id} = ${parseStr(key)};`);
9031
+ doc.write(`const ${id2} = ${parseStr(key)};`);
8603
9032
  if (isOptionalIn && isOptionalOut) {
8604
9033
  doc.write(`
8605
- if (${id}.issues.length) {
9034
+ if (${id2}.issues.length) {
8606
9035
  if (${k} in input) {
8607
- payload.issues = payload.issues.concat(${id}.issues.map(iss => ({
9036
+ payload.issues = payload.issues.concat(${id2}.issues.map(iss => ({
8608
9037
  ...iss,
8609
9038
  path: iss.path ? [${k}, ...iss.path] : [${k}]
8610
9039
  })));
8611
9040
  }
8612
9041
  }
8613
9042
 
8614
- if (${id}.value === undefined) {
9043
+ if (${id2}.value === undefined) {
8615
9044
  if (${k} in input) {
8616
9045
  newResult[${k}] = undefined;
8617
9046
  }
8618
9047
  } else {
8619
- newResult[${k}] = ${id}.value;
9048
+ newResult[${k}] = ${id2}.value;
8620
9049
  }
8621
9050
 
8622
9051
  `);
8623
9052
  } else if (!isOptionalIn) {
8624
9053
  doc.write(`
8625
- const ${id}_present = ${k} in input;
8626
- if (${id}.issues.length) {
8627
- payload.issues = payload.issues.concat(${id}.issues.map(iss => ({
9054
+ const ${id2}_present = ${k} in input;
9055
+ if (${id2}.issues.length) {
9056
+ payload.issues = payload.issues.concat(${id2}.issues.map(iss => ({
8628
9057
  ...iss,
8629
9058
  path: iss.path ? [${k}, ...iss.path] : [${k}]
8630
9059
  })));
8631
9060
  }
8632
- if (!${id}_present && !${id}.issues.length) {
9061
+ if (!${id2}_present && !${id2}.issues.length) {
8633
9062
  payload.issues.push({
8634
9063
  code: "invalid_type",
8635
9064
  expected: "nonoptional",
@@ -8638,30 +9067,30 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
8638
9067
  });
8639
9068
  }
8640
9069
 
8641
- if (${id}_present) {
8642
- if (${id}.value === undefined) {
9070
+ if (${id2}_present) {
9071
+ if (${id2}.value === undefined) {
8643
9072
  newResult[${k}] = undefined;
8644
9073
  } else {
8645
- newResult[${k}] = ${id}.value;
9074
+ newResult[${k}] = ${id2}.value;
8646
9075
  }
8647
9076
  }
8648
9077
 
8649
9078
  `);
8650
9079
  } else {
8651
9080
  doc.write(`
8652
- if (${id}.issues.length) {
8653
- payload.issues = payload.issues.concat(${id}.issues.map(iss => ({
9081
+ if (${id2}.issues.length) {
9082
+ payload.issues = payload.issues.concat(${id2}.issues.map(iss => ({
8654
9083
  ...iss,
8655
9084
  path: iss.path ? [${k}, ...iss.path] : [${k}]
8656
9085
  })));
8657
9086
  }
8658
9087
 
8659
- if (${id}.value === undefined) {
9088
+ if (${id2}.value === undefined) {
8660
9089
  if (${k} in input) {
8661
9090
  newResult[${k}] = undefined;
8662
9091
  }
8663
9092
  } else {
8664
- newResult[${k}] = ${id}.value;
9093
+ newResult[${k}] = ${id2}.value;
8665
9094
  }
8666
9095
 
8667
9096
  `);
@@ -16993,26 +17422,26 @@ function extractDefs(ctx, schema) {
16993
17422
  throw new Error("Unprocessed schema. This is a bug in Zod.");
16994
17423
  const idToSchema = /* @__PURE__ */ new Map();
16995
17424
  for (const entry of ctx.seen.entries()) {
16996
- const id = ctx.metadataRegistry.get(entry[0])?.id;
16997
- if (id) {
16998
- const existing = idToSchema.get(id);
17425
+ const id2 = ctx.metadataRegistry.get(entry[0])?.id;
17426
+ if (id2) {
17427
+ const existing = idToSchema.get(id2);
16999
17428
  if (existing && existing !== entry[0]) {
17000
- throw new Error(`Duplicate schema id "${id}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);
17429
+ throw new Error(`Duplicate schema id "${id2}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);
17001
17430
  }
17002
- idToSchema.set(id, entry[0]);
17431
+ idToSchema.set(id2, entry[0]);
17003
17432
  }
17004
17433
  }
17005
17434
  const makeURI = (entry) => {
17006
17435
  const defsSegment = ctx.target === "draft-2020-12" ? "$defs" : "definitions";
17007
17436
  if (ctx.external) {
17008
17437
  const externalId = ctx.external.registry.get(entry[0])?.id;
17009
- const uriGenerator = ctx.external.uri ?? ((id2) => id2);
17438
+ const uriGenerator = ctx.external.uri ?? ((id3) => id3);
17010
17439
  if (externalId) {
17011
17440
  return { ref: uriGenerator(externalId) };
17012
17441
  }
17013
- const id = entry[1].defId ?? entry[1].schema.id ?? `schema${ctx.counter++}`;
17014
- entry[1].defId = id;
17015
- return { defId: id, ref: `${uriGenerator("__shared")}#/${defsSegment}/${id}` };
17442
+ const id2 = entry[1].defId ?? entry[1].schema.id ?? `schema${ctx.counter++}`;
17443
+ entry[1].defId = id2;
17444
+ return { defId: id2, ref: `${uriGenerator("__shared")}#/${defsSegment}/${id2}` };
17016
17445
  }
17017
17446
  if (entry[1] === root) {
17018
17447
  return { ref: "#" };
@@ -17060,8 +17489,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17060
17489
  continue;
17061
17490
  }
17062
17491
  }
17063
- const id = ctx.metadataRegistry.get(entry[0])?.id;
17064
- if (id) {
17492
+ const id2 = ctx.metadataRegistry.get(entry[0])?.id;
17493
+ if (id2) {
17065
17494
  extractToDef(entry);
17066
17495
  continue;
17067
17496
  }
@@ -17157,10 +17586,10 @@ function finalize(ctx, schema) {
17157
17586
  } else {
17158
17587
  }
17159
17588
  if (ctx.external?.uri) {
17160
- const id = ctx.external.registry.get(schema)?.id;
17161
- if (!id)
17589
+ const id2 = ctx.external.registry.get(schema)?.id;
17590
+ if (!id2)
17162
17591
  throw new Error("Schema is missing an `id` property");
17163
- result.$id = ctx.external.uri(id);
17592
+ result.$id = ctx.external.uri(id2);
17164
17593
  }
17165
17594
  Object.assign(result, root.def ?? root.schema);
17166
17595
  const rootMetaId = ctx.metadataRegistry.get(schema)?.id;
@@ -20016,7 +20445,7 @@ function date4(params) {
20016
20445
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
20017
20446
  config(en_default());
20018
20447
 
20019
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/common.js
20448
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/common.js
20020
20449
  var apiErrorSchema = external_exports.object({
20021
20450
  error: external_exports.object({
20022
20451
  code: external_exports.string(),
@@ -20121,12 +20550,12 @@ function isValidMediaType(value) {
20121
20550
  return value.length >= 1 && value.length <= 255 && isLatin1(value) && MEDIA_TYPE_RE.test(value);
20122
20551
  }
20123
20552
 
20124
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/scope.js
20553
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/scope.js
20125
20554
  function defineScopeSchema(scopes) {
20126
20555
  return external_exports.enum(scopes);
20127
20556
  }
20128
20557
 
20129
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/seams.js
20558
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/seams.js
20130
20559
  var KNOWN_AUTH_METHODS = [
20131
20560
  "password",
20132
20561
  "email-otp",
@@ -21710,7 +22139,7 @@ var HUB_TOOL_WIRE_INPUTS = {
21710
22139
  }
21711
22140
  };
21712
22141
 
21713
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/entitlements.js
22142
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/entitlements.js
21714
22143
  var entitlementTierSchema = billingPlanSchema;
21715
22144
  var entitlementActionSchema = external_exports.object({
21716
22145
  key: external_exports.string().min(1),
@@ -21744,7 +22173,7 @@ var entitlementProfileSchema = external_exports.object({
21744
22173
  upgradeUrl: external_exports.string()
21745
22174
  });
21746
22175
 
21747
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/instance.js
22176
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/instance.js
21748
22177
  var instanceInfoSchema2 = external_exports.object({
21749
22178
  name: external_exports.string(),
21750
22179
  instanceId: external_exports.string().nullable(),
@@ -21794,6 +22223,14 @@ var instanceInfoSchema2 = external_exports.object({
21794
22223
  * false, so the self-hosted discovery bytes are unchanged.
21795
22224
  */
21796
22225
  restricted: external_exports.boolean().optional(),
22226
+ /**
22227
+ * The tool's own CLI package (cloud edition, PRDCT-3312): present only when
22228
+ * the instance was released with it (`CLI_PACKAGE_DIR`), naming the npm
22229
+ * package `POST /cli/package` serves and its version. The `team` command
22230
+ * reads it to know what it installs and whether to update. ABSENT
22231
+ * otherwise, so older discovery bytes are unchanged.
22232
+ */
22233
+ cli: external_exports.object({ name: external_exports.string(), version: external_exports.string() }).optional(),
21797
22234
  /**
21798
22235
  * What this version of the tool declares for the billing rail (its priced
21799
22236
  * actions with their default credits, its limits and features per tier):
@@ -21805,7 +22242,7 @@ var instanceInfoSchema2 = external_exports.object({
21805
22242
  entitlements: toolEntitlementsSchema.optional()
21806
22243
  });
21807
22244
 
21808
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/setup.js
22245
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/setup.js
21809
22246
  var setupRequestSchema2 = external_exports.object({
21810
22247
  instanceName: plainText(1, 120),
21811
22248
  owner: external_exports.object({
@@ -21822,7 +22259,7 @@ var setupResponseSchema2 = external_exports.object({
21822
22259
  ownerUserId: external_exports.string()
21823
22260
  });
21824
22261
 
21825
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/workspaces.js
22262
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/workspaces.js
21826
22263
  var lookKey2 = external_exports.string().regex(/^[a-z][a-z0-9-]{0,31}$/, "a short lowercase key").nullable();
21827
22264
  var lookLevel2 = external_exports.number().min(0).max(1).nullable();
21828
22265
  var workspaceLookSchema2 = external_exports.object({
@@ -21862,7 +22299,7 @@ var workspaceUpdatedSchema2 = external_exports.object({
21862
22299
  })
21863
22300
  });
21864
22301
 
21865
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/me.js
22302
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/me.js
21866
22303
  var onboardingDismissedSchema = external_exports.object({
21867
22304
  dismissed: external_exports.literal(true)
21868
22305
  });
@@ -22014,7 +22451,7 @@ function defineMeSchemas(scopeSchema3) {
22014
22451
  return { meResponseSchema: meResponseSchema3 };
22015
22452
  }
22016
22453
 
22017
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/members.js
22454
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/members.js
22018
22455
  var memberSchema2 = external_exports.object({
22019
22456
  id: external_exports.string(),
22020
22457
  userId: external_exports.string(),
@@ -22048,7 +22485,7 @@ var memberChangeEmailLinkSchema2 = external_exports.object({
22048
22485
  expiresAt: external_exports.string()
22049
22486
  });
22050
22487
 
22051
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/cli-auth.js
22488
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/cli-auth.js
22052
22489
  var cliAuthRequestSchema2 = external_exports.object({
22053
22490
  email: external_exports.email()
22054
22491
  });
@@ -22090,7 +22527,7 @@ function defineCliAuthSchemas(apiKeySchema3) {
22090
22527
  return { cliAuthCompletedSchema: cliAuthCompletedSchema3 };
22091
22528
  }
22092
22529
 
22093
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/sso-connect.js
22530
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/sso-connect.js
22094
22531
  var ssoCliConnectSchema = external_exports.object({
22095
22532
  /** The hub-minted exchange JWT (compact JWS — three base64url segments). */
22096
22533
  token: external_exports.string().min(20).max(4096),
@@ -22105,12 +22542,18 @@ var ssoCliConnectSchema = external_exports.object({
22105
22542
  hubRefreshToken: external_exports.string().min(20).max(512).optional()
22106
22543
  });
22107
22544
 
22108
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/sso-logout.js
22545
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/cli-package.js
22546
+ var cliPackageRequestSchema = external_exports.object({
22547
+ /** The hub-minted exchange JWT (compact JWS — three base64url segments). */
22548
+ token: external_exports.string().min(1)
22549
+ });
22550
+
22551
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/sso-logout.js
22109
22552
  var ssoLogoutResponseSchema = external_exports.object({
22110
22553
  url: external_exports.string().nullable()
22111
22554
  });
22112
22555
 
22113
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/invitations.js
22556
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/invitations.js
22114
22557
  var invitationSchema2 = external_exports.object({
22115
22558
  id: external_exports.string(),
22116
22559
  email: external_exports.string(),
@@ -22152,7 +22595,7 @@ var invitationAcceptedSchema2 = external_exports.object({
22152
22595
  role: workspaceRoleSchema
22153
22596
  });
22154
22597
 
22155
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/audit.js
22598
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/audit.js
22156
22599
  var auditEntrySchema2 = external_exports.object({
22157
22600
  id: external_exports.number(),
22158
22601
  actorUserId: external_exports.string().nullable(),
@@ -22197,7 +22640,7 @@ var auditListSchema2 = external_exports.object({
22197
22640
  total: external_exports.number().int().nullable()
22198
22641
  });
22199
22642
 
22200
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/break-glass.js
22643
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/break-glass.js
22201
22644
  var breakGlassClaimOwnershipRequestSchema2 = external_exports.object({
22202
22645
  userId: external_exports.string().min(1).optional(),
22203
22646
  workspaceId: external_exports.uuid().optional()
@@ -22222,7 +22665,7 @@ var breakGlassResetTwoFactorSchema2 = external_exports.object({
22222
22665
  hadTwoFactor: external_exports.boolean()
22223
22666
  });
22224
22667
 
22225
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/files.js
22668
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/files.js
22226
22669
  var fileSchema2 = external_exports.object({
22227
22670
  id: external_exports.string(),
22228
22671
  sha256: external_exports.string(),
@@ -22247,7 +22690,7 @@ var fileUploadQuerySchema2 = external_exports.object({
22247
22690
  name: plainText(1, 255)
22248
22691
  });
22249
22692
 
22250
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/projects.js
22693
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/projects.js
22251
22694
  var projectRoleSchema = external_exports.enum(["manager", "editor", "viewer"]);
22252
22695
  var PROJECT_METADATA_MAX_LENGTH = 16 * 1024;
22253
22696
  var projectMetadataSchema = opaqueJsonChecks(external_exports.record(external_exports.string(), external_exports.unknown())).refine((v) => JSON.stringify(v).length <= PROJECT_METADATA_MAX_LENGTH, `metadata must serialize to at most ${PROJECT_METADATA_MAX_LENGTH} characters`);
@@ -22335,7 +22778,7 @@ var projectMemberParamsSchema = external_exports.object({
22335
22778
  });
22336
22779
  var projectTeamParamsSchema = external_exports.object({ id: external_exports.uuid(), teamId: external_exports.uuid() });
22337
22780
 
22338
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/teams.js
22781
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/teams.js
22339
22782
  var teamSlugSchema2 = external_exports.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "lowercase letters and digits, joined by single dashes").min(1).max(60);
22340
22783
  var teamSchema2 = external_exports.object({
22341
22784
  id: external_exports.string(),
@@ -22389,7 +22832,119 @@ var teamMemberParamsSchema = external_exports.object({
22389
22832
  userId: noControlChars(external_exports.string().min(1).max(200))
22390
22833
  });
22391
22834
 
22392
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/demo-passes.js
22835
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/webhooks.js
22836
+ var webhookEventPatternSchema = external_exports.string().max(80).regex(/^(\*|[a-z][a-z0-9_]*\.(\*|[a-z][a-z0-9_]*))$/, "an event type (thing.created), a family (thing.*) or everything (*)");
22837
+ var webhookSubjectKeySchema = external_exports.string().max(40).regex(/^[a-z][a-z0-9_]*$/, "lowercase letters, digits and underscores, starting with a letter");
22838
+ var webhookFiltersSchema = external_exports.record(webhookSubjectKeySchema, external_exports.array(plainText(1, 200)).min(1).max(100)).refine((v) => Object.keys(v).length <= 10, { error: "at most 10 subject keys" }).describe("Subject key \u2192 ids; AND across keys, OR within a key; an event that does not carry a filtered subject does not match");
22839
+ var UrlParser = globalThis.URL;
22840
+ function isHttpUrlWithoutCredentials(value) {
22841
+ let parsed;
22842
+ try {
22843
+ parsed = new UrlParser(value);
22844
+ } catch {
22845
+ return false;
22846
+ }
22847
+ return (parsed.protocol === "http:" || parsed.protocol === "https:") && parsed.username === "" && parsed.password === "";
22848
+ }
22849
+ var webhookUrlSchema = external_exports.string().max(2048).refine((v) => !/\s/.test(v) && !hasControlChars(v), {
22850
+ error: "must not contain whitespace or control characters",
22851
+ abort: true
22852
+ }).refine(isHttpUrlWithoutCredentials, { error: "an http or https URL without credentials" });
22853
+ var webhookDeliveryStatusSchema = external_exports.enum(["pending", "delivered", "failed", "held"]);
22854
+ var webhookEndpointSchema = external_exports.object({
22855
+ id: external_exports.string(),
22856
+ url: external_exports.string(),
22857
+ description: external_exports.string(),
22858
+ events: external_exports.array(external_exports.string()),
22859
+ filters: external_exports.record(external_exports.string(), external_exports.array(external_exports.string())),
22860
+ enabled: external_exports.boolean(),
22861
+ createdBy: external_exports.string().nullable(),
22862
+ createdAt: external_exports.string(),
22863
+ updatedAt: external_exports.string(),
22864
+ /** Set with `disabledReason` when the endpoint was switched off after failing too long. */
22865
+ disabledAt: external_exports.string().nullable(),
22866
+ disabledReason: external_exports.string().nullable(),
22867
+ consecutiveFailures: external_exports.number().int(),
22868
+ lastDeliveryAt: external_exports.string().nullable(),
22869
+ lastDeliveryStatus: external_exports.enum(["delivered", "failed"]).nullable(),
22870
+ /** During a rotation, the previous secret keeps signing until this date. */
22871
+ previousSecretExpiresAt: external_exports.string().nullable()
22872
+ });
22873
+ var webhookEndpointCreatedSchema = webhookEndpointSchema.extend({
22874
+ secret: external_exports.string()
22875
+ });
22876
+ var webhookSecretRotatedSchema = webhookEndpointSchema.extend({
22877
+ secret: external_exports.string(),
22878
+ previousSecretExpiresAt: external_exports.string()
22879
+ });
22880
+ var webhookDescriptionSchema = plainText(0, 200);
22881
+ var webhookEventsSchema = external_exports.array(webhookEventPatternSchema).min(1).max(50);
22882
+ var webhookEndpointCreateSchema = external_exports.object({
22883
+ url: webhookUrlSchema,
22884
+ description: webhookDescriptionSchema.default(""),
22885
+ events: webhookEventsSchema,
22886
+ filters: webhookFiltersSchema.default({}),
22887
+ enabled: external_exports.boolean().default(true)
22888
+ });
22889
+ var webhookEndpointUpdateSchema = external_exports.object({
22890
+ url: webhookUrlSchema.optional(),
22891
+ description: webhookDescriptionSchema.optional(),
22892
+ events: webhookEventsSchema.optional(),
22893
+ filters: webhookFiltersSchema.optional(),
22894
+ enabled: external_exports.boolean().optional()
22895
+ }).refine((b) => Object.values(b).some((v) => v !== void 0), { error: "nothing to change" });
22896
+ var webhooksListSchema = external_exports.object({
22897
+ webhooks: external_exports.array(webhookEndpointSchema),
22898
+ nextCursor: external_exports.string().nullable()
22899
+ });
22900
+ var webhookDeliverySchema = external_exports.object({
22901
+ id: external_exports.string(),
22902
+ endpointId: external_exports.string(),
22903
+ eventId: external_exports.string(),
22904
+ eventType: external_exports.string(),
22905
+ status: webhookDeliveryStatusSchema,
22906
+ attempt: external_exports.number().int(),
22907
+ lastStatusCode: external_exports.number().int().nullable(),
22908
+ lastError: external_exports.string().nullable(),
22909
+ nextAttemptAt: external_exports.string().nullable(),
22910
+ deliveredAt: external_exports.string().nullable(),
22911
+ createdAt: external_exports.string(),
22912
+ updatedAt: external_exports.string(),
22913
+ payload: external_exports.record(external_exports.string(), external_exports.unknown())
22914
+ });
22915
+ var webhookDeliveriesListSchema = external_exports.object({
22916
+ deliveries: external_exports.array(webhookDeliverySchema),
22917
+ nextCursor: external_exports.string().nullable()
22918
+ });
22919
+ var webhookDeliveriesListQuerySchema = cursorPageQuerySchema.extend({
22920
+ status: webhookDeliveryStatusSchema.optional()
22921
+ });
22922
+ var webhookTestResultSchema = external_exports.object({
22923
+ delivery: webhookDeliverySchema
22924
+ });
22925
+ var webhookCatalogSubjectSchema = external_exports.object({
22926
+ key: external_exports.string(),
22927
+ field: external_exports.string(),
22928
+ description: external_exports.string(),
22929
+ /** The value under `field` is always a list of ids (`projectIds`); else always one id. */
22930
+ list: external_exports.boolean()
22931
+ });
22932
+ var webhookCatalogEventSchema = external_exports.object({
22933
+ type: external_exports.string(),
22934
+ description: external_exports.string(),
22935
+ /** The subject keys this event carries (what a filter can match it on). */
22936
+ subjects: external_exports.array(external_exports.string()),
22937
+ /** The JSON Schema of the event's `data`. */
22938
+ schema: external_exports.record(external_exports.string(), external_exports.unknown())
22939
+ });
22940
+ var webhookCatalogSchema = external_exports.object({
22941
+ subjects: external_exports.array(webhookCatalogSubjectSchema),
22942
+ events: external_exports.array(webhookCatalogEventSchema)
22943
+ });
22944
+ var webhookParamsSchema = external_exports.object({ id: external_exports.uuid() });
22945
+ var webhookDeliveryParamsSchema = webhookParamsSchema.extend({ deliveryId: external_exports.uuid() });
22946
+
22947
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/demo-passes.js
22393
22948
  var DEMO_PASS_MAX_MINUTES2 = 10080;
22394
22949
  var demoPassSchema2 = external_exports.object({
22395
22950
  id: external_exports.string(),
@@ -22430,7 +22985,7 @@ var demoPassRedeemedSchema2 = external_exports.object({
22430
22985
  expiresAt: external_exports.string()
22431
22986
  });
22432
22987
 
22433
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/api-keys.js
22988
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/schemas/api-keys.js
22434
22989
  function defineApiKeySchemas(scopeSchema3) {
22435
22990
  const apiKeySchema3 = external_exports.object({
22436
22991
  id: external_exports.string(),
@@ -22475,7 +23030,7 @@ function defineApiKeySchemas(scopeSchema3) {
22475
23030
  return { apiKeySchema: apiKeySchema3, apiKeysListSchema: apiKeysListSchema3, apiKeyCreateSchema: apiKeyCreateSchema3, apiKeyCreatedSchema: apiKeyCreatedSchema3 };
22476
23031
  }
22477
23032
 
22478
- // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/define.js
23033
+ // ../../node_modules/.pnpm/@antasphere+chassis-contract@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-contract/dist/define.js
22479
23034
  function defineChassisContract(tool) {
22480
23035
  return buildChassisContract(defineScopeSchema(tool.scopes));
22481
23036
  }
@@ -22489,7 +23044,7 @@ function buildChassisContract(scopeSchema3) {
22489
23044
  };
22490
23045
  }
22491
23046
 
22492
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/owner-session.js
23047
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/owner-session.js
22493
23048
  var SIGN_IN_WAITS_MS = [4e3, 8e3, 12e3];
22494
23049
  var SESSION_COOKIE = /session_token$/;
22495
23050
  function sessionCookie(res) {
@@ -22570,7 +23125,7 @@ async function withOwnerSession(ctx, options, run2) {
22570
23125
  }
22571
23126
  }
22572
23127
 
22573
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/demo.js
23128
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/demo.js
22574
23129
  var SWITCH_OFF = "Demo sign-in is off on this instance (DEMO_SIGN_IN), or this is the cloud edition, where demo links are minted at the Antasphere hub.";
22575
23130
  var NOT_AN_OWNER = "Only an owner of this workspace manages demo links: the account that signed in is not one.";
22576
23131
  var REFUSALS = /* @__PURE__ */ new Set([
@@ -22592,7 +23147,7 @@ var MemberRefusal = class extends CliApiRefusal {
22592
23147
  this.code = code;
22593
23148
  }
22594
23149
  };
22595
- async function explained2(run2) {
23150
+ async function explained3(run2) {
22596
23151
  try {
22597
23152
  return await run2();
22598
23153
  } catch (e) {
@@ -22637,7 +23192,7 @@ function lifetimeMinutes(opts) {
22637
23192
  function demoLink(baseUrl, secret, path) {
22638
23193
  return `${baseUrl.replace(/\/+$/, "")}/demo#pass=${secret}&to=${encodeURIComponent(path)}`;
22639
23194
  }
22640
- var collect = (value, previous) => [...previous, value];
23195
+ var collect2 = (value, previous) => [...previous, value];
22641
23196
  function registerDemoCommands(kit, program2, io) {
22642
23197
  const { identity, resolveContext: resolveContext2 } = kit;
22643
23198
  const prefix = identity.envPrefix;
@@ -22648,7 +23203,7 @@ function registerDemoCommands(kit, program2, io) {
22648
23203
  ...opts.ownerEmail !== void 0 ? { ownerEmail: opts.ownerEmail } : {},
22649
23204
  ownerPasswordStdin: opts.ownerPasswordStdin
22650
23205
  });
22651
- ownerFlags(demo.command("link").description("Mint one demo pass per member and print one link per page").requiredOption("--email <address>", "a member the links sign in (repeatable: one sign-in, one pass per member)", collect, []).option("--path <p>", "a page the link lands on (repeatable; the first is the default, /)", collect, []).option("--hours <n>", "how long the link lives, in hours (default: a day; at most a week)").option("--minutes <n>", "how long the link lives, in minutes (instead of --hours)")).action(async (opts, cmd) => {
23206
+ ownerFlags(demo.command("link").description("Mint one demo pass per member and print one link per page").requiredOption("--email <address>", "a member the links sign in (repeatable: one sign-in, one pass per member)", collect2, []).option("--path <p>", "a page the link lands on (repeatable; the first is the default, /)", collect2, []).option("--hours <n>", "how long the link lives, in hours (default: a day; at most a week)").option("--minutes <n>", "how long the link lives, in minutes (instead of --hours)")).action(async (opts, cmd) => {
22652
23207
  const paths = opts.path.length > 0 ? opts.path : ["/"];
22653
23208
  for (const path of paths) {
22654
23209
  if (!isSafeDemoPath(path)) {
@@ -22662,7 +23217,7 @@ function registerDemoCommands(kit, program2, io) {
22662
23217
  const refused2 = [];
22663
23218
  for (const email3 of opts.email) {
22664
23219
  try {
22665
- const minted = await explained2(() => client.mintDemoPass({
23220
+ const minted = await explained3(() => client.mintDemoPass({
22666
23221
  email: email3,
22667
23222
  path: paths[0],
22668
23223
  ...expiresInMinutes !== void 0 ? { expiresInMinutes } : {}
@@ -22694,7 +23249,7 @@ function registerDemoCommands(kit, program2, io) {
22694
23249
  });
22695
23250
  ownerFlags(demo.command("list").description("List the demo passes of the workspace (newest first)")).action(async (opts, cmd) => {
22696
23251
  const ctx = resolveContext2(cmd, io);
22697
- const { passes } = await withOwnerSession(ctx, session(opts), (client) => explained2(() => client.demoPasses()));
23252
+ const { passes } = await withOwnerSession(ctx, session(opts), (client) => explained3(() => client.demoPasses()));
22698
23253
  if (ctx.json)
22699
23254
  return printJson2(io, { passes });
22700
23255
  if (passes.length === 0) {
@@ -22714,9 +23269,9 @@ function registerDemoCommands(kit, program2, io) {
22714
23269
  ])
22715
23270
  ]));
22716
23271
  });
22717
- ownerFlags(demo.command("revoke <id>").description("Revoke a demo pass; the sessions it opened end with it")).action(async (id, opts, cmd) => {
23272
+ ownerFlags(demo.command("revoke <id>").description("Revoke a demo pass; the sessions it opened end with it")).action(async (id2, opts, cmd) => {
22718
23273
  const ctx = resolveContext2(cmd, io);
22719
- const pass = await withOwnerSession(ctx, session(opts), (client) => explained2(() => client.revokeDemoPass(id)));
23274
+ const pass = await withOwnerSession(ctx, session(opts), (client) => explained3(() => client.revokeDemoPass(id2)));
22720
23275
  if (ctx.json)
22721
23276
  return printJson2(io, pass);
22722
23277
  io.out.write(`Revoked the demo pass ${pass.id} for ${pass.email}. The sessions it opened are signed out.
@@ -22724,14 +23279,14 @@ function registerDemoCommands(kit, program2, io) {
22724
23279
  });
22725
23280
  }
22726
23281
 
22727
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/files.js
23282
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/files.js
22728
23283
  import { createWriteStream } from "node:fs";
22729
23284
  import { mkdir as mkdir2, readFile, writeFile } from "node:fs/promises";
22730
23285
  import { basename, resolve as resolve2, win32 } from "node:path";
22731
23286
  import { Readable } from "node:stream";
22732
23287
  import { pipeline as pipeline2 } from "node:stream/promises";
22733
23288
 
22734
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/safe-write.js
23289
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/safe-write.js
22735
23290
  import { constants as FS } from "node:fs";
22736
23291
  import { mkdir, open, realpath, unlink } from "node:fs/promises";
22737
23292
  import { dirname as dirname2, isAbsolute, relative, resolve } from "node:path";
@@ -22812,7 +23367,7 @@ async function streamContained(root, relPath, source) {
22812
23367
  }
22813
23368
  }
22814
23369
 
22815
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/files.js
23370
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/files.js
22816
23371
  function safeDownloadName(originalName) {
22817
23372
  const name = basename(win32.basename(originalName));
22818
23373
  if (name === "" || name === "." || name === ".." || name.startsWith(".")) {
@@ -22893,15 +23448,15 @@ function registerFileCommands(kit, program2, io) {
22893
23448
  id: ${result.file.id}
22894
23449
  `);
22895
23450
  });
22896
- files.command("download <id>").description("Download a file by id").option("--out <path>", "write to this exact path (your path, used verbatim)").option("--dir <path>", "directory to write the stored name into (default: .)").action(async (id, opts, cmd) => {
23451
+ files.command("download <id>").description("Download a file by id").option("--out <path>", "write to this exact path (your path, used verbatim)").option("--dir <path>", "directory to write the stored name into (default: .)").action(async (id2, opts, cmd) => {
22897
23452
  const ctx = resolveContext2(cmd, io);
22898
23453
  const apiKey = await requireApiKey2(ctx);
22899
23454
  if (opts.out && opts.dir) {
22900
23455
  throw new CliUsageError("Pass either --out <path> or --dir <path>, not both.");
22901
23456
  }
22902
- const meta3 = await ctx.client.file(id);
23457
+ const meta3 = await ctx.client.file(id2);
22903
23458
  const fetchImpl = io.fetch ?? globalThis.fetch.bind(globalThis);
22904
- const res = await fetchImpl(ctx.client.fileContentUrl(id), {
23459
+ const res = await fetchImpl(ctx.client.fileContentUrl(id2), {
22905
23460
  // This one bypasses the SDK, so it carries the SDK's headers itself:
22906
23461
  // the key, and the selected workspace (a download follows it too).
22907
23462
  headers: {
@@ -22928,18 +23483,18 @@ function registerFileCommands(kit, program2, io) {
22928
23483
  io.out.write(`Downloaded ${meta3.originalName} \u2192 ${out} (${fmtBytes(buf.length)})
22929
23484
  `);
22930
23485
  });
22931
- files.command("rm <id>").description("Delete a file by id").action(async (id, _opts, cmd) => {
23486
+ files.command("rm <id>").description("Delete a file by id").action(async (id2, _opts, cmd) => {
22932
23487
  const ctx = resolveContext2(cmd, io);
22933
23488
  await requireApiKey2(ctx);
22934
- await ctx.client.deleteFile(id);
23489
+ await ctx.client.deleteFile(id2);
22935
23490
  if (ctx.json)
22936
- return printJson2(io, { deleted: id });
22937
- io.out.write(`Deleted ${id}
23491
+ return printJson2(io, { deleted: id2 });
23492
+ io.out.write(`Deleted ${id2}
22938
23493
  `);
22939
23494
  });
22940
23495
  }
22941
23496
 
22942
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/completion.js
23497
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/commands/completion.js
22943
23498
  function commandTree(program2) {
22944
23499
  return program2.commands.filter((c) => !c.name().startsWith("help")).map((c) => ({
22945
23500
  name: c.name(),
@@ -23014,7 +23569,7 @@ function registerCompletionCommand(identity, program2, io) {
23014
23569
  });
23015
23570
  }
23016
23571
 
23017
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/program.js
23572
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/program.js
23018
23573
  function creditFigures(credit) {
23019
23574
  const parts = [
23020
23575
  typeof credit?.credits === "number" ? `this needs ${credit.credits} credits` : null,
@@ -23032,6 +23587,7 @@ function createProgram(kit, definition) {
23032
23587
  registerWorkspaceCommands(kit, program2, io);
23033
23588
  registerProjectCommands(kit, program2, io);
23034
23589
  registerTeamCommands(kit, program2, io);
23590
+ registerWebhookCommands(kit, program2, io);
23035
23591
  registerDemoCommands(kit, program2, io);
23036
23592
  registerTool2(program2, io);
23037
23593
  registerFileCommands(kit, program2, io);
@@ -23068,9 +23624,9 @@ function createProgram(kit, definition) {
23068
23624
  return e.exitCode;
23069
23625
  }
23070
23626
  if (e instanceof PlatformApiError || e instanceof CliAuthError) {
23071
- const explained3 = await explainWorkspaceRefusal(io, e);
23072
- if (explained3) {
23073
- io.err.write(`Error: ${explained3}
23627
+ const explained4 = await explainWorkspaceRefusal(io, e);
23628
+ if (explained4) {
23629
+ io.err.write(`Error: ${explained4}
23074
23630
  `);
23075
23631
  return 1;
23076
23632
  }
@@ -23096,21 +23652,7 @@ function createProgram(kit, definition) {
23096
23652
  return { buildProgram, run: run2 };
23097
23653
  }
23098
23654
 
23099
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/identity.js
23100
- function cliIdentity(identity) {
23101
- return {
23102
- bin: identity.cli.bin,
23103
- tool: identity.slug,
23104
- legacyConfigDir: identity.cli.legacyConfigDir,
23105
- displayName: identity.displayName,
23106
- envPrefix: identity.cli.envPrefix,
23107
- keyPrefix: identity.apiKeyPrefix,
23108
- exportScope: identity.scopes.dataExport,
23109
- cloudUrl: identity.cloud.url
23110
- };
23111
- }
23112
-
23113
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/open.js
23655
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/open.js
23114
23656
  import { spawn } from "node:child_process";
23115
23657
  function platformOpener(platform = process.platform) {
23116
23658
  if (platform === "darwin")
@@ -23136,7 +23678,7 @@ function isInteractive(io) {
23136
23678
  return io.out.isTTY === true;
23137
23679
  }
23138
23680
 
23139
- // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.0.2_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/index.js
23681
+ // ../../node_modules/.pnpm/@antasphere+chassis-cli@1.3.0_hono@4.12.27/node_modules/@antasphere/chassis-cli/dist/index.js
23140
23682
  function defineCli(definition) {
23141
23683
  const { identity, createClient } = definition;
23142
23684
  const config2 = createConfig(identity);
@@ -23154,9 +23696,11 @@ var IDENTITY = {
23154
23696
  scopes: {
23155
23697
  read: "presentations:read",
23156
23698
  write: "presentations:write",
23157
- dataExport: "data:export"
23699
+ dataExport: "data:export",
23700
+ // Managing the workspace's webhook endpoints (PRDCT-3482): on the CLI key like read and write (Romain, 13 October 2026).
23701
+ webhooks: "webhooks:manage"
23158
23702
  },
23159
- cliKeyScopesLabel: "presentations:read+write",
23703
+ cliKeyScopesLabel: "presentations:read+write, webhooks:manage",
23160
23704
  cloud: { url: "https://slideless.antasphere.com" },
23161
23705
  cli: {
23162
23706
  bin: "slideless",
@@ -23173,7 +23717,9 @@ var IDENTITY = {
23173
23717
 
23174
23718
  // ../contract/dist/chassis.js
23175
23719
  var { read, write, dataExport } = IDENTITY.scopes;
23176
- var chassisContract = defineChassisContract({ scopes: [read, write, dataExport] });
23720
+ var chassisContract = defineChassisContract({
23721
+ scopes: [read, write, dataExport, IDENTITY.scopes.webhooks]
23722
+ });
23177
23723
  var scopeSchema2 = chassisContract.scopeSchema;
23178
23724
  var apiKeySchema2 = chassisContract.apiKeySchema;
23179
23725
  var apiKeysListSchema2 = chassisContract.apiKeysListSchema;
@@ -23881,6 +24427,250 @@ var formResponsesSummarySchema = external_exports.object({
23881
24427
  total: external_exports.number().int()
23882
24428
  });
23883
24429
 
24430
+ // ../contract/dist/schemas/apps.js
24431
+ var appEntrySchema = external_exports.object({
24432
+ /** The tool's registry slug (`finance`, `hiring`, …): what picks its drawing and its sentence. */
24433
+ slug: external_exports.string(),
24434
+ /** The tool's display name. */
24435
+ name: external_exports.string(),
24436
+ /** Where opening the tool lands. */
24437
+ launchUrl: external_exports.string(),
24438
+ /** The operator's own sentence for the tool (the file source), else null. */
24439
+ description: external_exports.string().nullable(),
24440
+ /** The person has signed in to the tool (the hub source); false when nothing says so. */
24441
+ connected: external_exports.boolean(),
24442
+ /** When the person first signed in to the tool (the hub source), else null. */
24443
+ firstUsedAt: external_exports.string().nullable(),
24444
+ /** When the person last signed in to the tool (the hub source), else null. */
24445
+ lastUsedAt: external_exports.string().nullable(),
24446
+ /** This very tool: the page shows it, with no button. */
24447
+ current: external_exports.boolean()
24448
+ });
24449
+ var APP_SOURCES = ["hub", "file", "none"];
24450
+ var appsListSchema = external_exports.object({
24451
+ apps: external_exports.array(appEntrySchema),
24452
+ /** The account that signs the person in (the hub), when the instance knows one. */
24453
+ hub: external_exports.object({ url: external_exports.string(), name: external_exports.string() }).nullable(),
24454
+ source: external_exports.enum(APP_SOURCES)
24455
+ });
24456
+
24457
+ // ../contract/dist/schemas/webhooks.js
24458
+ var id = external_exports.string();
24459
+ var isoDate = external_exports.string();
24460
+ var shareLinkFacts = external_exports.object({
24461
+ deckId: id,
24462
+ linkId: id,
24463
+ name: external_exports.string(),
24464
+ purpose: external_exports.string(),
24465
+ pinnedVersion: external_exports.number().int().nullable(),
24466
+ expiresAt: isoDate.nullable(),
24467
+ hasPassword: external_exports.boolean()
24468
+ });
24469
+ var formResponseFacts = external_exports.object({
24470
+ deckId: id,
24471
+ formName: external_exports.string(),
24472
+ responseId: id,
24473
+ revision: external_exports.number().int(),
24474
+ linkId: id.nullable(),
24475
+ version: external_exports.number().int(),
24476
+ source: external_exports.string(),
24477
+ placement: external_exports.string().nullable(),
24478
+ /** The answers as submitted, by field name: a text, or a list for a multiple choice. */
24479
+ answers: external_exports.record(external_exports.string(), external_exports.union([external_exports.string(), external_exports.array(external_exports.string())])),
24480
+ files: external_exports.array(external_exports.object({ id, name: external_exports.string(), sizeBytes: external_exports.number().int() }))
24481
+ });
24482
+ var collaboratorFacts = external_exports.object({
24483
+ deckId: id,
24484
+ collaboratorId: id,
24485
+ email: external_exports.string(),
24486
+ userId: id.nullable()
24487
+ });
24488
+ var annotationFacts = external_exports.object({
24489
+ deckId: id,
24490
+ version: external_exports.number().int(),
24491
+ annotationId: id,
24492
+ linkId: id.nullable(),
24493
+ authorName: external_exports.string().nullable()
24494
+ });
24495
+ var thumbnailFacts = external_exports.object({ deckId: id, versionId: id, version: external_exports.number().int() });
24496
+ var DECK_WEBHOOK_EVENTS = [
24497
+ {
24498
+ type: "deck.created",
24499
+ description: "A deck was created: its first version was pushed, or a deck was duplicated.",
24500
+ subjects: ["deck", "project"],
24501
+ data: external_exports.object({
24502
+ deckId: id,
24503
+ title: external_exports.string(),
24504
+ version: external_exports.number().int(),
24505
+ projectIds: external_exports.array(id),
24506
+ ownerUserId: id,
24507
+ remixedFrom: id.nullable()
24508
+ })
24509
+ },
24510
+ {
24511
+ type: "deck.version_committed",
24512
+ description: "A new version of a deck was pushed.",
24513
+ subjects: ["deck", "project"],
24514
+ data: external_exports.object({
24515
+ deckId: id,
24516
+ version: external_exports.number().int(),
24517
+ title: external_exports.string(),
24518
+ authorUserId: id,
24519
+ authorRole: external_exports.string()
24520
+ })
24521
+ },
24522
+ {
24523
+ type: "deck.updated",
24524
+ description: "A deck\u2019s settings changed (its title, its description, its form notifications\u2026); `fields` names what.",
24525
+ subjects: ["deck", "project"],
24526
+ data: external_exports.object({ deckId: id, fields: external_exports.array(external_exports.string()) })
24527
+ },
24528
+ {
24529
+ type: "deck.deleted",
24530
+ description: "A deck was deleted.",
24531
+ subjects: ["deck", "project"],
24532
+ data: external_exports.object({ deckId: id, title: external_exports.string() })
24533
+ },
24534
+ {
24535
+ type: "deck.project_linked",
24536
+ description: "A deck was put in a project (at creation, or later).",
24537
+ subjects: ["deck", "project"],
24538
+ data: external_exports.object({ deckId: id, projectId: id })
24539
+ },
24540
+ {
24541
+ type: "deck.project_unlinked",
24542
+ description: "A deck was taken out of a project.",
24543
+ subjects: ["deck", "project"],
24544
+ data: external_exports.object({ deckId: id, projectId: id })
24545
+ },
24546
+ {
24547
+ type: "share_link.created",
24548
+ description: "A share link was made for a deck (preview links never emit).",
24549
+ subjects: ["deck", "project", "link"],
24550
+ data: shareLinkFacts
24551
+ },
24552
+ {
24553
+ type: "share_link.updated",
24554
+ description: "A share link changed; `changed` names the fields.",
24555
+ subjects: ["deck", "project", "link"],
24556
+ data: shareLinkFacts.extend({ changed: external_exports.array(external_exports.string()) })
24557
+ },
24558
+ {
24559
+ type: "share_link.revoked",
24560
+ description: "A share link was revoked.",
24561
+ subjects: ["deck", "project", "link"],
24562
+ data: shareLinkFacts
24563
+ },
24564
+ {
24565
+ type: "share_link.sent",
24566
+ description: "A share link was sent by mail from the dashboard.",
24567
+ subjects: ["deck", "project", "link"],
24568
+ data: shareLinkFacts.extend({ recipient: external_exports.string() })
24569
+ },
24570
+ {
24571
+ type: "share_link.viewed",
24572
+ description: "A share link was opened. Grouped per link: the first view is sent at once, then at most one event per link per five minutes carrying the count and the facts of the views since the last one. No address, no identity.",
24573
+ subjects: ["deck", "project", "link"],
24574
+ data: external_exports.object({
24575
+ deckId: id,
24576
+ linkId: id,
24577
+ version: external_exports.number().int().nullable(),
24578
+ views: external_exports.number().int(),
24579
+ firstViewAt: isoDate,
24580
+ lastViewAt: isoDate,
24581
+ referrerHosts: external_exports.array(external_exports.string()),
24582
+ placements: external_exports.array(external_exports.string()),
24583
+ browserFamilies: external_exports.array(external_exports.string())
24584
+ })
24585
+ },
24586
+ {
24587
+ type: "attachment.downloaded",
24588
+ description: "An attachment of a deck was downloaded through a share link (`name` null for the whole bundle).",
24589
+ subjects: ["deck", "project", "link"],
24590
+ data: external_exports.object({ deckId: id, linkId: id, version: external_exports.number().int(), name: external_exports.string().nullable() })
24591
+ },
24592
+ {
24593
+ type: "form.response_submitted",
24594
+ description: "A form inside a deck received a response; `answers` carries it.",
24595
+ subjects: ["deck", "project", "link"],
24596
+ data: formResponseFacts
24597
+ },
24598
+ {
24599
+ type: "form.response_edited",
24600
+ description: "A respondent edited their response through their edit link; `answers` is the new revision.",
24601
+ subjects: ["deck", "project", "link"],
24602
+ data: formResponseFacts
24603
+ },
24604
+ {
24605
+ type: "form.file_uploaded",
24606
+ description: "A respondent dropped a file into a form field (before the response is submitted).",
24607
+ subjects: ["deck", "project", "link"],
24608
+ data: external_exports.object({
24609
+ deckId: id,
24610
+ formName: external_exports.string(),
24611
+ linkId: id,
24612
+ uploadId: id,
24613
+ name: external_exports.string(),
24614
+ sizeBytes: external_exports.number().int()
24615
+ })
24616
+ },
24617
+ {
24618
+ type: "form.response_deleted",
24619
+ description: "A form response was deleted from the dashboard.",
24620
+ subjects: ["deck", "project"],
24621
+ data: external_exports.object({ deckId: id, responseId: id })
24622
+ },
24623
+ {
24624
+ type: "collaborator.invited",
24625
+ description: "Someone was invited to work on a deck.",
24626
+ subjects: ["deck", "project"],
24627
+ data: collaboratorFacts
24628
+ },
24629
+ {
24630
+ type: "collaborator.revoked",
24631
+ description: "A collaborator\u2019s grant on a deck was revoked (by hand, or with a member\u2019s removal).",
24632
+ subjects: ["deck", "project"],
24633
+ data: collaboratorFacts
24634
+ },
24635
+ {
24636
+ type: "collaborator.claimed",
24637
+ description: "An invited collaborator claimed their grant on a deck.",
24638
+ subjects: ["deck", "project"],
24639
+ data: collaboratorFacts
24640
+ },
24641
+ {
24642
+ type: "annotation.created",
24643
+ description: "An annotation was left on a deck version, by a viewer through a share link or by a member.",
24644
+ subjects: ["deck", "project", "link"],
24645
+ data: annotationFacts
24646
+ },
24647
+ {
24648
+ type: "annotation.resolved",
24649
+ description: "An annotation was marked resolved.",
24650
+ subjects: ["deck", "project"],
24651
+ data: annotationFacts
24652
+ },
24653
+ {
24654
+ type: "annotation.deleted",
24655
+ description: "An annotation was deleted.",
24656
+ subjects: ["deck", "project"],
24657
+ data: annotationFacts
24658
+ },
24659
+ {
24660
+ type: "thumbnail.rendered",
24661
+ description: "The still image of a deck version is ready.",
24662
+ subjects: ["deck", "project"],
24663
+ data: thumbnailFacts
24664
+ },
24665
+ {
24666
+ type: "thumbnail.failed",
24667
+ description: "The still image of a deck version could not be made.",
24668
+ subjects: ["deck", "project"],
24669
+ data: thumbnailFacts
24670
+ }
24671
+ ];
24672
+ var DECK_WEBHOOK_EVENT_TYPES = DECK_WEBHOOK_EVENTS.map((e) => e.type);
24673
+
23884
24674
  // ../contract/dist/embed.js
23885
24675
  var EMBED_PLACEMENT_RE = /^[A-Za-z0-9._-]{1,64}$/;
23886
24676
  function buildEmbedSnippets(opts) {
@@ -23946,8 +24736,8 @@ var PlatformClient = class extends ChassisClient {
23946
24736
  const { presentations } = await this.presentations({ type, default: true, limit: 1 });
23947
24737
  return presentations[0] ?? null;
23948
24738
  }
23949
- presentation(id) {
23950
- return this.request("GET", `/presentations/${encodeURIComponent(id)}`);
24739
+ presentation(id2) {
24740
+ return this.request("GET", `/presentations/${encodeURIComponent(id2)}`);
23951
24741
  }
23952
24742
  /**
23953
24743
  * Update mutable deck properties. `metadata` replaces the stored object
@@ -23959,12 +24749,12 @@ var PlatformClient = class extends ChassisClient {
23959
24749
  * made private, 403 `forbidden` when the caller reads the deck but may not
23960
24750
  * change that property.
23961
24751
  */
23962
- updatePresentation(id, patch) {
23963
- return this.request("PATCH", `/presentations/${encodeURIComponent(id)}`, patch);
24752
+ updatePresentation(id2, patch) {
24753
+ return this.request("PATCH", `/presentations/${encodeURIComponent(id2)}`, patch);
23964
24754
  }
23965
24755
  /** Soft delete: versions and share tokens stop resolving. */
23966
- deletePresentation(id) {
23967
- return this.request("DELETE", `/presentations/${encodeURIComponent(id)}`);
24756
+ deletePresentation(id2) {
24757
+ return this.request("DELETE", `/presentations/${encodeURIComponent(id2)}`);
23968
24758
  }
23969
24759
  /**
23970
24760
  * Duplicate a deck (PRDCT-2279): a new deck in the same workspace whose
@@ -23972,8 +24762,8 @@ var PlatformClient = class extends ChassisClient {
23972
24762
  * re-uploaded. `version` picks the source version (current when omitted),
23973
24763
  * `title` names the copy. Idempotency-Key aware like the other creates.
23974
24764
  */
23975
- duplicatePresentation(id, req = {}, opts = {}) {
23976
- return this.request("POST", `/presentations/${encodeURIComponent(id)}/duplicate`, req, idempotencyHeader(opts));
24765
+ duplicatePresentation(id2, req = {}, opts = {}) {
24766
+ return this.request("POST", `/presentations/${encodeURIComponent(id2)}/duplicate`, req, idempotencyHeader(opts));
23977
24767
  }
23978
24768
  // ── Projects (ADR 026) ────────────────────────────────────────────────────
23979
24769
  // The chassis client carries the projects themselves (`projects()`,
@@ -23982,12 +24772,12 @@ var PlatformClient = class extends ChassisClient {
23982
24772
  * Link a deck to a project: the project's members read it from then on.
23983
24773
  * The deck administrator's act, with editor or more on the project.
23984
24774
  */
23985
- linkPresentationProject(id, projectId) {
23986
- return this.request("PUT", `/presentations/${encodeURIComponent(id)}/projects/${encodeURIComponent(projectId)}`);
24775
+ linkPresentationProject(id2, projectId) {
24776
+ return this.request("PUT", `/presentations/${encodeURIComponent(id2)}/projects/${encodeURIComponent(projectId)}`);
23987
24777
  }
23988
24778
  /** Take a deck out of a project (the deck administrator, or a project manager). */
23989
- unlinkPresentationProject(id, projectId) {
23990
- return this.request("DELETE", `/presentations/${encodeURIComponent(id)}/projects/${encodeURIComponent(projectId)}`);
24779
+ unlinkPresentationProject(id2, projectId) {
24780
+ return this.request("DELETE", `/presentations/${encodeURIComponent(id2)}/projects/${encodeURIComponent(projectId)}`);
23991
24781
  }
23992
24782
  /** The project's brand: the brand reference its decks are authored with, or null. */
23993
24783
  projectBrand(projectId) {
@@ -24035,28 +24825,28 @@ var PlatformClient = class extends ChassisClient {
24035
24825
  * Commit a new immutable version. `expectedBaseVersion` must equal the
24036
24826
  * deck's currentVersion or the server answers 409 version_conflict.
24037
24827
  */
24038
- commitVersion(id, req) {
24039
- return this.request("POST", `/presentations/${encodeURIComponent(id)}/versions`, req);
24828
+ commitVersion(id2, req) {
24829
+ return this.request("POST", `/presentations/${encodeURIComponent(id2)}/versions`, req);
24040
24830
  }
24041
24831
  // ── Pull ──────────────────────────────────────────────────────────────────
24042
- presentationVersions(id, params = {}) {
24043
- return this.request("GET", this.pathWithQuery(`/presentations/${encodeURIComponent(id)}/versions`, params));
24832
+ presentationVersions(id2, params = {}) {
24833
+ return this.request("GET", this.pathWithQuery(`/presentations/${encodeURIComponent(id2)}/versions`, params));
24044
24834
  }
24045
24835
  /** One version including its full manifest (path → sha256). */
24046
- presentationVersion(id, version2) {
24047
- return this.request("GET", `/presentations/${encodeURIComponent(id)}/versions/${version2}`);
24836
+ presentationVersion(id2, version2) {
24837
+ return this.request("GET", `/presentations/${encodeURIComponent(id2)}/versions/${version2}`);
24048
24838
  }
24049
24839
  /** URL of the streamed asset download endpoint (content-addressed). */
24050
- presentationAssetUrl(id, sha256) {
24051
- return `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id)}/assets/${encodeURIComponent(sha256)}`;
24840
+ presentationAssetUrl(id2, sha256) {
24841
+ return `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id2)}/assets/${encodeURIComponent(sha256)}`;
24052
24842
  }
24053
24843
  /**
24054
24844
  * Downloads one deck blob. Returns the raw Response so callers can stream
24055
24845
  * the bytes; a non-2xx answer throws PlatformApiError like every method.
24056
24846
  */
24057
- async downloadPresentationAsset(id, sha256) {
24847
+ async downloadPresentationAsset(id2, sha256) {
24058
24848
  const headers = this.baseHeaders();
24059
- const res = await this.fetchImpl(this.presentationAssetUrl(id, sha256), {
24849
+ const res = await this.fetchImpl(this.presentationAssetUrl(id2, sha256), {
24060
24850
  method: "GET",
24061
24851
  headers,
24062
24852
  credentials: "same-origin",
@@ -24070,8 +24860,8 @@ var PlatformClient = class extends ChassisClient {
24070
24860
  return res;
24071
24861
  }
24072
24862
  /** URL of the streamed attachments zip of one version (PRDCT-2278). */
24073
- versionAttachmentsZipUrl(id, version2) {
24074
- return `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id)}/versions/${version2}/downloads.zip`;
24863
+ versionAttachmentsZipUrl(id2, version2) {
24864
+ return `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id2)}/versions/${version2}/downloads.zip`;
24075
24865
  }
24076
24866
  /**
24077
24867
  * Downloads one version's attachments (its `downloads/` folder) as a
@@ -24079,24 +24869,24 @@ var PlatformClient = class extends ChassisClient {
24079
24869
  * Content-Disposition carries it). Returns the raw Response so callers can
24080
24870
  * stream the bytes; 404 no_attachments when the version carries none.
24081
24871
  */
24082
- async downloadVersionAttachmentsZip(id, version2) {
24083
- return this.rawDownload(this.versionAttachmentsZipUrl(id, version2));
24872
+ async downloadVersionAttachmentsZip(id2, version2) {
24873
+ return this.rawDownload(this.versionAttachmentsZipUrl(id2, version2));
24084
24874
  }
24085
24875
  /**
24086
24876
  * URL of one attachment of one version by its name (the path relative to
24087
24877
  * `downloads/`). The name is ONE path segment on the wire: a nested name
24088
24878
  * (`sub/file.csv`) is percent-encoded whole (`sub%2Ffile.csv`).
24089
24879
  */
24090
- versionAttachmentUrl(id, version2, name) {
24091
- return `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id)}/versions/${version2}/downloads/${encodeURIComponent(name)}`;
24880
+ versionAttachmentUrl(id2, version2, name) {
24881
+ return `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id2)}/versions/${version2}/downloads/${encodeURIComponent(name)}`;
24092
24882
  }
24093
24883
  /** Downloads one attachment (attachment disposition, the manifest content type). Raw Response. */
24094
- async downloadVersionAttachment(id, version2, name) {
24095
- return this.rawDownload(this.versionAttachmentUrl(id, version2, name));
24884
+ async downloadVersionAttachment(id2, version2, name) {
24885
+ return this.rawDownload(this.versionAttachmentUrl(id2, version2, name));
24096
24886
  }
24097
24887
  /** URL of a version's still image (WebP). */
24098
- versionThumbnailUrl(id, version2) {
24099
- return `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id)}/versions/${version2}/thumbnail`;
24888
+ versionThumbnailUrl(id2, version2) {
24889
+ return `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id2)}/versions/${version2}/thumbnail`;
24100
24890
  }
24101
24891
  /**
24102
24892
  * A version's still image. Raw Response; a non-2xx throws PlatformApiError
@@ -24105,8 +24895,8 @@ var PlatformClient = class extends ChassisClient {
24105
24895
  * `private, no-cache` with an ETag, so the browser keeps the bytes and revalidates
24106
24896
  * on each ask (a 304), and a read right that was revoked is felt at once.
24107
24897
  */
24108
- async versionThumbnail(id, version2) {
24109
- const res = await this.fetchImpl(this.versionThumbnailUrl(id, version2), {
24898
+ async versionThumbnail(id2, version2) {
24899
+ const res = await this.fetchImpl(this.versionThumbnailUrl(id2, version2), {
24110
24900
  method: "GET",
24111
24901
  headers: this.baseHeaders(),
24112
24902
  credentials: "same-origin",
@@ -24120,17 +24910,17 @@ var PlatformClient = class extends ChassisClient {
24120
24910
  return res;
24121
24911
  }
24122
24912
  /** URL of the streamed AGENT.md briefing endpoint. */
24123
- agentDocUrl(id, version2) {
24124
- const base = `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id)}/agent-doc`;
24913
+ agentDocUrl(id2, version2) {
24914
+ const base = `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id2)}/agent-doc`;
24125
24915
  return version2 !== void 0 ? `${base}?version=${version2}` : base;
24126
24916
  }
24127
24917
  /**
24128
24918
  * The deck's AGENT.md briefing as markdown text (current version, or a
24129
24919
  * pinned one). 404 agent_doc_not_found when that version ships none.
24130
24920
  */
24131
- async agentDoc(id, version2) {
24921
+ async agentDoc(id2, version2) {
24132
24922
  const headers = this.baseHeaders();
24133
- const res = await this.fetchImpl(this.agentDocUrl(id, version2), {
24923
+ const res = await this.fetchImpl(this.agentDocUrl(id2, version2), {
24134
24924
  method: "GET",
24135
24925
  headers,
24136
24926
  credentials: "same-origin",
@@ -24144,12 +24934,12 @@ var PlatformClient = class extends ChassisClient {
24144
24934
  return res.text();
24145
24935
  }
24146
24936
  // ── Sharing ───────────────────────────────────────────────────────────────
24147
- shareTokens(id, params = {}) {
24148
- return this.request("GET", this.pathWithQuery(`/presentations/${encodeURIComponent(id)}/tokens`, params));
24937
+ shareTokens(id2, params = {}) {
24938
+ return this.request("GET", this.pathWithQuery(`/presentations/${encodeURIComponent(id2)}/tokens`, params));
24149
24939
  }
24150
24940
  /** The returned `secret`/`url` appear only here — never retrievable again. */
24151
- createShareToken(id, req, opts = {}) {
24152
- return this.request("POST", `/presentations/${encodeURIComponent(id)}/tokens`, req, idempotencyHeader(opts));
24941
+ createShareToken(id2, req, opts = {}) {
24942
+ return this.request("POST", `/presentations/${encodeURIComponent(id2)}/tokens`, req, idempotencyHeader(opts));
24153
24943
  }
24154
24944
  /**
24155
24945
  * Mint the dashboard's transient preview token (deck owner / workspace
@@ -24157,8 +24947,8 @@ var PlatformClient = class extends ChassisClient {
24157
24947
  * 'preview', 1 h expiry, hidden from the sharing panel, excluded from view
24158
24948
  * stats, immutable. `version` pins the preview; omitted = latest.
24159
24949
  */
24160
- createPreviewToken(id, req = {}) {
24161
- return this.request("POST", `/presentations/${encodeURIComponent(id)}/preview-token`, req);
24950
+ createPreviewToken(id2, req = {}) {
24951
+ return this.request("POST", `/presentations/${encodeURIComponent(id2)}/preview-token`, req);
24162
24952
  }
24163
24953
  /**
24164
24954
  * Per-view events of one share token, newest first (cursor-paginated):
@@ -24166,31 +24956,31 @@ var PlatformClient = class extends ChassisClient {
24166
24956
  * placement label, and a coarse browser family. No IP, no geolocation,
24167
24957
  * no full referrer URLs — the server never stores them.
24168
24958
  */
24169
- shareTokenViews(id, tokenId, params = {}) {
24170
- return this.request("GET", this.pathWithQuery(`/presentations/${encodeURIComponent(id)}/tokens/${encodeURIComponent(tokenId)}/views`, params));
24959
+ shareTokenViews(id2, tokenId, params = {}) {
24960
+ return this.request("GET", this.pathWithQuery(`/presentations/${encodeURIComponent(id2)}/tokens/${encodeURIComponent(tokenId)}/views`, params));
24171
24961
  }
24172
24962
  /** Pin/unpin version, rename, the per-link switches (annotate, forms, downloads, bar, remembering, file uploads), expiry, password (null clears). */
24173
- updateShareToken(id, tokenId, patch) {
24174
- return this.request("PATCH", `/presentations/${encodeURIComponent(id)}/tokens/${encodeURIComponent(tokenId)}`, patch);
24963
+ updateShareToken(id2, tokenId, patch) {
24964
+ return this.request("PATCH", `/presentations/${encodeURIComponent(id2)}/tokens/${encodeURIComponent(tokenId)}`, patch);
24175
24965
  }
24176
24966
  /** Soft revoke — access stats survive. */
24177
- revokeShareToken(id, tokenId) {
24178
- return this.request("DELETE", `/presentations/${encodeURIComponent(id)}/tokens/${encodeURIComponent(tokenId)}`);
24967
+ revokeShareToken(id2, tokenId) {
24968
+ return this.request("DELETE", `/presentations/${encodeURIComponent(id2)}/tokens/${encodeURIComponent(tokenId)}`);
24179
24969
  }
24180
24970
  /** Email the viewer link to a recipient (best-effort on top of the copyable URL). */
24181
- sendShareToken(id, tokenId, req) {
24182
- return this.request("POST", `/presentations/${encodeURIComponent(id)}/tokens/${encodeURIComponent(tokenId)}/send`, req);
24971
+ sendShareToken(id2, tokenId, req) {
24972
+ return this.request("POST", `/presentations/${encodeURIComponent(id2)}/tokens/${encodeURIComponent(tokenId)}/send`, req);
24183
24973
  }
24184
24974
  // ── Collaborators ─────────────────────────────────────────────────────────
24185
- collaborators(id, params = {}) {
24186
- return this.request("GET", this.pathWithQuery(`/presentations/${encodeURIComponent(id)}/collaborators`, params));
24975
+ collaborators(id2, params = {}) {
24976
+ return this.request("GET", this.pathWithQuery(`/presentations/${encodeURIComponent(id2)}/collaborators`, params));
24187
24977
  }
24188
24978
  /** `claimUrl` is always returned — email delivery is best-effort on top. */
24189
- inviteCollaborator(id, req, opts = {}) {
24190
- return this.request("POST", `/presentations/${encodeURIComponent(id)}/collaborators`, req, idempotencyHeader(opts));
24979
+ inviteCollaborator(id2, req, opts = {}) {
24980
+ return this.request("POST", `/presentations/${encodeURIComponent(id2)}/collaborators`, req, idempotencyHeader(opts));
24191
24981
  }
24192
- removeCollaborator(id, collaboratorId) {
24193
- return this.request("DELETE", `/presentations/${encodeURIComponent(id)}/collaborators/${encodeURIComponent(collaboratorId)}`);
24982
+ removeCollaborator(id2, collaboratorId) {
24983
+ return this.request("DELETE", `/presentations/${encodeURIComponent(id2)}/collaborators/${encodeURIComponent(collaboratorId)}`);
24194
24984
  }
24195
24985
  /** Public: resolves a collaborator claim token for the claim page. */
24196
24986
  lookupCollaboratorInvite(token) {
@@ -24214,21 +25004,21 @@ var PlatformClient = class extends ChassisClient {
24214
25004
  const qs = query.toString();
24215
25005
  return qs ? `${base}?${qs}` : base;
24216
25006
  }
24217
- annotations(id, params = {}) {
24218
- return this.request("GET", this.pathWithAnnotationQuery(`/presentations/${encodeURIComponent(id)}/annotations`, params));
25007
+ annotations(id2, params = {}) {
25008
+ return this.request("GET", this.pathWithAnnotationQuery(`/presentations/${encodeURIComponent(id2)}/annotations`, params));
24219
25009
  }
24220
25010
  /** Workspace-wide inbox: annotations across all decks, newest first. */
24221
25011
  annotationInbox(params = {}) {
24222
25012
  return this.request("GET", this.pathWithAnnotationQuery("/annotations", params));
24223
25013
  }
24224
- createAnnotation(id, req) {
24225
- return this.request("POST", `/presentations/${encodeURIComponent(id)}/annotations`, req);
25014
+ createAnnotation(id2, req) {
25015
+ return this.request("POST", `/presentations/${encodeURIComponent(id2)}/annotations`, req);
24226
25016
  }
24227
- updateAnnotation(id, annotationId, patch) {
24228
- return this.request("PATCH", `/presentations/${encodeURIComponent(id)}/annotations/${encodeURIComponent(annotationId)}`, patch);
25017
+ updateAnnotation(id2, annotationId, patch) {
25018
+ return this.request("PATCH", `/presentations/${encodeURIComponent(id2)}/annotations/${encodeURIComponent(annotationId)}`, patch);
24229
25019
  }
24230
- deleteAnnotation(id, annotationId) {
24231
- return this.request("DELETE", `/presentations/${encodeURIComponent(id)}/annotations/${encodeURIComponent(annotationId)}`);
25020
+ deleteAnnotation(id2, annotationId) {
25021
+ return this.request("DELETE", `/presentations/${encodeURIComponent(id2)}/annotations/${encodeURIComponent(annotationId)}`);
24232
25022
  }
24233
25023
  // ── Form responses (ADR 022) ──────────────────────────────────────────────
24234
25024
  pathWithFormResponseQuery(base, params) {
@@ -24255,8 +25045,8 @@ var PlatformClient = class extends ChassisClient {
24255
25045
  * form, share link, source (link/embed), placement label, and time.
24256
25046
  * Payload values are the respondent's RAW input — escape before rendering.
24257
25047
  */
24258
- formResponses(id, params = {}) {
24259
- return this.request("GET", this.pathWithFormResponseQuery(`/presentations/${encodeURIComponent(id)}/responses`, params));
25048
+ formResponses(id2, params = {}) {
25049
+ return this.request("GET", this.pathWithFormResponseQuery(`/presentations/${encodeURIComponent(id2)}/responses`, params));
24260
25050
  }
24261
25051
  /**
24262
25052
  * One response with its edit history (PRDCT-2329): the current row and
@@ -24264,8 +25054,8 @@ var PlatformClient = class extends ChassisClient {
24264
25054
  * written through. Payload values are RAW respondent input at every
24265
25055
  * revision — escape before rendering.
24266
25056
  */
24267
- formResponse(id, responseId) {
24268
- return this.request("GET", `/presentations/${encodeURIComponent(id)}/responses/${encodeURIComponent(responseId)}`);
25057
+ formResponse(id2, responseId) {
25058
+ return this.request("GET", `/presentations/${encodeURIComponent(id2)}/responses/${encodeURIComponent(responseId)}`);
24269
25059
  }
24270
25060
  // The files of form responses (PRDCT-2403): what respondents uploaded into
24271
25061
  // a form's file fields. `FormResponse.files` lists them (RAW respondent
@@ -24273,30 +25063,30 @@ var PlatformClient = class extends ChassisClient {
24273
25063
  // path); these three calls fetch the bytes. Same return shape as every
24274
25064
  // streamed download here: the raw Response, PlatformApiError on a non-2xx.
24275
25065
  /** URL of one uploaded file of one response (attachment + nosniff, Range supported). */
24276
- formResponseFileUrl(id, responseId, fileId) {
24277
- return `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id)}/responses/${encodeURIComponent(responseId)}/files/${encodeURIComponent(fileId)}`;
25066
+ formResponseFileUrl(id2, responseId, fileId) {
25067
+ return `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id2)}/responses/${encodeURIComponent(responseId)}/files/${encodeURIComponent(fileId)}`;
24278
25068
  }
24279
25069
  /**
24280
25070
  * Downloads one file a respondent uploaded. Raw Response so callers can
24281
25071
  * stream it; verify the bytes against the wire's `sizeBytes` and `sha256`
24282
25072
  * before keeping them.
24283
25073
  */
24284
- async downloadFormResponseFile(id, responseId, fileId) {
24285
- return this.rawDownload(this.formResponseFileUrl(id, responseId, fileId));
25074
+ async downloadFormResponseFile(id2, responseId, fileId) {
25075
+ return this.rawDownload(this.formResponseFileUrl(id2, responseId, fileId));
24286
25076
  }
24287
25077
  /** URL of one response's files as one zip (`<field>/<file>`). */
24288
- formResponseFilesZipUrl(id, responseId) {
24289
- return `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id)}/responses/${encodeURIComponent(responseId)}/files.zip`;
25078
+ formResponseFilesZipUrl(id2, responseId) {
25079
+ return `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id2)}/responses/${encodeURIComponent(responseId)}/files.zip`;
24290
25080
  }
24291
25081
  /**
24292
25082
  * Downloads one response's uploaded files as a streamed store-only zip (the
24293
25083
  * Content-Disposition carries its name). 404 no_files when it holds none.
24294
25084
  */
24295
- async downloadFormResponseFilesZip(id, responseId) {
24296
- return this.rawDownload(this.formResponseFilesZipUrl(id, responseId));
25085
+ async downloadFormResponseFilesZip(id2, responseId) {
25086
+ return this.rawDownload(this.formResponseFilesZipUrl(id2, responseId));
24297
25087
  }
24298
25088
  /** URL of the whole deck's form-files zip, with its filters. */
24299
- formResponsesFilesZipUrl(id, params = {}) {
25089
+ formResponsesFilesZipUrl(id2, params = {}) {
24300
25090
  const query = new URLSearchParams();
24301
25091
  if (params.form)
24302
25092
  query.set("form", params.form);
@@ -24309,7 +25099,7 @@ var PlatformClient = class extends ChassisClient {
24309
25099
  if (params.since)
24310
25100
  query.set("since", params.since);
24311
25101
  const qs = query.toString();
24312
- const base = `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id)}/responses/files.zip`;
25102
+ const base = `${this.baseUrl}/api/v1/presentations/${encodeURIComponent(id2)}/responses/files.zip`;
24313
25103
  return qs ? `${base}?${qs}` : base;
24314
25104
  }
24315
25105
  /**
@@ -24318,16 +25108,23 @@ var PlatformClient = class extends ChassisClient {
24318
25108
  * listing (form, share link, source, placement, time). 404 no_files when
24319
25109
  * nothing matches.
24320
25110
  */
24321
- async downloadFormResponsesFilesZip(id, params = {}) {
24322
- return this.rawDownload(this.formResponsesFilesZipUrl(id, params));
25111
+ async downloadFormResponsesFilesZip(id2, params = {}) {
25112
+ return this.rawDownload(this.formResponsesFilesZipUrl(id2, params));
24323
25113
  }
24324
25114
  /** Grouped counts per form × link × source × placement, plus the deck total. */
24325
- formResponsesSummary(id) {
24326
- return this.request("GET", `/presentations/${encodeURIComponent(id)}/responses/summary`);
25115
+ formResponsesSummary(id2) {
25116
+ return this.request("GET", `/presentations/${encodeURIComponent(id2)}/responses/summary`);
24327
25117
  }
24328
25118
  /** Owner moderation: delete one response (audited server-side). */
24329
- deleteFormResponse(id, responseId) {
24330
- return this.request("DELETE", `/presentations/${encodeURIComponent(id)}/responses/${encodeURIComponent(responseId)}`);
25119
+ deleteFormResponse(id2, responseId) {
25120
+ return this.request("DELETE", `/presentations/${encodeURIComponent(id2)}/responses/${encodeURIComponent(responseId)}`);
25121
+ }
25122
+ // ── Apps ──────────────────────────────────────────────────────────────────
25123
+ // The other tools of the organization: a browser session's alone (an API key
25124
+ // or an OAuth token is refused 403). `me()` is the chassis client's.
25125
+ /** The tools the caller may open, the account that signs them in, and where the list came from. */
25126
+ apps() {
25127
+ return this.request("GET", "/apps");
24331
25128
  }
24332
25129
  };
24333
25130
 
@@ -24348,6 +25145,16 @@ var requireApiKey = cli.requireApiKey;
24348
25145
  import { readFile as readFile3, stat as stat2 } from "node:fs/promises";
24349
25146
  import { join as join4 } from "node:path";
24350
25147
 
25148
+ // ../../node_modules/.pnpm/@antasphere+cli-core@0.5.0/node_modules/@antasphere/cli-core/dist/resolve.js
25149
+ var CliUsageError2 = class extends Error {
25150
+ exitCode;
25151
+ constructor(message, opts = {}) {
25152
+ super(message);
25153
+ this.name = "CliUsageError";
25154
+ this.exitCode = opts.exitCode ?? 1;
25155
+ }
25156
+ };
25157
+
24351
25158
  // src/manifest.ts
24352
25159
  import { createHash } from "node:crypto";
24353
25160
  import { createReadStream } from "node:fs";
@@ -24603,7 +25410,7 @@ function isReferenceType(value) {
24603
25410
  function parseReferenceType(value) {
24604
25411
  const wanted = value.trim().toLowerCase();
24605
25412
  if (isReferenceType(wanted)) return wanted;
24606
- throw new CliUsageError(`--type must be one of ${REFERENCE_TYPES.join(", ")} (got "${value}")`);
25413
+ throw new CliUsageError2(`--type must be one of ${REFERENCE_TYPES.join(", ")} (got "${value}")`);
24607
25414
  }
24608
25415
  var OPEN_FENCE = /^---[ \t]*$/;
24609
25416
  var CLOSE_FENCE = /^(?:---|\.\.\.)[ \t]*$/;
@@ -24685,7 +25492,7 @@ function referenceLines(refs) {
24685
25492
  }
24686
25493
  function resolveReference(candidates, value, what) {
24687
25494
  const wanted = value.trim();
24688
- if (!wanted) throw new CliUsageError(`Name a ${what}: its id, its title, or the start of its title.`);
25495
+ if (!wanted) throw new CliUsageError2(`Name a ${what}: its id, its title, or the start of its title.`);
24689
25496
  if (isDeckId(wanted)) {
24690
25497
  const byId = candidates.find((r) => r.id.toLowerCase() === wanted.toLowerCase());
24691
25498
  if (byId) return byId;
@@ -24697,13 +25504,13 @@ function resolveReference(candidates, value, what) {
24697
25504
  const prefixed = candidates.filter((r) => r.title.trim().toLowerCase().startsWith(lower));
24698
25505
  if (prefixed.length === 1) return prefixed[0];
24699
25506
  if (prefixed.length > 1) throw ambiguous(prefixed, wanted, what);
24700
- throw new CliUsageError(
25507
+ throw new CliUsageError2(
24701
25508
  `No ${what} named "${wanted}" among the ones you can read` + (candidates.length > 0 ? `. Yours:
24702
25509
  ${referenceLines(candidates)}` : ` (there are none).`)
24703
25510
  );
24704
25511
  }
24705
25512
  function ambiguous(matches, wanted, what) {
24706
- return new CliUsageError(
25513
+ return new CliUsageError2(
24707
25514
  `"${wanted}" names several ${what}s. Name one by its id:
24708
25515
  ${referenceLines(matches)}`
24709
25516
  );
@@ -24712,7 +25519,7 @@ function splitRefAtVersion(value) {
24712
25519
  const m = value.match(/^(.*)@(\d+)$/);
24713
25520
  if (!m) return { ref: value, version: void 0 };
24714
25521
  const version2 = Number(m[2]);
24715
- if (version2 < 1) throw new CliUsageError(`"${value}": a version is a whole number from 1.`);
25522
+ if (version2 < 1) throw new CliUsageError2(`"${value}": a version is a whole number from 1.`);
24716
25523
  return { ref: m[1], version: version2 };
24717
25524
  }
24718
25525
  var PROVENANCE_KEY = "references";
@@ -25494,10 +26301,10 @@ function registerContentCommands(program2, io) {
25494
26301
  `);
25495
26302
  openInBrowser(io, url2);
25496
26303
  });
25497
- program2.command("agent-doc [id]").description(`Print a deck's ${AGENT_DOC_PATH} briefing (id defaults to the ${LINK_FILENAME} link in .)`).option("--at <version>", "read this version instead of the latest", (v) => parseInt(v, 10)).option("--out <file>", "write to a file instead of stdout").action(async (id, opts, cmd) => {
26304
+ program2.command("agent-doc [id]").description(`Print a deck's ${AGENT_DOC_PATH} briefing (id defaults to the ${LINK_FILENAME} link in .)`).option("--at <version>", "read this version instead of the latest", (v) => parseInt(v, 10)).option("--out <file>", "write to a file instead of stdout").action(async (id2, opts, cmd) => {
25498
26305
  const ctx = resolveContext(cmd, io);
25499
26306
  await requireApiKey(ctx);
25500
- let deckId = id ?? null;
26307
+ let deckId = id2 ?? null;
25501
26308
  if (!deckId) {
25502
26309
  const link = await readLink(resolve6("."));
25503
26310
  if (!link) {
@@ -25533,13 +26340,13 @@ function registerContentCommands(program2, io) {
25533
26340
  });
25534
26341
  program2.command("pull [id] [path]").description(
25535
26342
  `Download a deck version to a folder (id defaults to the ${LINK_FILENAME} link in the target)`
25536
- ).option("--at <version>", "pull this version instead of the latest", (v) => parseInt(v, 10)).action(async (id, path, opts, cmd) => {
26343
+ ).option("--at <version>", "pull this version instead of the latest", (v) => parseInt(v, 10)).action(async (id2, path, opts, cmd) => {
25537
26344
  const ctx = resolveContext(cmd, io);
25538
26345
  await requireApiKey(ctx);
25539
26346
  const linkMismatch = (linked) => new CliUsageError(
25540
26347
  `${LINK_FILENAME} links this folder to ${linked}, but you are pulling from ${ctx.baseUrl}. Pull into a different folder, or delete ${LINK_FILENAME} first.`
25541
26348
  );
25542
- let deckId = id ?? null;
26349
+ let deckId = id2 ?? null;
25543
26350
  let dest = path ?? null;
25544
26351
  if (!deckId) {
25545
26352
  const link = await readLink(resolve6(dest ?? "."));
@@ -25578,10 +26385,10 @@ function registerContentCommands(program2, io) {
25578
26385
  );
25579
26386
  });
25580
26387
  program2.command("pull-annotations [id]").description(`List a deck's annotations (id defaults to the ${LINK_FILENAME} link in .)`).option("--version <n>", "only notes anchored to this version", (v) => parseInt(v, 10)).option("--status <status>", "open | resolved").option("--out <file>", "write the annotations as JSON to this file").action(
25581
- async (id, opts, cmd) => {
26388
+ async (id2, opts, cmd) => {
25582
26389
  const ctx = resolveContext(cmd, io);
25583
26390
  await requireApiKey(ctx);
25584
- let deckId = id ?? null;
26391
+ let deckId = id2 ?? null;
25585
26392
  if (!deckId) {
25586
26393
  const link = await readLink(resolve6("."));
25587
26394
  if (!link) {
@@ -25632,10 +26439,10 @@ function registerContentCommands(program2, io) {
25632
26439
  );
25633
26440
  const annotation = program2.command("annotation").description("Update deck annotations (pull-annotations lists them)");
25634
26441
  annotation.command("resolve <id> <annotationId>").description("Mark an annotation resolved").action(
25635
- (id, annotationId, _opts, cmd) => setAnnotationStatus(cmd, io, id, annotationId, "resolved")
26442
+ (id2, annotationId, _opts, cmd) => setAnnotationStatus(cmd, io, id2, annotationId, "resolved")
25636
26443
  );
25637
26444
  annotation.command("reopen <id> <annotationId>").description("Reopen a resolved annotation").action(
25638
- (id, annotationId, _opts, cmd) => setAnnotationStatus(cmd, io, id, annotationId, "open")
26445
+ (id2, annotationId, _opts, cmd) => setAnnotationStatus(cmd, io, id2, annotationId, "open")
25639
26446
  );
25640
26447
  program2.command("dev [path]").description(
25641
26448
  "Serve the deck folder locally with the exact viewer sandbox headers + live reload (no backend)"
@@ -25964,10 +26771,10 @@ function openAfterPush(ctx, url2, input) {
25964
26771
  ctx.io.out.write(" opened in your browser (--no-open to skip)\n");
25965
26772
  openInBrowser(ctx.io, url2);
25966
26773
  }
25967
- async function setAnnotationStatus(cmd, io, id, annotationId, status) {
26774
+ async function setAnnotationStatus(cmd, io, id2, annotationId, status) {
25968
26775
  const ctx = resolveContext(cmd, io);
25969
26776
  await requireApiKey(ctx);
25970
- const updated = await ctx.client.updateAnnotation(id, annotationId, { status });
26777
+ const updated = await ctx.client.updateAnnotation(id2, annotationId, { status });
25971
26778
  if (ctx.json) return printJson2(io, updated);
25972
26779
  io.out.write(`Annotation ${updated.id} ${status === "resolved" ? "resolved" : "reopened"}.
25973
26780
  `);
@@ -25997,7 +26804,7 @@ function parseSetPair(pair) {
25997
26804
  return [key, raw];
25998
26805
  }
25999
26806
  }
26000
- var collect2 = (value, all) => [...all, value];
26807
+ var collect3 = (value, all) => [...all, value];
26001
26808
  function registerDeckCommands(program2, io) {
26002
26809
  program2.command("list").description("List presentations (newest first, cursor-paginated)").option("--cursor <cursor>", "resume from a previous nextCursor").option("--limit <n>", "page size (1-100)", (v) => parseInt(v, 10)).option("--all", "follow nextCursor until every page is fetched", false).option("--project <id>", "only the decks in this project").action(
26003
26810
  async (opts, cmd) => {
@@ -26037,10 +26844,10 @@ function registerDeckCommands(program2, io) {
26037
26844
  }
26038
26845
  }
26039
26846
  );
26040
- program2.command("get <id>").description("Show one presentation (metadata + latest version)").action(async (id, _opts, cmd) => {
26847
+ program2.command("get <id>").description("Show one presentation (metadata + latest version)").action(async (id2, _opts, cmd) => {
26041
26848
  const ctx = resolveContext(cmd, io);
26042
26849
  await requireApiKey(ctx);
26043
- const deck = await ctx.client.presentation(id);
26850
+ const deck = await ctx.client.presentation(id2);
26044
26851
  if (ctx.json) return printJson2(io, deck);
26045
26852
  const metaKeys = Object.keys(deck.metadata);
26046
26853
  const references = provenanceOf(deck.metadata);
@@ -26065,9 +26872,9 @@ function registerDeckCommands(program2, io) {
26065
26872
  program2.command("meta <id>").description("Show or edit a deck's metadata object (the seam for building your own dashboard)").option(
26066
26873
  "--set <key=value>",
26067
26874
  "set one key (repeatable; values parse as JSON when valid, else string)",
26068
- collect2,
26875
+ collect3,
26069
26876
  []
26070
- ).option("--unset <key>", "remove one key (repeatable)", collect2, []).option("--replace <object>", "replace the WHOLE metadata object with this JSON").action(async (id, opts, cmd) => {
26877
+ ).option("--unset <key>", "remove one key (repeatable)", collect3, []).option("--replace <object>", "replace the WHOLE metadata object with this JSON").action(async (id2, opts, cmd) => {
26071
26878
  const ctx = resolveContext(cmd, io);
26072
26879
  await requireApiKey(ctx);
26073
26880
  const editing = opts.set.length > 0 || opts.unset.length > 0 || opts.replace !== void 0;
@@ -26075,7 +26882,7 @@ function registerDeckCommands(program2, io) {
26075
26882
  throw new CliUsageError("--replace cannot be combined with --set/--unset");
26076
26883
  }
26077
26884
  if (!editing) {
26078
- const deck = await ctx.client.presentation(id);
26885
+ const deck = await ctx.client.presentation(id2);
26079
26886
  if (ctx.json) return printJson2(io, deck.metadata);
26080
26887
  io.out.write(`${JSON.stringify(deck.metadata, null, 2)}
26081
26888
  `);
@@ -26094,7 +26901,7 @@ function registerDeckCommands(program2, io) {
26094
26901
  }
26095
26902
  metadata = parsed;
26096
26903
  } else {
26097
- const deck = await ctx.client.presentation(id);
26904
+ const deck = await ctx.client.presentation(id2);
26098
26905
  metadata = { ...deck.metadata };
26099
26906
  for (const pair of opts.set) {
26100
26907
  const [key, value] = parseSetPair(pair);
@@ -26102,7 +26909,7 @@ function registerDeckCommands(program2, io) {
26102
26909
  }
26103
26910
  for (const key of opts.unset) delete metadata[key];
26104
26911
  }
26105
- const updated = await ctx.client.updatePresentation(id, { metadata });
26912
+ const updated = await ctx.client.updatePresentation(id2, { metadata });
26106
26913
  if (ctx.json) return printJson2(io, updated.metadata);
26107
26914
  io.out.write(
26108
26915
  `Updated metadata of "${updated.title}" (${Object.keys(updated.metadata).length} key(s)):
@@ -26110,18 +26917,18 @@ ${JSON.stringify(updated.metadata, null, 2)}
26110
26917
  `
26111
26918
  );
26112
26919
  });
26113
- program2.command("versions <id>").description("List a deck's version history (newest first, cursor-paginated)").option("--cursor <cursor>", "resume from a previous nextCursor").option("--limit <n>", "page size (1-100)", (v) => parseInt(v, 10)).option("--all", "follow nextCursor until every page is fetched", false).action(async (id, opts, cmd) => {
26920
+ program2.command("versions <id>").description("List a deck's version history (newest first, cursor-paginated)").option("--cursor <cursor>", "resume from a previous nextCursor").option("--limit <n>", "page size (1-100)", (v) => parseInt(v, 10)).option("--all", "follow nextCursor until every page is fetched", false).action(async (id2, opts, cmd) => {
26114
26921
  const ctx = resolveContext(cmd, io);
26115
26922
  await requireApiKey(ctx);
26116
26923
  const params = {};
26117
26924
  if (opts.cursor) params.cursor = opts.cursor;
26118
26925
  if (opts.limit !== void 0) params.limit = opts.limit;
26119
- const first = await ctx.client.presentationVersions(id, params);
26926
+ const first = await ctx.client.presentationVersions(id2, params);
26120
26927
  const rows = [...first.versions];
26121
26928
  if (opts.all) {
26122
26929
  let cursor = first.nextCursor;
26123
26930
  while (cursor) {
26124
- const page = await ctx.client.presentationVersions(id, { ...params, cursor });
26931
+ const page = await ctx.client.presentationVersions(id2, { ...params, cursor });
26125
26932
  rows.push(...page.versions);
26126
26933
  cursor = page.nextCursor;
26127
26934
  }
@@ -26148,10 +26955,10 @@ ${JSON.stringify(updated.metadata, null, 2)}
26148
26955
  `);
26149
26956
  }
26150
26957
  });
26151
- program2.command("delete <id>").description("Delete a presentation (soft delete; versions and share links stop resolving)").action(async (id, _opts, cmd) => {
26958
+ program2.command("delete <id>").description("Delete a presentation (soft delete; versions and share links stop resolving)").action(async (id2, _opts, cmd) => {
26152
26959
  const ctx = resolveContext(cmd, io);
26153
26960
  await requireApiKey(ctx);
26154
- const deck = await ctx.client.deletePresentation(id);
26961
+ const deck = await ctx.client.deletePresentation(id2);
26155
26962
  if (ctx.json) return printJson2(io, deck);
26156
26963
  io.out.write(`Deleted "${deck.title}" (${deck.id}).
26157
26964
  `);
@@ -26649,7 +27456,7 @@ function registerSharingCommands(program2, io) {
26649
27456
  "--placement <label>",
26650
27457
  "placement label baked into the embed snippets (per-view analytics dimension; slug of [A-Za-z0-9._-], max 64)"
26651
27458
  ).action(
26652
- async (id, opts, cmd) => {
27459
+ async (id2, opts, cmd) => {
26653
27460
  const ctx = resolveContext(cmd, io);
26654
27461
  await requireApiKey(ctx);
26655
27462
  if (opts.placement !== void 0 && !EMBED_PLACEMENT_RE.test(opts.placement)) {
@@ -26657,7 +27464,7 @@ function registerSharingCommands(program2, io) {
26657
27464
  }
26658
27465
  const password = await resolveSharePassword(io, opts);
26659
27466
  const created = await ctx.client.createShareToken(
26660
- id,
27467
+ id2,
26661
27468
  shareOptionsOf({ ...opts, ...password !== void 0 ? { password } : {} })
26662
27469
  );
26663
27470
  const embed = buildEmbedSnippets({
@@ -26687,11 +27494,11 @@ Password-protected links do not render inside embeds; docs: sharing/embedding.
26687
27494
  }
26688
27495
  }
26689
27496
  );
26690
- program2.command("unshare <id>").description("Revoke one share token (--token) or ALL active tokens of the deck").option("--token <tokenId>", "revoke only this token").action(async (id, opts, cmd) => {
27497
+ program2.command("unshare <id>").description("Revoke one share token (--token) or ALL active tokens of the deck").option("--token <tokenId>", "revoke only this token").action(async (id2, opts, cmd) => {
26691
27498
  const ctx = resolveContext(cmd, io);
26692
27499
  await requireApiKey(ctx);
26693
27500
  if (opts.token) {
26694
- const revoked2 = await ctx.client.revokeShareToken(id, opts.token);
27501
+ const revoked2 = await ctx.client.revokeShareToken(id2, opts.token);
26695
27502
  if (ctx.json) return printJson2(io, revoked2);
26696
27503
  io.out.write(`Revoked share token ${revoked2.id} ("${revoked2.name}").
26697
27504
  `);
@@ -26700,10 +27507,10 @@ Password-protected links do not render inside embeds; docs: sharing/embedding.
26700
27507
  const revoked = [];
26701
27508
  let cursor = null;
26702
27509
  do {
26703
- const page = await ctx.client.shareTokens(id, cursor ? { cursor } : {});
27510
+ const page = await ctx.client.shareTokens(id2, cursor ? { cursor } : {});
26704
27511
  for (const token of page.shareTokens) {
26705
27512
  if (!token.revokedAt) {
26706
- await ctx.client.revokeShareToken(id, token.id);
27513
+ await ctx.client.revokeShareToken(id2, token.id);
26707
27514
  revoked.push(token.id);
26708
27515
  }
26709
27516
  }
@@ -26723,17 +27530,17 @@ Password-protected links do not render inside embeds; docs: sharing/embedding.
26723
27530
  `annotation badge slot (${BADGE_POSITIONS}); remembered as the deck default`,
26724
27531
  parseBadgePosition
26725
27532
  ).option("--expires <datetime>", "ISO expiry").option("--password <password>", `viewer password (tell recipients separately; or ${SHARE_PASSWORD_ENV})`).option("--password-stdin", "read the viewer password from stdin (keeps it out of argv)", false).option("--message <text>", "personal note included in the email").action(
26726
- async (id, opts, cmd) => {
27533
+ async (id2, opts, cmd) => {
26727
27534
  const ctx = resolveContext(cmd, io);
26728
27535
  await requireApiKey(ctx);
26729
27536
  const password = await resolveSharePassword(io, opts);
26730
27537
  const results = [];
26731
27538
  for (const email3 of opts.to) {
26732
27539
  const created = await ctx.client.createShareToken(
26733
- id,
27540
+ id2,
26734
27541
  shareOptionsOf({ ...opts, name: email3, ...password !== void 0 ? { password } : {} })
26735
27542
  );
26736
- const sent = await ctx.client.sendShareToken(id, created.shareToken.id, {
27543
+ const sent = await ctx.client.sendShareToken(id2, created.shareToken.id, {
26737
27544
  email: email3,
26738
27545
  ...opts.message ? { message: opts.message } : {}
26739
27546
  });
@@ -26746,14 +27553,14 @@ Password-protected links do not render inside embeds; docs: sharing/embedding.
26746
27553
  }
26747
27554
  );
26748
27555
  program2.command("pin <id> <tokenId>").description("Pin a share token to a version, or set it back to following the latest").option("--to-version <n>", "freeze the recipient on this version", (v) => parseInt(v, 10)).option("--latest", "follow the latest version again", false).action(
26749
- async (id, tokenId, opts, cmd) => {
27556
+ async (id2, tokenId, opts, cmd) => {
26750
27557
  const ctx = resolveContext(cmd, io);
26751
27558
  await requireApiKey(ctx);
26752
27559
  if (opts.latest === (opts.toVersion !== void 0)) {
26753
27560
  throw new CliUsageError("Pass exactly one of --to-version <n> or --latest.");
26754
27561
  }
26755
27562
  const patch = opts.toVersion !== void 0 ? { versionMode: "pinned", pinnedVersion: opts.toVersion } : { versionMode: "latest" };
26756
- const updated = await ctx.client.updateShareToken(id, tokenId, patch);
27563
+ const updated = await ctx.client.updateShareToken(id2, tokenId, patch);
26757
27564
  if (ctx.json) return printJson2(io, updated);
26758
27565
  io.out.write(
26759
27566
  updated.versionMode === "pinned" ? `Token ${updated.id} pinned to v${updated.pinnedVersion}.
@@ -26762,18 +27569,18 @@ Password-protected links do not render inside embeds; docs: sharing/embedding.
26762
27569
  );
26763
27570
  }
26764
27571
  );
26765
- program2.command("tokens <id>").description("List a deck's share tokens with access stats (newest first, cursor-paginated)").option("--cursor <cursor>", "resume from a previous nextCursor").option("--limit <n>", "page size (1-100)", (v) => parseInt(v, 10)).option("--all", "follow nextCursor until every page is fetched", false).action(async (id, opts, cmd) => {
27572
+ program2.command("tokens <id>").description("List a deck's share tokens with access stats (newest first, cursor-paginated)").option("--cursor <cursor>", "resume from a previous nextCursor").option("--limit <n>", "page size (1-100)", (v) => parseInt(v, 10)).option("--all", "follow nextCursor until every page is fetched", false).action(async (id2, opts, cmd) => {
26766
27573
  const ctx = resolveContext(cmd, io);
26767
27574
  await requireApiKey(ctx);
26768
27575
  const params = {};
26769
27576
  if (opts.cursor) params.cursor = opts.cursor;
26770
27577
  if (opts.limit !== void 0) params.limit = opts.limit;
26771
- const first = await ctx.client.shareTokens(id, params);
27578
+ const first = await ctx.client.shareTokens(id2, params);
26772
27579
  const rows = [...first.shareTokens];
26773
27580
  if (opts.all) {
26774
27581
  let cursor = first.nextCursor;
26775
27582
  while (cursor) {
26776
- const page = await ctx.client.shareTokens(id, { ...params, cursor });
27583
+ const page = await ctx.client.shareTokens(id2, { ...params, cursor });
26777
27584
  rows.push(...page.shareTokens);
26778
27585
  cursor = page.nextCursor;
26779
27586
  }
@@ -26823,14 +27630,14 @@ Password-protected links do not render inside embeds; docs: sharing/embedding.
26823
27630
  program2.command("views <id> [tokenId]").description(
26824
27631
  "Per-view stats of a share link: when it was opened, the referring site, the ?p= placement label, and the browser family (no IPs, no full URLs \u2014 never stored). Omit tokenId to see which links exist."
26825
27632
  ).option("--cursor <cursor>", "resume from a previous nextCursor").option("--limit <n>", "page size (1-100)", (v) => parseInt(v, 10)).option("--all", "follow nextCursor until every page is fetched", false).action(
26826
- async (id, tokenId, opts, cmd) => {
27633
+ async (id2, tokenId, opts, cmd) => {
26827
27634
  const ctx = resolveContext(cmd, io);
26828
27635
  await requireApiKey(ctx);
26829
27636
  if (!tokenId) {
26830
27637
  const tokens = [];
26831
27638
  let cursor = opts.cursor ?? null;
26832
27639
  do {
26833
- const page = await ctx.client.shareTokens(id, cursor ? { cursor } : {});
27640
+ const page = await ctx.client.shareTokens(id2, cursor ? { cursor } : {});
26834
27641
  tokens.push(...page.shareTokens);
26835
27642
  cursor = page.nextCursor;
26836
27643
  } while (cursor);
@@ -26849,19 +27656,19 @@ Password-protected links do not render inside embeds; docs: sharing/embedding.
26849
27656
  ])
26850
27657
  )
26851
27658
  );
26852
- io.out.write(`Pick one: slideless views ${id} <tokenId>
27659
+ io.out.write(`Pick one: slideless views ${id2} <tokenId>
26853
27660
  `);
26854
27661
  return;
26855
27662
  }
26856
27663
  const params = {};
26857
27664
  if (opts.cursor) params.cursor = opts.cursor;
26858
27665
  if (opts.limit !== void 0) params.limit = opts.limit;
26859
- const first = await ctx.client.shareTokenViews(id, tokenId, params);
27666
+ const first = await ctx.client.shareTokenViews(id2, tokenId, params);
26860
27667
  const rows = [...first.views];
26861
27668
  if (opts.all) {
26862
27669
  let cursor = first.nextCursor;
26863
27670
  while (cursor) {
26864
- const page = await ctx.client.shareTokenViews(id, tokenId, { ...params, cursor });
27671
+ const page = await ctx.client.shareTokenViews(id2, tokenId, { ...params, cursor });
26865
27672
  rows.push(...page.views);
26866
27673
  cursor = page.nextCursor;
26867
27674
  }
@@ -26892,7 +27699,7 @@ Password-protected links do not render inside embeds; docs: sharing/embedding.
26892
27699
  program2.command("responses <id>").description(
26893
27700
  "A deck's embedded-form responses: what viewers submitted through share links and embeds, newest first. With no filters, prints the per-form summary (form, link, source, placement, count, last activity), then the most recent rows. Payload cells are the respondent's raw input."
26894
27701
  ).option("--form <name>", "only this form (the data-slideless-form name)").option("--link <tokenId>", "only responses that came through this share token").option("--source <source>", "only direct-link or embedded submissions (link | embed)").option("--placement <label>", "only responses whose serving document carried this ?p= label").option("--since <datetime>", "only responses created at or after this ISO instant").option("--csv", "output the listed rows as CSV (one column per payload field)", false).option("--cursor <cursor>", "resume from a previous nextCursor").option("--limit <n>", "page size (1-100)", (v) => parseInt(v, 10)).option("--all", "follow nextCursor until every page is fetched", false).action(
26895
- async (id, opts, cmd) => {
27702
+ async (id2, opts, cmd) => {
26896
27703
  const ctx = resolveContext(cmd, io);
26897
27704
  await requireApiKey(ctx);
26898
27705
  if (ctx.json && opts.csv) {
@@ -26918,12 +27725,12 @@ Password-protected links do not render inside embeds; docs: sharing/embedding.
26918
27725
  }
26919
27726
  const filtered = Boolean(opts.form || opts.link || opts.source || opts.placement || opts.since);
26920
27727
  const fetchRows = async () => {
26921
- const first = await ctx.client.formResponses(id, params);
27728
+ const first = await ctx.client.formResponses(id2, params);
26922
27729
  const rows2 = [...first.responses];
26923
27730
  if (opts.all) {
26924
27731
  let cursor = first.nextCursor;
26925
27732
  while (cursor) {
26926
- const page = await ctx.client.formResponses(id, { ...params, cursor });
27733
+ const page = await ctx.client.formResponses(id2, { ...params, cursor });
26927
27734
  rows2.push(...page.responses);
26928
27735
  cursor = page.nextCursor;
26929
27736
  }
@@ -26949,7 +27756,7 @@ Password-protected links do not render inside embeds; docs: sharing/embedding.
26949
27756
  `);
26950
27757
  return;
26951
27758
  }
26952
- const summary = await ctx.client.formResponsesSummary(id);
27759
+ const summary = await ctx.client.formResponsesSummary(id2);
26953
27760
  if (summary.total === 0 && !ctx.json) {
26954
27761
  io.out.write(
26955
27762
  'No form responses yet. Forms are <form data-slideless-form="name"> elements in the deck HTML.\n'
@@ -26980,17 +27787,17 @@ Password-protected links do not render inside embeds; docs: sharing/embedding.
26980
27787
  }
26981
27788
  io.out.write(
26982
27789
  `
26983
- Slice: slideless responses ${id} --form <name> [--link <tokenId>] [--source link|embed] [--placement <label>] [--since <ISO>]; export with --csv
27790
+ Slice: slideless responses ${id2} --form <name> [--link <tokenId>] [--source link|embed] [--placement <label>] [--since <ISO>]; export with --csv
26984
27791
  `
26985
27792
  );
26986
27793
  }
26987
27794
  );
26988
27795
  program2.command("response <id> <responseId>").description(
26989
27796
  "One form response with its edit history (PRDCT-2329): the current answer, then every kept revision newest first, with the link and the moment each was written through."
26990
- ).action(async (id, responseId, _opts, cmd) => {
27797
+ ).action(async (id2, responseId, _opts, cmd) => {
26991
27798
  const ctx = resolveContext(cmd, io);
26992
27799
  await requireApiKey(ctx);
26993
- const detail = await ctx.client.formResponse(id, responseId);
27800
+ const detail = await ctx.client.formResponse(id2, responseId);
26994
27801
  if (ctx.json) return printJson2(io, detail);
26995
27802
  const r = detail.response;
26996
27803
  io.out.write(
@@ -27005,7 +27812,7 @@ Slice: slideless responses ${id} --form <name> [--link <tokenId>] [--source link
27005
27812
  Files (${files.length}):
27006
27813
  `);
27007
27814
  io.out.write(table(files.map((f) => [` ${f.field}`, f.name, fmtBytes(f.sizeBytes), f.id])));
27008
- io.out.write(` Download them: slideless response-files ${id} ${r.id}
27815
+ io.out.write(` Download them: slideless response-files ${id2} ${r.id}
27009
27816
  `);
27010
27817
  }
27011
27818
  io.out.write(
@@ -27031,17 +27838,17 @@ History (${detail.versions.length} revision${detail.versions.length === 1 ? "" :
27031
27838
  });
27032
27839
  program2.command("uploads <id> <tokenId>").description(
27033
27840
  "Show or switch file uploads on one EXISTING share link (PRDCT-2403): whether its respondents may upload files into the deck's form file fields. A new link has them on; a link minted before file fields existed has them off until its owner turns them on here."
27034
- ).option("--on", "let respondents on this link upload files into form file fields", false).option("--off", "refuse file uploads through this link (the rest of the form still submits)", false).action(async (id, tokenId, opts, cmd) => {
27841
+ ).option("--on", "let respondents on this link upload files into form file fields", false).option("--off", "refuse file uploads through this link (the rest of the form still submits)", false).action(async (id2, tokenId, opts, cmd) => {
27035
27842
  const ctx = resolveContext(cmd, io);
27036
27843
  await requireApiKey(ctx);
27037
27844
  if (opts.on && opts.off) throw new CliUsageError("Pass either --on or --off, not both.");
27038
27845
  let token;
27039
27846
  if (opts.on || opts.off) {
27040
- token = await ctx.client.updateShareToken(id, tokenId, { canUploadFiles: opts.on });
27847
+ token = await ctx.client.updateShareToken(id2, tokenId, { canUploadFiles: opts.on });
27041
27848
  } else {
27042
27849
  let cursor = null;
27043
27850
  do {
27044
- const page = await ctx.client.shareTokens(id, { limit: 100, ...cursor ? { cursor } : {} });
27851
+ const page = await ctx.client.shareTokens(id2, { limit: 100, ...cursor ? { cursor } : {} });
27045
27852
  token = page.shareTokens.find((t) => t.id === tokenId);
27046
27853
  cursor = token ? null : page.nextCursor;
27047
27854
  } while (cursor);
@@ -27063,17 +27870,17 @@ History (${detail.versions.length} revision${detail.versions.length === 1 ? "" :
27063
27870
  });
27064
27871
  program2.command("pdf <id> <tokenId>").description(
27065
27872
  "Show or switch the PDF export on one EXISTING share link: whether its recipient sees an Export PDF action in the viewer's bar, printed by their browser. A new link has it on; a link minted before the switch existed has it off until its owner turns it on here."
27066
- ).option("--on", "let the recipient export the deck to PDF from the viewer", false).option("--off", "remove the Export PDF action from this link", false).action(async (id, tokenId, opts, cmd) => {
27873
+ ).option("--on", "let the recipient export the deck to PDF from the viewer", false).option("--off", "remove the Export PDF action from this link", false).action(async (id2, tokenId, opts, cmd) => {
27067
27874
  const ctx = resolveContext(cmd, io);
27068
27875
  await requireApiKey(ctx);
27069
27876
  if (opts.on && opts.off) throw new CliUsageError("Pass either --on or --off, not both.");
27070
27877
  let token;
27071
27878
  if (opts.on || opts.off) {
27072
- token = await ctx.client.updateShareToken(id, tokenId, { canExportPdf: opts.on });
27879
+ token = await ctx.client.updateShareToken(id2, tokenId, { canExportPdf: opts.on });
27073
27880
  } else {
27074
27881
  let cursor = null;
27075
27882
  do {
27076
- const page = await ctx.client.shareTokens(id, { limit: 100, ...cursor ? { cursor } : {} });
27883
+ const page = await ctx.client.shareTokens(id2, { limit: 100, ...cursor ? { cursor } : {} });
27077
27884
  token = page.shareTokens.find((t) => t.id === tokenId);
27078
27885
  cursor = token ? null : page.nextCursor;
27079
27886
  } while (cursor);
@@ -27090,11 +27897,11 @@ History (${detail.versions.length} revision${detail.versions.length === 1 ? "" :
27090
27897
  });
27091
27898
  program2.command("notify <id>").description(
27092
27899
  "Show or switch the owner mails for form responses on one deck (PRDCT-2330): a mail when a response arrives, another when one is edited; on by default"
27093
- ).option("--on", "mail the deck owner on new and edited responses", false).option("--off", "stop mailing the deck owner about responses (forms stay on)", false).action(async (id, opts, cmd) => {
27900
+ ).option("--on", "mail the deck owner on new and edited responses", false).option("--off", "stop mailing the deck owner about responses (forms stay on)", false).action(async (id2, opts, cmd) => {
27094
27901
  const ctx = resolveContext(cmd, io);
27095
27902
  await requireApiKey(ctx);
27096
27903
  if (opts.on && opts.off) throw new CliUsageError("Pass either --on or --off, not both.");
27097
- const deck = opts.on || opts.off ? await ctx.client.updatePresentation(id, { notifyOnResponse: opts.on }) : await ctx.client.presentation(id);
27904
+ const deck = opts.on || opts.off ? await ctx.client.updatePresentation(id2, { notifyOnResponse: opts.on }) : await ctx.client.presentation(id2);
27098
27905
  if (ctx.json) return printJson2(io, { notifyOnResponse: deck.notifyOnResponse });
27099
27906
  io.out.write(
27100
27907
  deck.notifyOnResponse ? `Response mails are ON for "${deck.title}": the owner is mailed on a new response and on an edit.
@@ -27102,10 +27909,10 @@ History (${detail.versions.length} revision${detail.versions.length === 1 ? "" :
27102
27909
  `
27103
27910
  );
27104
27911
  });
27105
- program2.command("invite <id>").description("Invite a dev collaborator to one deck (prints the claim link)").requiredOption("--email <email>", "invitee email").action(async (id, opts, cmd) => {
27912
+ program2.command("invite <id>").description("Invite a dev collaborator to one deck (prints the claim link)").requiredOption("--email <email>", "invitee email").action(async (id2, opts, cmd) => {
27106
27913
  const ctx = resolveContext(cmd, io);
27107
27914
  await requireApiKey(ctx);
27108
- const invited = await ctx.client.inviteCollaborator(id, { email: opts.email });
27915
+ const invited = await ctx.client.inviteCollaborator(id2, { email: opts.email });
27109
27916
  if (ctx.json) return printJson2(io, invited);
27110
27917
  io.out.write(
27111
27918
  `Invited ${opts.email} as a dev collaborator (grant ${invited.collaborator.id}).
@@ -27114,10 +27921,10 @@ History (${detail.versions.length} revision${detail.versions.length === 1 ? "" :
27114
27921
  `
27115
27922
  );
27116
27923
  });
27117
- program2.command("uninvite <id> <collaboratorId>").description("Revoke a collaborator grant (pending or active)").action(async (id, collaboratorId, _opts, cmd) => {
27924
+ program2.command("uninvite <id> <collaboratorId>").description("Revoke a collaborator grant (pending or active)").action(async (id2, collaboratorId, _opts, cmd) => {
27118
27925
  const ctx = resolveContext(cmd, io);
27119
27926
  await requireApiKey(ctx);
27120
- const revoked = await ctx.client.removeCollaborator(id, collaboratorId);
27927
+ const revoked = await ctx.client.removeCollaborator(id2, collaboratorId);
27121
27928
  if (ctx.json) return printJson2(io, revoked);
27122
27929
  io.out.write(`Revoked collaborator grant ${revoked.id} (${revoked.email}).
27123
27930
  `);
@@ -27288,7 +28095,7 @@ function registerResponseFilesCommand(program2, io) {
27288
28095
  "--zip [path]",
27289
28096
  "stream the server's zip to disk instead (default: the server's file name, in the current directory)"
27290
28097
  ).action(
27291
- async (id, responseId, opts, cmd) => {
28098
+ async (id2, responseId, opts, cmd) => {
27292
28099
  const ctx = resolveContext(cmd, io);
27293
28100
  await requireApiKey(ctx);
27294
28101
  if (opts.out !== void 0 && opts.zip !== void 0) {
@@ -27316,15 +28123,15 @@ function registerResponseFilesCommand(program2, io) {
27316
28123
  filters.since = new Date(opts.since).toISOString();
27317
28124
  }
27318
28125
  if (opts.zip !== void 0) {
27319
- return zipMode(ctx, io, id, responseId, filters, opts.zip);
28126
+ return zipMode(ctx, io, id2, responseId, filters, opts.zip);
27320
28127
  }
27321
28128
  const responses = [];
27322
28129
  if (responseId !== void 0) {
27323
- responses.push((await ctx.client.formResponse(id, responseId)).response);
28130
+ responses.push((await ctx.client.formResponse(id2, responseId)).response);
27324
28131
  } else {
27325
28132
  let cursor = null;
27326
28133
  do {
27327
- const page = await ctx.client.formResponses(id, {
28134
+ const page = await ctx.client.formResponses(id2, {
27328
28135
  ...filters,
27329
28136
  limit: 100,
27330
28137
  ...cursor ? { cursor } : {}
@@ -27335,7 +28142,7 @@ function registerResponseFilesCommand(program2, io) {
27335
28142
  }
27336
28143
  const planned = plan(responses, responseId !== void 0);
27337
28144
  const root = resolve8(
27338
- opts.out ?? (responseId !== void 0 ? `response-files-${safePathSegment(responseId.slice(0, 8))}` : `form-files-${safePathSegment(id.slice(0, 8))}`)
28145
+ opts.out ?? (responseId !== void 0 ? `response-files-${safePathSegment(responseId.slice(0, 8))}` : `form-files-${safePathSegment(id2.slice(0, 8))}`)
27339
28146
  );
27340
28147
  if (planned.length === 0) {
27341
28148
  if (ctx.json) return printJson2(io, { mode: "folder", path: null, files: [], totalBytes: 0 });
@@ -27346,7 +28153,7 @@ function registerResponseFilesCommand(program2, io) {
27346
28153
  }
27347
28154
  const written = [];
27348
28155
  for (const p of planned) {
27349
- const path = await downloadInto(ctx, id, root, p);
28156
+ const path = await downloadInto(ctx, id2, root, p);
27350
28157
  written.push({
27351
28158
  responseId: p.response.id,
27352
28159
  formName: p.response.formName,
@@ -27378,10 +28185,10 @@ function registerResponseFilesCommand(program2, io) {
27378
28185
  }
27379
28186
  );
27380
28187
  }
27381
- async function zipMode(ctx, io, id, responseId, filters, zip) {
28188
+ async function zipMode(ctx, io, id2, responseId, filters, zip) {
27382
28189
  let res;
27383
28190
  try {
27384
- res = responseId !== void 0 ? await ctx.client.downloadFormResponseFilesZip(id, responseId) : await ctx.client.downloadFormResponsesFilesZip(id, filters);
28191
+ res = responseId !== void 0 ? await ctx.client.downloadFormResponseFilesZip(id2, responseId) : await ctx.client.downloadFormResponsesFilesZip(id2, filters);
27385
28192
  } catch (e) {
27386
28193
  if (e instanceof PlatformApiError && e.code === "no_files") {
27387
28194
  if (ctx.json) return printJson2(io, { mode: "zip", path: null, sizeBytes: 0 });
@@ -27407,7 +28214,7 @@ async function zipMode(ctx, io, id, responseId, filters, zip) {
27407
28214
  sizeBytes = (await stat6(path)).size;
27408
28215
  } else {
27409
28216
  const served = contentDispositionName(res.headers.get("content-disposition"));
27410
- const fallback = `form-files-${safePathSegment((responseId ?? id).slice(0, 8))}.zip`;
28217
+ const fallback = `form-files-${safePathSegment((responseId ?? id2).slice(0, 8))}.zip`;
27411
28218
  let name = served ? safePathSegment(served) : fallback;
27412
28219
  if (name === "_") name = fallback;
27413
28220
  if (!/\.zip$/i.test(name)) name = `${name}.zip`;
@@ -27419,7 +28226,7 @@ async function zipMode(ctx, io, id, responseId, filters, zip) {
27419
28226
  }
27420
28227
 
27421
28228
  // src/index.ts
27422
- var VERSION = "0.13.7";
28229
+ var VERSION = "0.13.9";
27423
28230
  function registerTool(program2, io) {
27424
28231
  registerDeckCommands(program2, io);
27425
28232
  registerContentCommands(program2, io);