@tinycloud/cli 1.2.2 → 1.2.3-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -319,13 +319,14 @@ var init_warnings = __esm({
319
319
 
320
320
  // src/output/formatter.ts
321
321
  import ora from "ora";
322
+ import { CLI_NAME } from "@tinycloud/operations/cli-name";
322
323
  function outputJson(data) {
323
324
  process.stdout.write(JSON.stringify(data, null, 2) + "\n");
324
325
  }
325
326
  function warningLine(warnings) {
326
327
  const which = warnings.map((warning) => `${warning.grantCid ?? "unidentified"}: ${warning.reason}`).join(", ");
327
328
  const subject = warnings.length === 1 ? "A stored grant was" : `${warnings.length} stored grants were`;
328
- return `${subject} not used (${which}). Approve access again when a command needs it; remove the old grant with tc auth grants remove <cid>.`;
329
+ return `${subject} not used (${which}). Approve access again when a command needs it; remove the old grant with ${CLI_NAME} auth grants remove <cid>.`;
329
330
  }
330
331
  function outputError(code3, message, hint, details = {}) {
331
332
  const { meta, warnings = [], setup, recovery, progress } = details;
@@ -432,14 +433,6 @@ function formatBytes(bytes) {
432
433
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
433
434
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
434
435
  }
435
- function formatTimeAgo(date) {
436
- const d = typeof date === "string" ? new Date(date) : date;
437
- const seconds = Math.floor((Date.now() - d.getTime()) / 1e3);
438
- if (seconds < 60) return "just now";
439
- if (seconds < 3600) return `${Math.floor(seconds / 60)}m ago`;
440
- if (seconds < 86400) return `${Math.floor(seconds / 3600)}h ago`;
441
- return `${Math.floor(seconds / 86400)}d ago`;
442
- }
443
436
  var WARNING_CODE, WARNING_REASON, DELEGATION_CID, JSON_REQUESTED;
444
437
  var init_formatter = __esm({
445
438
  "src/output/formatter.ts"() {
@@ -538,6 +531,7 @@ import { readFileSync, readdirSync } from "fs";
538
531
  import { join as join2 } from "path";
539
532
  import { ProfileDeletedError, ProfileLockTimeoutError } from "@tinycloud/operations/state";
540
533
  import { isSafeRecovery } from "@tinycloud/operations/recovery";
534
+ import { CLI_NAME as CLI_NAME2 } from "@tinycloud/operations/cli-name";
541
535
  import {
542
536
  buildSecretRequestUrl,
543
537
  isSafeRequestAccessRecovery,
@@ -616,7 +610,7 @@ function missingPrivateKeyError() {
616
610
  "AUTH_REQUIRED",
617
611
  `Profile "${profileName2}" cannot restore its session because its private key material is missing.`,
618
612
  ExitCode.AUTH_REQUIRED,
619
- { hint: `Sign in again with: tc --profile ${profileName2} auth login --method openkey` }
613
+ { hint: `Sign in again with: ${CLI_NAME2} --profile ${profileName2} auth login --method openkey` }
620
614
  );
621
615
  }
622
616
  function storageFullError(error, progress) {
@@ -707,7 +701,7 @@ function buildAuthHint(error) {
707
701
  if (!spec) return void 0;
708
702
  return [
709
703
  "The active session is missing a TinyCloud capability.",
710
- `Request it with: tc auth request --cap '${spec.replaceAll("'", "'\\''")}'`,
704
+ `Request it with: ${CLI_NAME2} auth request --cap '${spec.replaceAll("'", "'\\''")}'`,
711
705
  "Then retry the original command."
712
706
  ].join("\n");
713
707
  }
@@ -750,12 +744,12 @@ function buildNetworkHint() {
750
744
  const lines = [];
751
745
  lines.push(activeHost ? `Active profile "${activeName}" \u2192 ${activeHost}` : `Active profile "${activeName}"`);
752
746
  if (others.length === 0) {
753
- lines.push(`No other profiles configured. Run \`tc profile create <name>\` or \`tc init\`.`);
747
+ lines.push(`No other profiles configured. Run \`${CLI_NAME2} profile create <name>\` or \`${CLI_NAME2} init\`.`);
754
748
  } else {
755
749
  lines.push(`Switch to a reachable profile:`);
756
750
  const longest = Math.max(...others.map((p) => p.name.length));
757
751
  for (const { name, host } of others) {
758
- lines.push(` tc profile switch ${name.padEnd(longest)} # ${host}`);
752
+ lines.push(` ${CLI_NAME2} profile switch ${name.padEnd(longest)} # ${host}`);
759
753
  }
760
754
  }
761
755
  lines.push(`Or override per-command with --host or TC_HOST.`);
@@ -815,6 +809,7 @@ var init_types = __esm({
815
809
  });
816
810
 
817
811
  // src/lib/space.ts
812
+ import { CLI_NAME as CLI_NAME3 } from "@tinycloud/operations/cli-name";
818
813
  function canonicalizeAddress(address) {
819
814
  const trimmed = address.trim();
820
815
  return trimmed.startsWith("0x") ? `0x${trimmed.slice(2).toLowerCase()}` : trimmed.toLowerCase();
@@ -862,7 +857,7 @@ function resolveAddress(profile, session) {
862
857
  }
863
858
  throw new CLIError(
864
859
  "ADDRESS_UNKNOWN",
865
- `Cannot determine Ethereum address for profile "${profile.name}". Run \`tc auth login\` to refresh the session.`,
860
+ `Cannot determine Ethereum address for profile "${profile.name}". Run \`${CLI_NAME3} auth login\` to refresh the session.`,
866
861
  ExitCode.AUTH_REQUIRED
867
862
  );
868
863
  }
@@ -14783,6 +14778,7 @@ var init_permissions = __esm({
14783
14778
 
14784
14779
  // src/auth/session-expired.ts
14785
14780
  import { signInRecovery } from "@tinycloud/operations/recovery";
14781
+ import { CLI_NAME as CLI_NAME4 } from "@tinycloud/operations/cli-name";
14786
14782
  function signInAgainHint(profileName2, posture) {
14787
14783
  const delegate = posture === "delegate-session";
14788
14784
  const { command } = signInRecovery(
@@ -14790,7 +14786,7 @@ function signInAgainHint(profileName2, posture) {
14790
14786
  delegate ? "delegate-session" : posture === "local-owner-key" ? "local-owner-key" : "owner-openkey"
14791
14787
  );
14792
14788
  if (command === void 0) {
14793
- return delegate ? `Have the owner approve a new scoped login for profile ${JSON.stringify(profileName2)} with tc auth login --method openkey --paste --manifest <manifest.json>.` : `Sign in again to profile ${JSON.stringify(profileName2)} with tc auth login.`;
14789
+ return delegate ? `Have the owner approve a new scoped login for profile ${JSON.stringify(profileName2)} with ${CLI_NAME4} auth login --method openkey --paste --manifest <manifest.json>.` : `Sign in again to profile ${JSON.stringify(profileName2)} with ${CLI_NAME4} auth login.`;
14794
14790
  }
14795
14791
  return delegate ? `Have the owner approve a new scoped login: ${command}. Pass the owner's code on stdin, newline-terminated.` : `Sign in again with: ${command}`;
14796
14792
  }
@@ -14835,6 +14831,7 @@ var init_delegation_expiry = __esm({
14835
14831
  });
14836
14832
 
14837
14833
  // src/lib/replication-log.ts
14834
+ import { CLI_NAME as CLI_NAME5 } from "@tinycloud/operations/cli-name";
14838
14835
  import { appendFileSync, chmodSync, mkdirSync, renameSync, statSync, writeFileSync } from "fs";
14839
14836
  import { dirname as dirname2, join as join4 } from "path";
14840
14837
  function appendReplicationEvent(root, event) {
@@ -14897,7 +14894,7 @@ function createReplicationEventSink(profileRoot, options) {
14897
14894
  }
14898
14895
  if (event.type === "replication.read" && (event.pendingState === "in_flight" || event.pendingState === "ambiguous") && !options.quiet && !pinnedNotices.has(event.key)) {
14899
14896
  pinnedNotices.add(event.key);
14900
- process.stderr.write(`[replication] ${event.key} reads from the network: an earlier write's outcome is unknown (${event.pendingState}${event.code ? `, ${event.code}` : ""}). Review: tc replica report
14897
+ process.stderr.write(`[replication] ${event.key} reads from the network: an earlier write's outcome is unknown (${event.pendingState}${event.code ? `, ${event.code}` : ""}). Review: ${CLI_NAME5} replica report
14901
14898
  `);
14902
14899
  }
14903
14900
  };
@@ -17737,6 +17734,7 @@ var init_dist3 = __esm({
17737
17734
 
17738
17735
  // src/lib/replication-config.ts
17739
17736
  import { join as join5 } from "path";
17737
+ import { CLI_NAME as CLI_NAME6 } from "@tinycloud/operations/cli-name";
17740
17738
  import { profilePath, withProfileLock as withProfileLock2 } from "@tinycloud/operations/state";
17741
17739
  import { sqliteReplicaStorage } from "@tinycloud/node-sdk";
17742
17740
  function createCliReplicationConfig(profile, settings, output2, enabled) {
@@ -17751,7 +17749,7 @@ function createCliReplicationConfig(profile, settings, output2, enabled) {
17751
17749
  "INVALID_REPLICATION_PREFIX",
17752
17750
  error instanceof Error ? error.message : String(error),
17753
17751
  ExitCode.USAGE_ERROR,
17754
- { hint: `Replace the saved replication prefix with \`tc auth login --replication-prefix ${replacement}\`; purging a replica alone does not change this profile setting.` }
17752
+ { hint: `Replace the saved replication prefix with \`${CLI_NAME6} auth login --replication-prefix ${replacement}\`; purging a replica alone does not change this profile setting.` }
17755
17753
  );
17756
17754
  }
17757
17755
  }
@@ -17797,6 +17795,7 @@ __export(sdk_exports, {
17797
17795
  storedSessionVerifiesLocally: () => storedSessionVerifiesLocally
17798
17796
  });
17799
17797
  import { TinyCloudNode, signedCompactUcanExpiry } from "@tinycloud/node-sdk";
17798
+ import { CLI_NAME as CLI_NAME7 } from "@tinycloud/operations/cli-name";
17800
17799
  import { ownerSessionLacksProof } from "@tinycloud/operations/profile";
17801
17800
  function jwkHasPrivateParameter(jwk) {
17802
17801
  if (!jwk || typeof jwk !== "object") return false;
@@ -17819,7 +17818,7 @@ function signerJwkForProfile(profileName2, sessionJwk, key) {
17819
17818
  `Profile "${profileName2}" cannot restore its session because its private key material is missing.`,
17820
17819
  ExitCode.AUTH_REQUIRED,
17821
17820
  {
17822
- hint: `Sign in again with: tc --profile ${profileName2} auth login --method openkey`
17821
+ hint: `Sign in again with: ${CLI_NAME7} --profile ${profileName2} auth login --method openkey`
17823
17822
  }
17824
17823
  );
17825
17824
  }
@@ -17906,7 +17905,7 @@ async function createSDKInstance(ctx, options) {
17906
17905
  if (!key && !effectivePrivateKey && !(profile?.authMethod === "openkey" && session !== null)) {
17907
17906
  throw new CLIError(
17908
17907
  "AUTH_REQUIRED",
17909
- `No key found for profile "${ctx.profile}". Run \`tc --profile ${ctx.profile} auth rotate\` to create a new key and sign in.`,
17908
+ `No key found for profile "${ctx.profile}". Run \`${CLI_NAME7} --profile ${ctx.profile} auth rotate\` to create a new key and sign in.`,
17910
17909
  ExitCode.AUTH_REQUIRED
17911
17910
  );
17912
17911
  }
@@ -18025,7 +18024,7 @@ async function bootstrapDelegatedSession(ctx, delegation) {
18025
18024
  return restoreBeforeBootstrap(ctx.profile, written.previousProfile);
18026
18025
  }, { timeoutMs: PROFILE_COMMIT_LOCK_TIMEOUT_MS }).catch((error) => (
18027
18026
  // The lock or a read failed: the import's error stays the one reported.
18028
- `Rolling back the provisional session of profile "${ctx.profile}" could not run (${failureName(error)}); check \`tc --profile ${ctx.profile} context\`.`
18027
+ `Rolling back the provisional session of profile "${ctx.profile}" could not run (${failureName(error)}); check \`${CLI_NAME7} --profile ${ctx.profile} context\`.`
18029
18028
  ));
18030
18029
  throw annotate(reported, note);
18031
18030
  };
@@ -18055,7 +18054,7 @@ async function restoreBeforeBootstrap(profileName2, previousProfile) {
18055
18054
  });
18056
18055
  }
18057
18056
  if (failures.length === 0) return void 0;
18058
- return `Rolling back the provisional session of profile "${profileName2}" failed too (${failures.join("; ")}); check \`tc --profile ${profileName2} context\`.`;
18057
+ return `Rolling back the provisional session of profile "${profileName2}" failed too (${failures.join("; ")}); check \`${CLI_NAME7} --profile ${profileName2} context\`.`;
18059
18058
  }
18060
18059
  function failureName(error) {
18061
18060
  if (error instanceof SyntaxError) return "a profile file is not valid JSON";
@@ -18079,7 +18078,7 @@ async function ensureAuthenticated(ctx, options) {
18079
18078
  if (!session) {
18080
18079
  throw new CLIError(
18081
18080
  "AUTH_REQUIRED",
18082
- `Not authenticated. Run \`tc auth login\` or \`tc init\` first.`,
18081
+ `Not authenticated. Run \`${CLI_NAME7} auth login\` or \`${CLI_NAME7} init\` first.`,
18083
18082
  ExitCode.AUTH_REQUIRED
18084
18083
  );
18085
18084
  }
@@ -18116,6 +18115,7 @@ __export(host_exports, {
18116
18115
  spaceNameFromUri: () => spaceNameFromUri,
18117
18116
  unhostedSpaceError: () => unhostedSpaceError
18118
18117
  });
18118
+ import { CLI_NAME as CLI_NAME8 } from "@tinycloud/operations/cli-name";
18119
18119
  import {
18120
18120
  discoverLocalTinyCloudNode
18121
18121
  } from "@tinycloud/sdk-core";
@@ -18209,13 +18209,13 @@ async function unhostedSpaceError(error, spaceUri, profileName2) {
18209
18209
  const owner = await isRootAuthority(spaceUri, profileName2);
18210
18210
  const hint = owner ? [
18211
18211
  "You are the owner. Host it once:",
18212
- ` tc space host ${spaceName}`,
18212
+ ` ${CLI_NAME8} space host ${spaceName}`,
18213
18213
  "Then retry."
18214
18214
  ].join("\n") : [
18215
18215
  "You are a delegate and CANNOT host this space \u2014 only its owner can.",
18216
18216
  "Emit a host request:",
18217
- ` tc space host-request ${spaceName} --emit ./host-request.json`,
18218
- "Send it to the owner; they run `tc space host` and confirm. Then retry."
18217
+ ` ${CLI_NAME8} space host-request ${spaceName} --emit ./host-request.json`,
18218
+ `Send it to the owner; they run \`${CLI_NAME8} space host\` and confirm. Then retry.`
18219
18219
  ].join("\n");
18220
18220
  const message = owner ? `Space '${spaceName}' (${spaceUri}) is not hosted.` : `Space '${spaceName}' (owner ${ownerDidFromSpaceUri(spaceUri) ?? spaceUri}) is not hosted.`;
18221
18221
  return new CLIError("SPACE_NOT_HOSTED", message, ExitCode.ERROR, { hint });
@@ -18240,6 +18240,7 @@ var init_host = __esm({
18240
18240
 
18241
18241
  // src/config/profiles.ts
18242
18242
  import { chmod as chmod2, lstat, readdir as readdir2, rm as rm2, rmdir } from "fs/promises";
18243
+ import { CLI_NAME as CLI_NAME9 } from "@tinycloud/operations/cli-name";
18243
18244
  import { join as join6 } from "path";
18244
18245
  import {
18245
18246
  profilePath as profilePath2,
@@ -18325,7 +18326,7 @@ var init_profiles = __esm({
18325
18326
  if (!profile) {
18326
18327
  throw new CLIError(
18327
18328
  "PROFILE_NOT_FOUND",
18328
- `Profile "${name}" does not exist. Create it with \`tc init --name ${name}\`.`
18329
+ `Profile "${name}" does not exist. Create it with \`${CLI_NAME9} init --name ${name}\`.`
18329
18330
  );
18330
18331
  }
18331
18332
  return profile;
@@ -18383,7 +18384,7 @@ var init_profiles = __esm({
18383
18384
  if (config.defaultProfile === name) {
18384
18385
  throw new CLIError(
18385
18386
  "PROFILE_DELETE_DEFAULT",
18386
- `Cannot delete the default profile "${name}". Change the default first with \`tc profile default <other>\`.`
18387
+ `Cannot delete the default profile "${name}". Change the default first with \`${CLI_NAME9} profile default <other>\`.`
18387
18388
  );
18388
18389
  }
18389
18390
  const kind = await lstat(profileDir).then((stats) => stats.isSymbolicLink() ? "link" : "present", (error) => {
@@ -18840,6 +18841,7 @@ function formatSpace(space) {
18840
18841
  }
18841
18842
 
18842
18843
  // src/commands/auth.ts
18844
+ import { CLI_NAME as CLI_NAME14 } from "@tinycloud/operations/cli-name";
18843
18845
  import { get as httpGet } from "http";
18844
18846
  import { get as httpsGet } from "https";
18845
18847
  import { spawn } from "child_process";
@@ -20310,7 +20312,8 @@ async function startAuthFlow(did, options = {}) {
20310
20312
  }
20311
20313
  try {
20312
20314
  return await callbackFlow(did, options);
20313
- } catch {
20315
+ } catch (error) {
20316
+ if (error instanceof CLIError && error.code === "CANCELLED") throw error;
20314
20317
  if (process.stdin.isTTY) {
20315
20318
  console.error("Could not open browser. Falling back to manual paste mode.");
20316
20319
  return pasteFlow(did, options);
@@ -20555,6 +20558,7 @@ If the browser can't connect back, enter the short code or paste the full delega
20555
20558
  resolving = false;
20556
20559
  }
20557
20560
  });
20561
+ rl.on("SIGINT", () => settle({ error: loginCancelled() }));
20558
20562
  }
20559
20563
  });
20560
20564
  timeout = setTimeout(() => {
@@ -20594,10 +20598,19 @@ Open this URL in a browser to authenticate:
20594
20598
  }
20595
20599
  ));
20596
20600
  });
20601
+ rl.on("SIGINT", () => {
20602
+ if (answered) return;
20603
+ answered = true;
20604
+ rl.close();
20605
+ reject(loginCancelled());
20606
+ });
20597
20607
  rl.setPrompt("Enter short code or paste full delegation code: ");
20598
20608
  rl.prompt();
20599
20609
  });
20600
20610
  }
20611
+ function loginCancelled() {
20612
+ return new CLIError("CANCELLED", "Interrupted: tc auth login stopped before approval. No session was saved.", ExitCode.CANCELLED);
20613
+ }
20601
20614
 
20602
20615
  // src/auth/device-auth.ts
20603
20616
  init_constants();
@@ -21023,13 +21036,14 @@ init_constants();
21023
21036
  init_profiles();
21024
21037
  init_errors();
21025
21038
  init_space();
21039
+ import { CLI_NAME as CLI_NAME10 } from "@tinycloud/operations/cli-name";
21026
21040
  import { isLocalOwnerProfile as isLocalOwnerProfile3, ownerSessionLacksProof as ownerSessionLacksProof3 } from "@tinycloud/operations/profile";
21027
21041
  import { ProfileLockTimeoutError as ProfileLockTimeoutError2 } from "@tinycloud/operations/state";
21028
21042
  function assertNotLocalOwner(profileName2, profile, flow) {
21029
21043
  if (profile === null || !isLocalOwnerProfile3(profile)) return;
21030
21044
  throw new CLIError(
21031
21045
  "LOCAL_OWNER_PROFILE",
21032
- `Profile "${profileName2}" holds a local owner key. ${flow} would turn it into an OpenKey profile while keeping that key. Use a separate profile: \`tc init --name publisher --key-only\`, then \`tc --profile publisher auth login --device --manifest ...\`.`,
21046
+ `Profile "${profileName2}" holds a local owner key. ${flow} would turn it into an OpenKey profile while keeping that key. Use a separate profile: \`${CLI_NAME10} init --name publisher --key-only\`, then \`${CLI_NAME10} --profile publisher auth login --device --manifest ...\`.`,
21033
21047
  ExitCode.USAGE_ERROR
21034
21048
  );
21035
21049
  }
@@ -21064,7 +21078,7 @@ function assertSessionReplaceable(profileName2, snapshot, ownerDid, scope, newEx
21064
21078
  if (problem !== void 0) {
21065
21079
  throw new CLIError(
21066
21080
  "PROFILE_STATE_INCONSISTENT",
21067
- `Profile "${profileName2}" is inconsistent (${problem}), possibly from an interrupted write. Nothing was saved. Check \`tc --profile ${profileName2} context\`, then pass --replace-session to replace this state, or use a new profile.`,
21081
+ `Profile "${profileName2}" is inconsistent (${problem}), possibly from an interrupted write. Nothing was saved. Check \`${CLI_NAME10} --profile ${profileName2} context\`, then pass --replace-session to replace this state, or use a new profile.`,
21068
21082
  ExitCode.ERROR
21069
21083
  );
21070
21084
  }
@@ -21080,7 +21094,7 @@ function assertSessionReplaceable(profileName2, snapshot, ownerDid, scope, newEx
21080
21094
  const space = typeof session.spaceId === "string" ? session.spaceId : "an unknown space";
21081
21095
  throw new CLIError(
21082
21096
  "SESSION_IN_USE",
21083
- `Profile "${profileName2}" has a live session for ${space}${expiresAt ? ` until ${expiresAt}` : ""} that this login would ${keepsScope ? "shorten" : "narrow or replace"}, dropping that authority. Nothing was saved. Keep the user's existing profiles: use a new profile name (\`tc init --name publisher --key-only\`, then \`tc --profile publisher auth login --device --manifest ...\`), or pass --replace-session to replace this session.`,
21097
+ `Profile "${profileName2}" has a live session for ${space}${expiresAt ? ` until ${expiresAt}` : ""} that this login would ${keepsScope ? "shorten" : "narrow or replace"}, dropping that authority. Nothing was saved. Keep the user's existing profiles: use a new profile name (\`${CLI_NAME10} init --name publisher --key-only\`, then \`${CLI_NAME10} --profile publisher auth login --device --manifest ...\`), or pass --replace-session to replace this session.`,
21084
21098
  ExitCode.USAGE_ERROR
21085
21099
  );
21086
21100
  }
@@ -21109,7 +21123,7 @@ async function commitLogin(profileName2, snapshot, commit) {
21109
21123
  if (canonicalJson(current.profile) !== canonicalJson(snapshot.profile) || canonicalJson(current.key) !== canonicalJson(snapshot.key) || canonicalJson(current.session) !== canonicalJson(snapshot.session)) {
21110
21124
  throw new CLIError(
21111
21125
  "PROFILE_CHANGED_DURING_LOGIN",
21112
- `Profile "${profileName2}" changed while this login was in progress (another login, key rotation or logout). Nothing was saved; check \`tc --profile ${profileName2} context\` and run the login again if it is still needed.`,
21126
+ `Profile "${profileName2}" changed while this login was in progress (another login, key rotation or logout). Nothing was saved; check \`${CLI_NAME10} --profile ${profileName2} context\` and run the login again if it is still needed.`,
21113
21127
  ExitCode.ERROR
21114
21128
  );
21115
21129
  }
@@ -21126,7 +21140,7 @@ async function commitLogin(profileName2, snapshot, commit) {
21126
21140
  if (failures.length === 0) throw error;
21127
21141
  throw new CLIError(
21128
21142
  "PROFILE_STATE_INCONSISTENT",
21129
- `Saving the login for profile "${profileName2}" failed (${errorMessage(error)}), and restoring its previous state failed too (${failures.map(errorMessage).join("; ")}). The profile's key, session and settings may not match. Check \`tc --profile ${profileName2} context\`, then run the login again with --replace-session, or use a new profile.`,
21143
+ `Saving the login for profile "${profileName2}" failed (${errorMessage(error)}), and restoring its previous state failed too (${failures.map(errorMessage).join("; ")}). The profile's key, session and settings may not match. Check \`${CLI_NAME10} --profile ${profileName2} context\`, then run the login again with --replace-session, or use a new profile.`,
21130
21144
  ExitCode.ERROR
21131
21145
  );
21132
21146
  }
@@ -21142,6 +21156,7 @@ async function commitLogin(profileName2, snapshot, commit) {
21142
21156
 
21143
21157
  // src/auth/owner-key.ts
21144
21158
  init_theme();
21159
+ import { CLI_NAME as CLI_NAME11 } from "@tinycloud/operations/cli-name";
21145
21160
  function openKeyPrimaryFlag(delegation) {
21146
21161
  return typeof delegation.primary === "boolean" ? delegation.primary : void 0;
21147
21162
  }
@@ -21152,7 +21167,7 @@ function withOwnerKeyPrimary(profile, primary) {
21152
21167
  function nonPrimaryKeyWarning(ownerDid) {
21153
21168
  const address = ownerDid.split(":")[4] ?? ownerDid;
21154
21169
  return `${theme.warn("Warning:")} you signed in with OpenKey key ${address} (${ownerDid}), which is not your account's primary OpenKey key. This key is a separate owner with its own spaces and data, so this profile does not see the data stored under your primary key.
21155
- To use your primary key, log in again and choose the primary key in OpenKey, for example into a new profile: tc init --name <profile>
21170
+ To use your primary key, log in again and choose the primary key in OpenKey, for example into a new profile: ${CLI_NAME11} init --name <profile>
21156
21171
  `;
21157
21172
  }
21158
21173
  function warnIfNotPrimaryKey(ownerDid, primary) {
@@ -21161,7 +21176,7 @@ function warnIfNotPrimaryKey(ownerDid, primary) {
21161
21176
  }
21162
21177
  function announceFirstOwner(profileName2, expectedOwner, ownerDid) {
21163
21178
  if (expectedOwner !== void 0 || ownerDid === void 0) return;
21164
- process.stderr.write(`Profile "${profileName2}" now belongs to ${ownerDid}. If that isn't your OpenKey account, stop using this profile and create a new one with tc init.
21179
+ process.stderr.write(`Profile "${profileName2}" now belongs to ${ownerDid}. If that isn't your OpenKey account, stop using this profile and create a new one with ${CLI_NAME11} init.
21165
21180
  `);
21166
21181
  }
21167
21182
  function ownerLoginPermissions(owner) {
@@ -21585,6 +21600,7 @@ init_types();
21585
21600
  init_constants();
21586
21601
  init_permissions();
21587
21602
  init_sdk();
21603
+ import { CLI_NAME as CLI_NAME13 } from "@tinycloud/operations/cli-name";
21588
21604
  import { TinyCloudNode as TinyCloudNode2 } from "@tinycloud/node-sdk";
21589
21605
  import { DelegationRequestBindingSchema, PermissionEntrySchema } from "@tinycloud/operations/artifacts";
21590
21606
  import {
@@ -21599,6 +21615,7 @@ import {
21599
21615
  // src/lib/revoke-delegation.ts
21600
21616
  init_constants();
21601
21617
  init_errors();
21618
+ import { CLI_NAME as CLI_NAME12 } from "@tinycloud/operations/cli-name";
21602
21619
  import { parseSignedCompactUcanAttenuation } from "@tinycloud/sdk-core";
21603
21620
  import { inspectStoredDelegation, withoutBearer } from "@tinycloud/operations/delegation-binding";
21604
21621
  init_permissions();
@@ -21784,7 +21801,7 @@ async function revokeDelegationOnNode(params) {
21784
21801
  "REVOKE_UNAUTHORIZED",
21785
21802
  "The node rejected this revocation: Unauthorized Revoker.",
21786
21803
  ExitCode.PERMISSION_DENIED,
21787
- { status: 403, hint: `Use a different profile belonging to the delegation's grantor, its recipient, or the owner of a space it covers; the rejected profile was "${ctx.profile}" (DID ${profileDid}). Retry with \`tc --profile <profile-name> delegation revoke ${cid}\`.` }
21804
+ { status: 403, hint: `Use a different profile belonging to the delegation's grantor, its recipient, or the owner of a space it covers; the rejected profile was "${ctx.profile}" (DID ${profileDid}). Retry with \`${CLI_NAME12} --profile <profile-name> delegation revoke ${cid}\`.` }
21788
21805
  );
21789
21806
  }
21790
21807
  throw cliErrorFromService(result.error);
@@ -21867,7 +21884,7 @@ function renderList(result) {
21867
21884
  }
21868
21885
  process.stdout.write(`Profile: ${result.profile}
21869
21886
  `);
21870
- process.stdout.write(`Session CID: ${result.session?.cid ?? "unavailable"}` + (result.session?.cid ? ` (revoke with tc delegation revoke ${result.session.cid})
21887
+ process.stdout.write(`Session CID: ${result.session?.cid ?? "unavailable"}` + (result.session?.cid ? ` (revoke with ${CLI_NAME13} delegation revoke ${result.session.cid})
21871
21888
  ` : "\n"));
21872
21889
  process.stdout.write(`Local verification: ${result.localVerification}; node validation and revocation are not checked.
21873
21890
  `);
@@ -21963,7 +21980,7 @@ function registerAuthGrantsCommand(auth, options = {}) {
21963
21980
  ExitCode.ERROR,
21964
21981
  {
21965
21982
  causeCode: cause.code,
21966
- hint: `Do not use --revoke again. After fixing local profile storage, run: tc --profile ${ctx.profile} auth grants remove ${cid}`
21983
+ hint: `Do not use --revoke again. After fixing local profile storage, run: ${CLI_NAME13} --profile ${ctx.profile} auth grants remove ${cid}`
21967
21984
  }
21968
21985
  );
21969
21986
  }
@@ -22124,7 +22141,7 @@ async function promptAuthMethod() {
22124
22141
  function registerAuthCommand(program, options) {
22125
22142
  const auth = program.command("auth").description("Authentication management");
22126
22143
  registerAuthGrantsCommand(auth, { openKeyAcquisition: options?.openKeyAcquisition });
22127
- auth.command("login").description("Authenticate with TinyCloud").option("--device", "Approve on another device (e.g. a phone) through OpenKey device authorization; requires a KV-scoped --manifest (SQL and secret decrypt need browser or --paste login)").option("--paste", "Use manual paste mode instead of browser callback").option("--no-popup", "Print the OpenKey URL without opening a browser").option("--method <method>", "Authentication method: local or openkey").option("--manifest <fileOrBase64>", `Request only this manifest's permissions (one space, plus raw encryption network entries such as a secrets decrypt grant); ${SHARE_PUBLISHING_MANIFEST_REF} covers \`tc share publish\``).option("--expiry <duration>", "OpenKey session lifetime, e.g. 1h or 7d (device login: at most 30d, default 30d)").option("--owner <did>", "Sign in as this owner (did:pkh:eip155:CHAIN:ADDRESS): OpenKey preselects that key, e.g. one that is not the account's primary key, and an approval by any other identity is refused. With --manifest, also names the secrets owner for a manifest's `secrets` on a profile with no recorded owner").option("--replace-session", "Scoped or device login: replace this profile's live session even though the new scope would narrow, change or shorten it (prefer a new profile)").option("--replication-prefix <prefix>", "Add replication get+sync authority for a folder prefix ending in /, or root (repeatable)", (prefix, values = []) => [...values, prefix]).option("--replication-allow-secrets", "Allow replication of secret material (network-wide decrypt warning)").action(async (options2, cmd) => {
22144
+ auth.command("login").description("Authenticate with TinyCloud").option("--device", "Approve on another device (e.g. a phone) through OpenKey device authorization; requires a KV-scoped --manifest (SQL and secret decrypt need browser or --paste login)").option("--paste", "Use manual paste mode instead of browser callback").option("--no-popup", "Print the OpenKey URL without opening a browser").option("--method <method>", "Authentication method: local or openkey").option("--manifest <fileOrBase64>", `Request only this manifest's permissions (one space, plus raw encryption network entries such as a secrets decrypt grant); ${SHARE_PUBLISHING_MANIFEST_REF} covers \`${CLI_NAME14} share publish\``).option("--expiry <duration>", "OpenKey session lifetime, e.g. 1h or 7d (device login: at most 30d, default 30d)").option("--owner <did>", "Sign in as this owner (did:pkh:eip155:CHAIN:ADDRESS): OpenKey preselects that key, e.g. one that is not the account's primary key, and an approval by any other identity is refused. With --manifest, also names the secrets owner for a manifest's `secrets` on a profile with no recorded owner").option("--replace-session", "Scoped or device login: replace this profile's live session even though the new scope would narrow, change or shorten it (prefer a new profile)").option("--replication-prefix <prefix>", "Add replication get+sync authority for a folder prefix ending in /, or root (repeatable)", (prefix, values = []) => [...values, prefix]).option("--replication-allow-secrets", "Allow replication of secret material (network-wide decrypt warning)").action(async (options2, cmd) => {
22128
22145
  try {
22129
22146
  if (options2.device && options2.paste) {
22130
22147
  throw new CLIError("INVALID_ARGUMENT", "--device and --paste are mutually exclusive.", ExitCode.USAGE_ERROR);
@@ -22232,7 +22249,7 @@ function registerAuthCommand(program, options) {
22232
22249
  return handleError(error);
22233
22250
  }
22234
22251
  });
22235
- auth.command("logout").description("Clear the local session and remove local replicas. Logout is local; delegations and grants on the node stay valid until they expire. Use `tc delegation revoke <cid>` to end access now.").option("--keep-replicas", "Keep this profile's local replicas").action(async (options2, cmd) => {
22252
+ auth.command("logout").description(`Clear the local session and remove local replicas. Logout is local; delegations and grants on the node stay valid until they expire. Use \`${CLI_NAME14} delegation revoke <cid>\` to end access now.`).option("--keep-replicas", "Keep this profile's local replicas").action(async (options2, cmd) => {
22236
22253
  try {
22237
22254
  const globalOpts = cmd.optsWithGlobals();
22238
22255
  const ctx = await ProfileManager.resolveContext(globalOpts, { storedSession: "unused" });
@@ -22244,7 +22261,7 @@ function registerAuthCommand(program, options) {
22244
22261
  authenticated: false,
22245
22262
  replicasRemoved,
22246
22263
  replicasKept: options2.keepReplicas === true,
22247
- warning: "Logout is local; delegations and grants on the node stay valid until they expire. Use `tc delegation revoke <cid>` to end access now."
22264
+ warning: `Logout is local; delegations and grants on the node stay valid until they expire. Use \`${CLI_NAME14} delegation revoke <cid>\` to end access now.`
22248
22265
  });
22249
22266
  } catch (error) {
22250
22267
  return handleError(error);
@@ -22366,7 +22383,7 @@ ${signInAgainHint(ctx.profile, posture ?? void 0)}
22366
22383
  if (profile.authMethod === "openkey" || options2.device) {
22367
22384
  const key = await ProfileManager.getKey(ctx.profile);
22368
22385
  if (!key) {
22369
- throw new CLIError("NO_KEY", `No key found for profile "${ctx.profile}". Run \`tc --profile ${ctx.profile} auth rotate\` to create a new key and sign in.`, ExitCode.AUTH_REQUIRED);
22386
+ throw new CLIError("NO_KEY", `No key found for profile "${ctx.profile}". Run \`${CLI_NAME14} --profile ${ctx.profile} auth rotate\` to create a new key and sign in.`, ExitCode.AUTH_REQUIRED);
22370
22387
  }
22371
22388
  const openkeyHost = resolveOpenKeyHost(profile);
22372
22389
  const grants = [];
@@ -22380,7 +22397,7 @@ ${signInAgainHint(ctx.profile, posture ?? void 0)}
22380
22397
  const declined = [];
22381
22398
  for (const group of groupPermissionsBySpace(requested)) {
22382
22399
  const reason = permissionGrantReason(
22383
- "Grant requested TinyCloud permissions from `tc auth request --grant`.",
22400
+ `Grant requested TinyCloud permissions from \`${CLI_NAME14} auth request --grant\`.`,
22384
22401
  group
22385
22402
  );
22386
22403
  const request = grantRequestPermissions(group, profile.spaceId ?? profile.spaceName);
@@ -22489,7 +22506,7 @@ ${signInAgainHint(ctx.profile, posture ?? void 0)}
22489
22506
  kind: parsed.kind,
22490
22507
  requestId: parsed.requestId,
22491
22508
  requested: parsed.requested,
22492
- next: `tc auth retry ${parsed.requestId}`
22509
+ next: `${CLI_NAME14} auth retry ${parsed.requestId}`
22493
22510
  });
22494
22511
  return;
22495
22512
  }
@@ -23040,7 +23057,7 @@ async function ensureDelegationAuthority(params) {
23040
23057
  if (!key) {
23041
23058
  throw new CLIError(
23042
23059
  "NO_KEY",
23043
- `No key found for profile "${params.ctx.profile}". Run \`tc --profile ${params.ctx.profile} auth rotate\` to create a new key and sign in.`,
23060
+ `No key found for profile "${params.ctx.profile}". Run \`${CLI_NAME14} --profile ${params.ctx.profile} auth rotate\` to create a new key and sign in.`,
23044
23061
  ExitCode.AUTH_REQUIRED
23045
23062
  );
23046
23063
  }
@@ -23285,7 +23302,7 @@ async function rotateAuthKey(profileName2, host, options = {}) {
23285
23302
  if (!profile.privateKey) {
23286
23303
  throw new CLIError(
23287
23304
  "LOCAL_OWNER_KEY_REQUIRED",
23288
- `Profile "${profileName2}" does not have a local owner private key. Run \`tc auth login --method local\` first.`,
23305
+ `Profile "${profileName2}" does not have a local owner private key. Run \`${CLI_NAME14} auth login --method local\` first.`,
23289
23306
  ExitCode.AUTH_REQUIRED
23290
23307
  );
23291
23308
  }
@@ -23508,7 +23525,7 @@ async function refreshOpenKeySession(profileName2, host, options = {}) {
23508
23525
  if (!key) {
23509
23526
  throw new CLIError(
23510
23527
  "NO_KEY",
23511
- `No key found for profile "${profileName2}". Run \`tc --profile ${profileName2} auth rotate\` to create a new key and sign in.`,
23528
+ `No key found for profile "${profileName2}". Run \`${CLI_NAME14} --profile ${profileName2} auth rotate\` to create a new key and sign in.`,
23512
23529
  ExitCode.AUTH_REQUIRED
23513
23530
  );
23514
23531
  }
@@ -23589,6 +23606,7 @@ async function refreshOpenKeySession(profileName2, host, options = {}) {
23589
23606
  }
23590
23607
 
23591
23608
  // src/commands/completion.ts
23609
+ import { CLI_NAME as CLI_NAME15 } from "@tinycloud/operations/cli-name";
23592
23610
  function registerCompletionCommand(program) {
23593
23611
  const completion = program.command("completion").description("Generate shell completions");
23594
23612
  completion.command("bash").description("Output bash completions").action(() => {
@@ -23605,7 +23623,7 @@ function registerCompletionCommand(program) {
23605
23623
  });
23606
23624
  }
23607
23625
  function generateBashCompletion() {
23608
- return `# tc bash completion
23626
+ return `# ${CLI_NAME15} bash completion
23609
23627
  _tc_completions() {
23610
23628
  local cur prev commands subcommands
23611
23629
  COMPREPLY=()
@@ -23630,11 +23648,11 @@ _tc_completions() {
23630
23648
  COMPREPLY=( $(compgen -W "\${subcommands}" -- "\${cur}") )
23631
23649
  fi
23632
23650
  }
23633
- complete -F _tc_completions tc
23651
+ complete -F _tc_completions ${CLI_NAME15}
23634
23652
  `;
23635
23653
  }
23636
23654
  function generateZshCompletion() {
23637
- return `#compdef tc
23655
+ return `#compdef ${CLI_NAME15}
23638
23656
 
23639
23657
  _tc() {
23640
23658
  local -a commands
@@ -23685,49 +23703,50 @@ _tc
23685
23703
  `;
23686
23704
  }
23687
23705
  function generateFishCompletion() {
23688
- return `# tc fish completion
23706
+ return `# ${CLI_NAME15} fish completion
23689
23707
  set -l commands init auth kv space delegation share node profile completion
23690
23708
 
23691
23709
  # Disable file completion by default
23692
- complete -c tc -f
23710
+ complete -c ${CLI_NAME15} -f
23693
23711
 
23694
23712
  # Top-level commands
23695
- complete -c tc -n "not __fish_seen_subcommand_from $commands" -a init -d "Initialize a new TinyCloud profile"
23696
- complete -c tc -n "not __fish_seen_subcommand_from $commands" -a auth -d "Authentication management"
23697
- complete -c tc -n "not __fish_seen_subcommand_from $commands" -a kv -d "Key-value store operations"
23698
- complete -c tc -n "not __fish_seen_subcommand_from $commands" -a space -d "Space management"
23699
- complete -c tc -n "not __fish_seen_subcommand_from $commands" -a delegation -d "Manage delegations"
23700
- complete -c tc -n "not __fish_seen_subcommand_from $commands" -a share -d "Share data with others"
23701
- complete -c tc -n "not __fish_seen_subcommand_from $commands" -a node -d "Node health and info"
23702
- complete -c tc -n "not __fish_seen_subcommand_from $commands" -a profile -d "Profile management"
23703
- complete -c tc -n "not __fish_seen_subcommand_from $commands" -a completion -d "Generate shell completions"
23713
+ complete -c ${CLI_NAME15} -n "not __fish_seen_subcommand_from $commands" -a init -d "Initialize a new TinyCloud profile"
23714
+ complete -c ${CLI_NAME15} -n "not __fish_seen_subcommand_from $commands" -a auth -d "Authentication management"
23715
+ complete -c ${CLI_NAME15} -n "not __fish_seen_subcommand_from $commands" -a kv -d "Key-value store operations"
23716
+ complete -c ${CLI_NAME15} -n "not __fish_seen_subcommand_from $commands" -a space -d "Space management"
23717
+ complete -c ${CLI_NAME15} -n "not __fish_seen_subcommand_from $commands" -a delegation -d "Manage delegations"
23718
+ complete -c ${CLI_NAME15} -n "not __fish_seen_subcommand_from $commands" -a share -d "Share data with others"
23719
+ complete -c ${CLI_NAME15} -n "not __fish_seen_subcommand_from $commands" -a node -d "Node health and info"
23720
+ complete -c ${CLI_NAME15} -n "not __fish_seen_subcommand_from $commands" -a profile -d "Profile management"
23721
+ complete -c ${CLI_NAME15} -n "not __fish_seen_subcommand_from $commands" -a completion -d "Generate shell completions"
23704
23722
 
23705
23723
  # Subcommands
23706
- complete -c tc -n "__fish_seen_subcommand_from auth" -a "login logout rotate status whoami"
23707
- complete -c tc -n "__fish_seen_subcommand_from kv" -a "get put delete list head"
23708
- complete -c tc -n "__fish_seen_subcommand_from space" -a "list create info switch"
23709
- complete -c tc -n "__fish_seen_subcommand_from delegation" -a "create list info revoke"
23710
- complete -c tc -n "__fish_seen_subcommand_from share" -a "create receive list revoke"
23711
- complete -c tc -n "__fish_seen_subcommand_from node" -a "health version status"
23712
- complete -c tc -n "__fish_seen_subcommand_from profile" -a "list create show switch delete"
23713
- complete -c tc -n "__fish_seen_subcommand_from completion" -a "bash zsh fish"
23724
+ complete -c ${CLI_NAME15} -n "__fish_seen_subcommand_from auth" -a "login logout rotate status whoami"
23725
+ complete -c ${CLI_NAME15} -n "__fish_seen_subcommand_from kv" -a "get put delete list head"
23726
+ complete -c ${CLI_NAME15} -n "__fish_seen_subcommand_from space" -a "list create info switch"
23727
+ complete -c ${CLI_NAME15} -n "__fish_seen_subcommand_from delegation" -a "create list info revoke"
23728
+ complete -c ${CLI_NAME15} -n "__fish_seen_subcommand_from share" -a "create receive list revoke"
23729
+ complete -c ${CLI_NAME15} -n "__fish_seen_subcommand_from node" -a "health version status"
23730
+ complete -c ${CLI_NAME15} -n "__fish_seen_subcommand_from profile" -a "list create show switch delete"
23731
+ complete -c ${CLI_NAME15} -n "__fish_seen_subcommand_from completion" -a "bash zsh fish"
23714
23732
 
23715
23733
  # Global options
23716
- complete -c tc -l profile -s p -d "Profile to use"
23717
- complete -c tc -l host -s H -d "TinyCloud node URL"
23718
- complete -c tc -l verbose -s v -d "Enable verbose output"
23719
- complete -c tc -l no-cache -d "Disable caching"
23720
- complete -c tc -l quiet -s q -d "Suppress non-essential output"
23721
- complete -c tc -l replication -d "Enable read-through replication"
23722
- complete -c tc -l no-replication -d "Disable replication"
23723
- complete -c tc -l replication-debug -d "Write replication diagnostics to stderr"
23734
+ complete -c ${CLI_NAME15} -l profile -s p -d "Profile to use"
23735
+ complete -c ${CLI_NAME15} -l host -s H -d "TinyCloud node URL"
23736
+ complete -c ${CLI_NAME15} -l verbose -s v -d "Enable verbose output"
23737
+ complete -c ${CLI_NAME15} -l no-cache -d "Disable caching"
23738
+ complete -c ${CLI_NAME15} -l quiet -s q -d "Suppress non-essential output"
23739
+ complete -c ${CLI_NAME15} -l replication -d "Enable read-through replication"
23740
+ complete -c ${CLI_NAME15} -l no-replication -d "Disable replication"
23741
+ complete -c ${CLI_NAME15} -l replication-debug -d "Write replication diagnostics to stderr"
23724
23742
  `;
23725
23743
  }
23726
23744
 
23727
23745
  // src/commands/courier.ts
23728
- var TC_OPTIONS_BEFORE_COURIER = 'tc courier takes no tc options and does not use tc profiles; Courier keeps its own profile in $COURIER_HOME (default ~/.courier). Put flags after "courier", e.g. tc courier init --host <url>.';
23746
+ import { CLI_NAME as CLI_NAME16 } from "@tinycloud/operations/cli-name";
23747
+ var TC_OPTIONS_BEFORE_COURIER = `${CLI_NAME16} courier takes no ${CLI_NAME16} options and does not use ${CLI_NAME16} profiles; Courier keeps its own profile in $COURIER_HOME (default ~/.courier). Put flags after "courier", e.g. ${CLI_NAME16} courier init --host <url>.`;
23729
23748
  function registerCourierCommand(program) {
23730
- const courier = program.command("courier").description("Agent-to-agent threads over TinyCloud; run `tc courier --help` (beta)").argument("[args...]").allowUnknownOption().helpOption(false);
23749
+ const courier = program.command("courier").description(`Agent-to-agent threads over TinyCloud; run \`${CLI_NAME16} courier --help\` (beta)`).argument("[args...]").allowUnknownOption().helpOption(false);
23731
23750
  courier.action(() => courier.error(TC_OPTIONS_BEFORE_COURIER, { exitCode: 2, code: "tc.courier.options" }));
23732
23751
  }
23733
23752
 
@@ -23884,6 +23903,7 @@ init_constants();
23884
23903
  init_formatter();
23885
23904
  init_theme();
23886
23905
  init_errors();
23906
+ import { CLI_NAME as CLI_NAME17 } from "@tinycloud/operations/cli-name";
23887
23907
  init_session_expired();
23888
23908
  init_types();
23889
23909
  function registerDoctorCommand(program) {
@@ -23917,7 +23937,7 @@ function registerDoctorCommand(program) {
23917
23937
  const profile = await ProfileManager.getProfile(profileName2);
23918
23938
  keyDetail = profile.did ? `${profile.did.slice(0, 20)}...` : "key found";
23919
23939
  } else {
23920
- keyDetail = "no key \u2014 run tc init";
23940
+ keyDetail = `no key \u2014 run ${CLI_NAME17} init`;
23921
23941
  }
23922
23942
  } catch {
23923
23943
  keyDetail = "error reading key";
@@ -23939,7 +23959,7 @@ function registerDoctorCommand(program) {
23939
23959
  } else if (state2 === "unverified") {
23940
23960
  sessionDetail = `not usable (no signed OpenKey proof) \u2014 ${signInAgainHint(profileName2, resolveProfilePosture(profile))}`;
23941
23961
  } else {
23942
- sessionDetail = sessionOk ? "active" : "no session \u2014 run tc auth login";
23962
+ sessionDetail = sessionOk ? "active" : `no session \u2014 run ${CLI_NAME17} auth login`;
23943
23963
  }
23944
23964
  } catch {
23945
23965
  sessionDetail = "error reading session";
@@ -23967,7 +23987,7 @@ function registerDoctorCommand(program) {
23967
23987
  try {
23968
23988
  const profile = await ProfileManager.getProfile(profileName2);
23969
23989
  spaceOk = Boolean(profile.spaceId);
23970
- spaceDetail = spaceOk ? `${profile.spaceId.slice(0, 16)}...` : "no space \u2014 run tc space create";
23990
+ spaceDetail = spaceOk ? `${profile.spaceId.slice(0, 16)}...` : `no space \u2014 run ${CLI_NAME17} space create`;
23971
23991
  } catch {
23972
23992
  spaceDetail = "error checking space";
23973
23993
  }
@@ -24157,6 +24177,7 @@ ${rowCount} row${rowCount === 1 ? "" : "s"} returned`) + "\n");
24157
24177
  }
24158
24178
 
24159
24179
  // src/commands/enable.ts
24180
+ import { CLI_NAME as CLI_NAME18 } from "@tinycloud/operations/cli-name";
24160
24181
  init_constants();
24161
24182
  init_profiles();
24162
24183
  init_errors();
@@ -24164,7 +24185,7 @@ init_formatter();
24164
24185
  init_publishing_manifest();
24165
24186
  function registerEnableCommand(program) {
24166
24187
  const enable = program.command("enable").description("Enable a narrowly scoped TinyCloud service");
24167
- enable.command("share").description("Approve Share publishing scope through OpenKey device authorization (same as `tc auth login --device --manifest builtin:share-publishing`). Use a dedicated profile, e.g. `tc init --name publisher --key-only && tc --profile publisher enable share`; keep existing profiles for their apps.").option("--replace-session", "Replace this profile's live session even though the new scope would narrow, change or shorten it (prefer a new profile)").action(async (options, command) => {
24188
+ enable.command("share").description(`Approve Share publishing scope through OpenKey device authorization (same as \`${CLI_NAME18} auth login --device --manifest builtin:share-publishing\`). Use a dedicated profile, e.g. \`${CLI_NAME18} init --name publisher --key-only && ${CLI_NAME18} --profile publisher enable share\`; keep existing profiles for their apps.`).option("--replace-session", "Replace this profile's live session even though the new scope would narrow, change or shorten it (prefer a new profile)").action(async (options, command) => {
24168
24189
  try {
24169
24190
  const globalOptions = command.optsWithGlobals();
24170
24191
  const context = await ProfileManager.resolveContext(globalOptions, { storedSession: "unused" });
@@ -24200,6 +24221,7 @@ init_profiles();
24200
24221
  init_formatter();
24201
24222
  init_errors();
24202
24223
  init_constants();
24224
+ import { CLI_NAME as CLI_NAME19 } from "@tinycloud/operations/cli-name";
24203
24225
  function registerInitCommand(program) {
24204
24226
  program.command("init").description("Initialize a new TinyCloud profile").option("--name <profile>", "Profile name", "default").option("--key-only", "Only generate key, skip authentication").option("--host <url>", "TinyCloud node URL").option("--paste", "Use manual paste mode for authentication").option("--no-popup", "Print the OpenKey URL without opening a browser").option("--default-space <name>", "Default space used when --space is omitted (e.g. applications)").action(async (options, cmd) => {
24205
24227
  try {
@@ -24217,7 +24239,7 @@ function registerInitCommand(program) {
24217
24239
  if (await ProfileManager.profileExists(profileName2)) {
24218
24240
  throw new CLIError(
24219
24241
  "PROFILE_EXISTS",
24220
- `Profile "${profileName2}" already exists. Use \`tc profile delete ${profileName2}\` first or choose a different name.`,
24242
+ `Profile "${profileName2}" already exists. Use \`${CLI_NAME19} profile delete ${profileName2}\` first or choose a different name.`,
24221
24243
  ExitCode.ERROR
24222
24244
  );
24223
24245
  }
@@ -24459,37 +24481,64 @@ function registerKvCommand(program) {
24459
24481
  return handleError(error);
24460
24482
  }
24461
24483
  });
24462
- kv.command("list").description("List keys").option("--prefix <prefix>", "Filter by key prefix").option("--space <name|uri>", "Target a non-primary space (short name or full URI)").action(async (options, cmd) => {
24484
+ kv.command("list").description("List keys").option("--prefix <prefix>", "Filter by key prefix").option("--space <name|uri>", "Target a non-primary space (short name or full URI)").option("--limit <n>", "Keys per page, 1-1000 (the node's default otherwise)").option("--cursor <cursor>", "Continue from a previous page's nextCursor").option("--all", "Follow nextCursor until the listing is complete").action(async (options, cmd) => {
24463
24485
  try {
24464
24486
  if (options.prefix) assertAddressableKey(options.prefix);
24487
+ const limit = options.limit === void 0 ? void 0 : Number(options.limit);
24488
+ if (limit !== void 0 && (!Number.isInteger(limit) || limit < 1 || limit > 1e3)) {
24489
+ throw new CLIError("USAGE_ERROR", "--limit must be an integer from 1 through 1000", ExitCode.USAGE_ERROR);
24490
+ }
24465
24491
  const globalOpts = cmd.optsWithGlobals();
24466
24492
  const ctx = await ProfileManager.resolveContext(globalOpts);
24467
24493
  const node = await ensureAuthenticated(ctx);
24468
24494
  const { kv: kv2, spaceUri } = await kvHandle(node, options.space, ctx.profile);
24469
- const listOptions = options.prefix ? { prefix: options.prefix } : void 0;
24470
- const result = await withSpinner("Listing keys...", () => kv2.list(listOptions));
24471
- if (!result.ok) {
24472
- await throwKvError(result.error, spaceUri, ctx.profile);
24495
+ const keyList = [];
24496
+ let cursor = options.cursor;
24497
+ let truncated;
24498
+ const seenCursors = /* @__PURE__ */ new Set();
24499
+ for (; ; ) {
24500
+ const result = await withSpinner("Listing keys...", () => kv2.list({
24501
+ ...options.prefix ? { prefix: options.prefix } : {},
24502
+ ...limit === void 0 ? {} : { limit },
24503
+ ...cursor === void 0 ? {} : { cursor }
24504
+ }));
24505
+ if (!result.ok) {
24506
+ await throwKvError(result.error, spaceUri, ctx.profile);
24507
+ break;
24508
+ }
24509
+ for (const key of result.data.keys) keyList.push(key);
24510
+ truncated = result.data.truncated;
24511
+ cursor = truncated === true ? result.data.nextCursor : void 0;
24512
+ if (options.all && truncated === true && cursor === void 0) {
24513
+ throw new CLIError("KV_LIST_CURSOR_MISSING", "The node reported more keys but no cursor to continue from, so the listing can't be completed.", ExitCode.ERROR);
24514
+ }
24515
+ if (!options.all || cursor === void 0) break;
24516
+ if (seenCursors.has(cursor)) {
24517
+ throw new CLIError("KV_LIST_CURSOR_STALLED", "The node returned a list cursor it had already returned, so the listing can't be completed.", ExitCode.ERROR);
24518
+ }
24519
+ seenCursors.add(cursor);
24473
24520
  }
24474
- const rawData = result.data.data ?? result.data;
24475
- const keyList = Array.isArray(rawData) ? rawData : rawData?.keys ?? [];
24476
24521
  if (shouldOutputJson()) {
24477
24522
  outputJson({
24478
24523
  keys: keyList,
24479
24524
  count: keyList.length,
24480
- prefix: options.prefix ?? null
24525
+ prefix: options.prefix ?? null,
24526
+ // null when the node doesn't report truncation.
24527
+ truncated: truncated ?? null,
24528
+ nextCursor: cursor ?? null
24481
24529
  });
24482
24530
  } else {
24483
24531
  if (keyList.length === 0) {
24484
24532
  process.stdout.write(theme.muted("No keys found.") + "\n");
24485
24533
  } else {
24486
- const rows = keyList.map((e) => [
24487
- e.key || e,
24488
- e.contentLength ? formatBytes(e.contentLength) : "\u2014",
24489
- e.updatedAt ? formatTimeAgo(e.updatedAt) : "\u2014"
24490
- ]);
24534
+ const rows = keyList.map((key) => [key, "\u2014", "\u2014"]);
24491
24535
  process.stdout.write(formatTable(["Key", "Size", "Updated"], rows) + "\n");
24492
24536
  }
24537
+ if (cursor !== void 0) {
24538
+ process.stdout.write(theme.muted(`More keys follow. Run again with --cursor ${cursor}, or use --all.`) + "\n");
24539
+ } else if (truncated === true) {
24540
+ process.stdout.write(theme.muted("More keys follow, but the node gave no cursor to continue from.") + "\n");
24541
+ }
24493
24542
  }
24494
24543
  } catch (error) {
24495
24544
  return handleError(error);
@@ -24532,6 +24581,7 @@ init_errors();
24532
24581
  init_constants();
24533
24582
  init_theme();
24534
24583
  import { resolveManifestKnowledgeRoot as resolveManifestKnowledgeRoot2 } from "@tinycloud/sdk-core";
24584
+ import { CLI_NAME as CLI_NAME20 } from "@tinycloud/operations/cli-name";
24535
24585
  import { readFile as readFile8 } from "fs/promises";
24536
24586
  var DEFAULT_APP_SPACE = "applications";
24537
24587
  function registerManifestCommand(program) {
@@ -24539,8 +24589,8 @@ function registerManifestCommand(program) {
24539
24589
  manifest.command("resolve <source>").description("Resolve a manifest file or URL to its effective space, paths, and DB basenames").addHelpText("after", `
24540
24590
 
24541
24591
  Examples:
24542
- $ tc manifest resolve ./manifest.json
24543
- $ tc manifest resolve https://app.example.com/manifest.json --json
24592
+ $ ${CLI_NAME20} manifest resolve ./manifest.json
24593
+ $ ${CLI_NAME20} manifest resolve https://app.example.com/manifest.json --json
24544
24594
 
24545
24595
  What it shows:
24546
24596
  - app_id, name, manifest_version
@@ -24550,7 +24600,7 @@ What it shows:
24550
24600
 
24551
24601
  This command is read-only and does NOT contact the node \u2014 it just resolves
24552
24602
  the manifest against the active profile's address/chain so you know which
24553
- \`--space\` and \`--db\` values to pass to other tc commands.
24603
+ \`--space\` and \`--db\` values to pass to other ${CLI_NAME20} commands.
24554
24604
  `).action(async (source, _options, cmd) => {
24555
24605
  try {
24556
24606
  const globalOpts = cmd.optsWithGlobals();
@@ -24619,7 +24669,7 @@ ${theme.heading("SQL databases")}
24619
24669
  `);
24620
24670
  }
24621
24671
  process.stdout.write(theme.muted(`
24622
- Use with: tc sql query --space ${spaceName} --db <db> "..."
24672
+ Use with: ${CLI_NAME20} sql query --space ${spaceName} --db <db> "..."
24623
24673
  `));
24624
24674
  }
24625
24675
  if (permissions.length > 0) {
@@ -24739,6 +24789,7 @@ init_profiles();
24739
24789
  init_formatter();
24740
24790
  init_errors();
24741
24791
  init_constants();
24792
+ import { CLI_NAME as CLI_NAME21 } from "@tinycloud/operations/cli-name";
24742
24793
  import { createInterface as createInterface3 } from "readline";
24743
24794
  init_theme();
24744
24795
  init_types();
@@ -24884,9 +24935,9 @@ profile at command time. Precedence for every kv/sql command:
24884
24935
  explicit --space flag > profile defaultSpace > primary space.
24885
24936
 
24886
24937
  Examples:
24887
- $ tc profile set-default-space applications
24888
- $ tc profile set-default-space applications --profile cli-test
24889
- $ tc profile set-default-space --unset
24938
+ $ ${CLI_NAME21} profile set-default-space applications
24939
+ $ ${CLI_NAME21} profile set-default-space applications --profile cli-test
24940
+ $ ${CLI_NAME21} profile set-default-space --unset
24890
24941
  `).action(async (name, options, cmd) => {
24891
24942
  try {
24892
24943
  const globalOpts = cmd.optsWithGlobals();
@@ -24898,7 +24949,7 @@ Examples:
24898
24949
  if (!options.unset && (name === void 0 || name === "")) {
24899
24950
  throw new CLIError(
24900
24951
  "USAGE_ERROR",
24901
- "Provide a space name (e.g. `tc profile set-default-space applications`) or pass --unset.",
24952
+ `Provide a space name (e.g. \`${CLI_NAME21} profile set-default-space applications\`) or pass --unset.`,
24902
24953
  ExitCode.USAGE_ERROR
24903
24954
  );
24904
24955
  }
@@ -24958,6 +25009,7 @@ function parseOperatorType(raw) {
24958
25009
  // src/commands/replica.ts
24959
25010
  init_sdk();
24960
25011
  init_replication_registry();
25012
+ import { CLI_NAME as CLI_NAME22 } from "@tinycloud/operations/cli-name";
24961
25013
  import { randomBytes as randomBytes6 } from "crypto";
24962
25014
  import { constants as fsConstants2 } from "fs";
24963
25015
  import { open as open4, readdir as readdir5, rename as rename3, stat as stat3, unlink as unlink2, readFile as readFile9, lstat as lstat4 } from "fs/promises";
@@ -25097,11 +25149,11 @@ var EXIT_BY_CODE = {
25097
25149
  var READ_FAILURE = {
25098
25150
  absent: { code: "KEY_ABSENT", exit: ExitCode.NOT_FOUND, what: "is not in the replica (the replica covers its whole prefix)" },
25099
25151
  deleted: { code: "KEY_DELETED", exit: ExitCode.NOT_FOUND, what: "was deleted at the source" },
25100
- content_missing: { code: "CONTENT_MISSING", exit: ExitCode.NOT_FOUND, what: "is known but its content has not been fetched yet; run tc replica sync" },
25152
+ content_missing: { code: "CONTENT_MISSING", exit: ExitCode.NOT_FOUND, what: `is known but its content has not been fetched yet; run ${CLI_NAME22} replica sync` },
25101
25153
  coverage_incomplete: {
25102
25154
  code: "COVERAGE_INCOMPLETE",
25103
25155
  exit: ExitCode.NOT_FOUND,
25104
- what: "is not in the replica, which has not finished its first sync; run tc replica sync"
25156
+ what: `is not in the replica, which has not finished its first sync; run ${CLI_NAME22} replica sync`
25105
25157
  },
25106
25158
  not_covered: { code: "NOT_COVERED", exit: ExitCode.USAGE_ERROR, what: "is outside the replica's prefix" }
25107
25159
  };
@@ -25152,7 +25204,7 @@ async function existingReplicaName(profile, option) {
25152
25204
  const names = await replicaNames(profile);
25153
25205
  if (names.length === 1) return names[0];
25154
25206
  if (names.length === 0) {
25155
- throw new ReplicaError(ReplicaErrorCode.NOT_FOUND, `Profile "${profile}" has no replicas. Create one with: tc replica sync --prefix <prefix>`);
25207
+ throw new ReplicaError(ReplicaErrorCode.NOT_FOUND, `Profile "${profile}" has no replicas. Create one with: ${CLI_NAME22} replica sync --prefix <prefix>`);
25156
25208
  }
25157
25209
  throw new CLIError("USAGE_ERROR", `Profile "${profile}" has several replicas (${names.join(", ")}); pass --replica <name>.`, ExitCode.USAGE_ERROR);
25158
25210
  }
@@ -25211,9 +25263,9 @@ async function storedGrants(profile) {
25211
25263
  function grantHint(space, prefix) {
25212
25264
  return [
25213
25265
  "A replica needs a device grant with get and sync on its prefix:",
25214
- ` device: tc auth request --cap tinycloud.kv:${space}:${prefix}:get,list,metadata,sync --expiry 30d --emit req.json`,
25215
- " owner: tc auth grant req.json > grant.json",
25216
- " device: tc auth import grant.json"
25266
+ ` device: ${CLI_NAME22} auth request --cap tinycloud.kv:${space}:${prefix}:get,list,metadata,sync --expiry 30d --emit req.json`,
25267
+ ` owner: ${CLI_NAME22} auth grant req.json > grant.json`,
25268
+ ` device: ${CLI_NAME22} auth import grant.json`
25217
25269
  ].join("\n");
25218
25270
  }
25219
25271
  function resolveSpace(input, prefix, grants) {
@@ -25304,7 +25356,7 @@ function describeStatus(status) {
25304
25356
  formatField("Size", formatBytes(status.bytes)),
25305
25357
  formatField("Grant", status.device.delegationCid),
25306
25358
  formatField("Last error", status.lastError ? `${status.lastError.code}: ${status.lastError.message}` : null),
25307
- formatField("Purge", status.purgePending ? "incomplete: content files remain; the next tc replica command retries" : null)
25359
+ formatField("Purge", status.purgePending ? `incomplete: content files remain; the next ${CLI_NAME22} replica command retries` : null)
25308
25360
  ].join("\n");
25309
25361
  }
25310
25362
  async function writeFileAtomic(path, bytes) {
@@ -25476,7 +25528,7 @@ or coverage incomplete; 5 grant expired, revoked or not yet valid; 6 network;
25476
25528
  await store.close();
25477
25529
  throw new ReplicaError(
25478
25530
  ReplicaErrorCode.CONFIG_MISMATCH,
25479
- `Replica ${name} already follows ${differs}. Use another --replica name, or tc replica reset --replica ${name} --purge first.`
25531
+ `Replica ${name} already follows ${differs}. Use another --replica name, or ${CLI_NAME22} replica reset --replica ${name} --purge first.`
25480
25532
  );
25481
25533
  }
25482
25534
  } else {
@@ -25654,6 +25706,7 @@ init_theme();
25654
25706
  init_errors();
25655
25707
  init_warnings();
25656
25708
  init_constants();
25709
+ import { CLI_NAME as CLI_NAME24 } from "@tinycloud/operations/cli-name";
25657
25710
  import { readFile as readFile10 } from "fs/promises";
25658
25711
  import { join as join11 } from "path";
25659
25712
  import { homedir, hostname, userInfo } from "os";
@@ -25864,6 +25917,7 @@ function parseStatusEnvelope(line) {
25864
25917
  // src/lib/secrets-wait.ts
25865
25918
  init_constants();
25866
25919
  init_errors();
25920
+ import { CLI_NAME as CLI_NAME23 } from "@tinycloud/operations/cli-name";
25867
25921
  var WAIT_BACKOFF_MS = [3e3, 4500, 6750, 10125];
25868
25922
  var WAIT_STEADY_INTERVAL_MS = 15e3;
25869
25923
  var DEFAULT_WAIT_TIMEOUT = "5m";
@@ -25871,7 +25925,7 @@ var MAX_WAIT_TIMEOUT_MS = 9 * 6e4;
25871
25925
  var MAX_CONSECUTIVE_FAILURES = 5;
25872
25926
  var TIMEOUT_RE = /^(0|\d+s|\d+m)$/;
25873
25927
  var RETRYABLE_STATUS_ERRORS = { NODE_UNREACHABLE: true, NODE_ERROR: true };
25874
- var EXPLICIT_KEY_HINT = "tc secrets wait never signs in, and an explicit private key has no stored session. Use a local profile signed in once with tc --profile <profile> auth login --method local, without TC_PRIVATE_KEY.";
25928
+ var EXPLICIT_KEY_HINT = `${CLI_NAME23} secrets wait never signs in, and an explicit private key has no stored session. Use a local profile signed in once with ${CLI_NAME23} --profile <profile> auth login --method local, without TC_PRIVATE_KEY.`;
25875
25929
  function abortableSleep(ms2, signal) {
25876
25930
  return new Promise((resolve5) => {
25877
25931
  if (signal.aborted) {
@@ -25907,7 +25961,7 @@ async function runSecretsWait(request, deps) {
25907
25961
  let step = 0;
25908
25962
  const cancelled = () => new CLIError(
25909
25963
  "CANCELLED",
25910
- "Interrupted: tc secrets wait stopped before the secrets were ready.",
25964
+ `Interrupted: ${CLI_NAME23} secrets wait stopped before the secrets were ready.`,
25911
25965
  ExitCode.CANCELLED,
25912
25966
  progress === void 0 ? {} : { progress }
25913
25967
  );
@@ -26051,13 +26105,13 @@ function statusError(error, profile, warnings) {
26051
26105
  if (error.code === "AUTH_REQUIRED" || error.code === "SESSION_NOT_FOUND") {
26052
26106
  const recovery = recoveryOf(error, "sign_in");
26053
26107
  if (recovery !== void 0) {
26054
- const hint = recovery.command !== void 0 ? `Sign in once with: ${recovery.command}, then retry.` : `Sign in to profile "${profile}" once with tc auth login, then retry.`;
26108
+ const hint = recovery.command !== void 0 ? `Sign in once with: ${recovery.command}, then retry.` : `Sign in to profile "${profile}" once with ${CLI_NAME23} auth login, then retry.`;
26055
26109
  return new CLIError("AUTH_REQUIRED", error.message, ExitCode.AUTH_REQUIRED, { hint, recovery, ...extra });
26056
26110
  }
26057
26111
  }
26058
26112
  if (error.code === "PROFILE_MIGRATION_REQUIRED") {
26059
26113
  const recovery = recoveryOf(error, "complete_migration");
26060
- const hint = recovery?.command !== void 0 ? `Run ${recovery.command} once to finish this profile's one-time upgrade, then retry wait.` : `Run tc auth caps once with profile "${profile}" to finish its one-time upgrade, then retry wait.`;
26114
+ const hint = recovery?.command !== void 0 ? `Run ${recovery.command} once to finish this profile's one-time upgrade, then retry wait.` : `Run ${CLI_NAME23} auth caps once with profile "${profile}" to finish its one-time upgrade, then retry wait.`;
26061
26115
  return new CLIError("PROFILE_MIGRATION_REQUIRED", error.message, ExitCode.ERROR, {
26062
26116
  hint,
26063
26117
  ...recovery === void 0 ? {} : { recovery },
@@ -26249,11 +26303,11 @@ async function runSecretOperation(params) {
26249
26303
  }
26250
26304
  function secretPermissionReason(action, name) {
26251
26305
  const target = name ? ` secret "${name}"` : " secrets";
26252
- return `Allow \`tc secrets ${action}${name ? ` ${name}` : ""}\` to access${target} with the required TinyCloud permissions.`;
26306
+ return `Allow \`${CLI_NAME24} secrets ${action}${name ? ` ${name}` : ""}\` to access${target} with the required TinyCloud permissions.`;
26253
26307
  }
26254
26308
  function assertOwnerApprovalPossible(profileName2, profile, action, name, missing = []) {
26255
26309
  if (profile.authMethod !== "openkey" || process.stdin.isTTY || process.stderr.isTTY) return;
26256
- const command = `tc secrets ${action === "del" ? "delete" : action}${name ? ` ${name}` : ""}`;
26310
+ const command = `${CLI_NAME24} secrets ${action === "del" ? "delete" : action}${name ? ` ${name}` : ""}`;
26257
26311
  throw new CLIError(
26258
26312
  "PERMISSION_DENIED",
26259
26313
  action === "get" ? missing.length > 0 && missing.every((permission) => permission.service === "tinycloud.encryption" && Array.isArray(permission.actions) && permission.actions.length > 0 && permission.actions.every((capability) => capability === SECRET_DECRYPT_CAPABILITY)) ? `Profile "${profileName2}" lacks the scoped decrypt authority (${SECRET_DECRYPT_CAPABILITY}) needed to read secret "${name}", and requesting it needs an interactive browser approval.` : `Profile "${profileName2}" lacks a scoped read or decrypt grant needed to read secret "${name}", and requesting it needs an interactive browser approval.` : `Profile "${profileName2}" holds no grant for \`${command}\`, and requesting one needs an interactive browser approval.`,
@@ -26264,7 +26318,7 @@ function assertOwnerApprovalPossible(profileName2, profile, action, name, missin
26264
26318
  );
26265
26319
  }
26266
26320
  function scopedSecretLoginHint(profileName2) {
26267
- return `Have the owner approve a scoped login whose manifest names the secret: tc --profile ${profileName2} auth login --method openkey --paste --manifest <manifest.json>. Pass the owner's code on stdin, newline-terminated.`;
26321
+ return `Have the owner approve a scoped login whose manifest names the secret: ${CLI_NAME24} --profile ${profileName2} auth login --method openkey --paste --manifest <manifest.json>. Pass the owner's code on stdin, newline-terminated.`;
26268
26322
  }
26269
26323
  async function runSecretOperationAttempt(label, operation) {
26270
26324
  try {
@@ -26398,7 +26452,7 @@ ${message}`,
26398
26452
  "AUTH_REQUIRED",
26399
26453
  "Not signed in to TinyCloud.",
26400
26454
  ExitCode.AUTH_REQUIRED,
26401
- { hint: `Sign in with: tc --profile ${result.context.profile} auth login` }
26455
+ { hint: `Sign in with: ${CLI_NAME24} --profile ${result.context.profile} auth login` }
26402
26456
  );
26403
26457
  }
26404
26458
  if (result.error.code === "NODE_UNREACHABLE") {
@@ -26875,7 +26929,7 @@ function registerSecretsCommand(program, openKeyAcquisition) {
26875
26929
  name: "Encryption network",
26876
26930
  ok: false,
26877
26931
  detail: `${networkName} not found`,
26878
- hint: `tc secrets network init ${networkName}`
26932
+ hint: `${CLI_NAME24} secrets network init ${networkName}`
26879
26933
  }
26880
26934
  ];
26881
26935
  let secret;
@@ -26921,7 +26975,7 @@ function registerSecretsCommand(program, openKeyAcquisition) {
26921
26975
  name: "Secret access",
26922
26976
  ok: false,
26923
26977
  detail: notFound ? `${resolved.permissionPaths.vault} not found` : result.error.message,
26924
- hint: notFound ? local ? `tc secrets put ${resolved.name}${formatSecretScopeFlag(scopeOptions)} --stdin` : `tc secrets request ${resolved.name}${formatSecretScopeFlag(scopeOptions)}` : `Ask the owner profile to grant ${secretCapabilityAction("get")} and ${SECRET_DECRYPT_CAPABILITY}.`
26978
+ hint: notFound ? local ? `${CLI_NAME24} secrets put ${resolved.name}${formatSecretScopeFlag(scopeOptions)} --stdin` : `${CLI_NAME24} secrets request ${resolved.name}${formatSecretScopeFlag(scopeOptions)}` : `Ask the owner profile to grant ${secretCapabilityAction("get")} and ${SECRET_DECRYPT_CAPABILITY}.`
26925
26979
  });
26926
26980
  }
26927
26981
  } else {
@@ -27165,7 +27219,7 @@ function registerSecretsCommand(program, openKeyAcquisition) {
27165
27219
  if (effectiveLocal(profile, options)) {
27166
27220
  throw new CLIError(
27167
27221
  "LOCAL_OWNER_PROFILE",
27168
- `Profile "${ctx.profile}" uses a local key, which owns its secrets: store them with tc secrets put NAME --stdin instead of requesting them.`,
27222
+ `Profile "${ctx.profile}" uses a local key, which owns its secrets: store them with ${CLI_NAME24} secrets put NAME --stdin instead of requesting them.`,
27169
27223
  ExitCode.USAGE_ERROR
27170
27224
  );
27171
27225
  }
@@ -27286,6 +27340,9 @@ function registerSecretsCommand(program, openKeyAcquisition) {
27286
27340
  });
27287
27341
  }
27288
27342
 
27343
+ // src/commands/share.ts
27344
+ import { CLI_NAME as CLI_NAME25 } from "@tinycloud/operations/cli-name";
27345
+
27289
27346
  // ../share-sdk/dist/index.js
27290
27347
  init_sha2();
27291
27348
  init_ed25519();
@@ -35765,12 +35822,12 @@ function shareCliError(error, operation = "publish") {
35765
35822
  const profileName2 = "profileName" in failure ? failure.profileName : void 0;
35766
35823
  const localKey = "localKey" in failure && failure.localKey === true;
35767
35824
  const profileHint = profileName2 === void 0 ? "" : `--profile ${profileName2} `;
35768
- const loginHint = localKey ? `\`tc ${profileHint}auth login --method local\`` : `\`tc ${profileHint}auth login --device --manifest builtin:share-publishing\` (or \`tc ${profileHint}enable share\`)`;
35825
+ const loginHint = localKey ? `\`${CLI_NAME25} ${profileHint}auth login --method local\`` : `\`${CLI_NAME25} ${profileHint}auth login --device --manifest builtin:share-publishing\` (or \`${CLI_NAME25} ${profileHint}enable share\`)`;
35769
35826
  if (failure.kind === "caveated-session") {
35770
35827
  const holder = profileName2 === void 0 ? "this session" : `profile ${profileName2}'s session`;
35771
35828
  return new CLIError(
35772
35829
  "PERMISSION_DENIED",
35773
- `${holder} carries signed restrictions (caveats) on the authority an anyone-with-link share needs, so it cannot create the share link; nothing was shared. Approve Share publishing without restrictions on a new, dedicated profile (any unused name): \`tc init --name publisher --key-only && tc --profile publisher enable share\``,
35830
+ `${holder} carries signed restrictions (caveats) on the authority an anyone-with-link share needs, so it cannot create the share link; nothing was shared. Approve Share publishing without restrictions on a new, dedicated profile (any unused name): \`${CLI_NAME25} init --name publisher --key-only && ${CLI_NAME25} --profile publisher enable share\``,
35774
35831
  5
35775
35832
  );
35776
35833
  }
@@ -36131,6 +36188,7 @@ init_constants();
36131
36188
  init_sdk();
36132
36189
  init_host();
36133
36190
  init_theme();
36191
+ import { CLI_NAME as CLI_NAME26 } from "@tinycloud/operations/cli-name";
36134
36192
  import { randomBytes as randomBytes8 } from "crypto";
36135
36193
  import { mkdir as mkdir5, writeFile as writeFile4 } from "fs/promises";
36136
36194
  import { dirname as dirname6 } from "path";
@@ -36182,10 +36240,10 @@ function registerSpaceCommand(program) {
36182
36240
 
36183
36241
  A delegate cannot host a space \u2014 only its owner (root authority) can. This
36184
36242
  emits a tinycloud.host.request artifact naming the space and its owner so you
36185
- can hand it to the owner; they run \`tc space host <name>\` and confirm.
36243
+ can hand it to the owner; they run \`${CLI_NAME26} space host <name>\` and confirm.
36186
36244
 
36187
36245
  If you ARE the owner of the resolved space, this refuses and tells you to host
36188
- it directly with \`tc space host <name>\` (no request needed).
36246
+ it directly with \`${CLI_NAME26} space host <name>\` (no request needed).
36189
36247
  `).action(async (name, options, cmd) => {
36190
36248
  try {
36191
36249
  const globalOpts = cmd.optsWithGlobals();
@@ -36196,7 +36254,7 @@ it directly with \`tc space host <name>\` (no request needed).
36196
36254
  if (await isRootAuthority(spaceId, ctx.profile)) {
36197
36255
  throw new CLIError(
36198
36256
  "ALREADY_ROOT_AUTHORITY",
36199
- `You are the owner of ${spaceId}. Host it directly: tc space host ${spaceName}`,
36257
+ `You are the owner of ${spaceId}. Host it directly: ${CLI_NAME26} space host ${spaceName}`,
36200
36258
  ExitCode.USAGE_ERROR
36201
36259
  );
36202
36260
  }
@@ -36282,6 +36340,7 @@ init_sdk();
36282
36340
  init_space();
36283
36341
  init_host();
36284
36342
  init_theme();
36343
+ import { CLI_NAME as CLI_NAME27 } from "@tinycloud/operations/cli-name";
36285
36344
  import { writeFile as writeFile5 } from "fs/promises";
36286
36345
  import { resolve as resolve4 } from "path";
36287
36346
  async function dbHandle(node, dbName, spaceInput, profileName2) {
@@ -36305,12 +36364,12 @@ database for simple apps, or pass --db to target a named database. Pass
36305
36364
  --space to target a non-primary space (e.g. the manifest "applications" space).
36306
36365
 
36307
36366
  Common workflows:
36308
- $ tc sql execute "CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, body TEXT)"
36309
- $ tc sql execute "INSERT INTO notes (body) VALUES (?)" --params '["ship docs"]'
36310
- $ tc sql query "SELECT id, body FROM notes ORDER BY id"
36311
- $ tc sql query "SELECT * FROM events WHERE type = ?" --db analytics --params '["signup"]'
36312
- $ tc sql query "SELECT count(*) FROM conversation" --space applications --db xyz.tinycloud.listen/conversations
36313
- $ tc sql export --db analytics --output analytics.db
36367
+ $ ${CLI_NAME27} sql execute "CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, body TEXT)"
36368
+ $ ${CLI_NAME27} sql execute "INSERT INTO notes (body) VALUES (?)" --params '["ship docs"]'
36369
+ $ ${CLI_NAME27} sql query "SELECT id, body FROM notes ORDER BY id"
36370
+ $ ${CLI_NAME27} sql query "SELECT * FROM events WHERE type = ?" --db analytics --params '["signup"]'
36371
+ $ ${CLI_NAME27} sql query "SELECT count(*) FROM conversation" --space applications --db xyz.tinycloud.listen/conversations
36372
+ $ ${CLI_NAME27} sql export --db analytics --output analytics.db
36314
36373
 
36315
36374
  Commands:
36316
36375
  query Read rows with SELECT statements
@@ -36327,10 +36386,10 @@ Tips:
36327
36386
  sql.command("query <sql>").description("Run a read-only SELECT query").option("--db <name>", "SQLite database name within the current space", "default").option("--space <name|uri>", "Target a non-primary space (short name or full URI)").option("--params <json>", "Bind parameters as a JSON array for ? placeholders").addHelpText("after", `
36328
36387
 
36329
36388
  Examples:
36330
- $ tc sql query "SELECT * FROM notes ORDER BY id"
36331
- $ tc sql query "SELECT * FROM notes WHERE id = ?" --params '[42]'
36332
- $ tc sql query "SELECT count(*) AS total FROM events" --db analytics --json
36333
- $ tc sql query "SELECT count(*) FROM conversation" --space applications --db xyz.tinycloud.listen/conversations
36389
+ $ ${CLI_NAME27} sql query "SELECT * FROM notes ORDER BY id"
36390
+ $ ${CLI_NAME27} sql query "SELECT * FROM notes WHERE id = ?" --params '[42]'
36391
+ $ ${CLI_NAME27} sql query "SELECT count(*) AS total FROM events" --db analytics --json
36392
+ $ ${CLI_NAME27} sql query "SELECT count(*) FROM conversation" --space applications --db xyz.tinycloud.listen/conversations
36334
36393
 
36335
36394
  Output:
36336
36395
  Human output is formatted as a table. Piped output or --json returns
@@ -36371,11 +36430,11 @@ ${rowCount} row${rowCount === 1 ? "" : "s"} returned`) + "\n");
36371
36430
  sql.command("execute <sql>").description("Run a write or schema statement").option("--db <name>", "SQLite database name within the current space", "default").option("--space <name|uri>", "Target a non-primary space (short name or full URI)").option("--params <json>", "Bind parameters as a JSON array for ? placeholders").addHelpText("after", `
36372
36431
 
36373
36432
  Examples:
36374
- $ tc sql execute "CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, body TEXT)"
36375
- $ tc sql execute "INSERT INTO notes (body) VALUES (?)" --params '["first note"]'
36376
- $ tc sql execute "UPDATE notes SET body = ? WHERE id = ?" --params '["edited", 1]'
36377
- $ tc sql execute "DROP TABLE old_notes" --db archive
36378
- $ tc sql execute "DELETE FROM conversation WHERE id = ?" --space applications --db xyz.tinycloud.listen/conversations --params '["abc"]'
36433
+ $ ${CLI_NAME27} sql execute "CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, body TEXT)"
36434
+ $ ${CLI_NAME27} sql execute "INSERT INTO notes (body) VALUES (?)" --params '["first note"]'
36435
+ $ ${CLI_NAME27} sql execute "UPDATE notes SET body = ? WHERE id = ?" --params '["edited", 1]'
36436
+ $ ${CLI_NAME27} sql execute "DROP TABLE old_notes" --db archive
36437
+ $ ${CLI_NAME27} sql execute "DELETE FROM conversation WHERE id = ?" --space applications --db xyz.tinycloud.listen/conversations --params '["abc"]'
36379
36438
 
36380
36439
  Output:
36381
36440
  Returns JSON with the changed row count and last inserted row id when available.
@@ -36404,9 +36463,9 @@ Output:
36404
36463
  sql.command("export").description("Export a SQLite database as a binary .db file").option("--db <name>", "SQLite database name within the current space", "default").option("--space <name|uri>", "Target a non-primary space (short name or full URI)").option("-o, --output <file>", "Output file path", "export.db").addHelpText("after", `
36405
36464
 
36406
36465
  Examples:
36407
- $ tc sql export
36408
- $ tc sql export --db analytics --output analytics.db
36409
- $ tc sql export --space applications --db xyz.tinycloud.listen/conversations --output listen.db
36466
+ $ ${CLI_NAME27} sql export
36467
+ $ ${CLI_NAME27} sql export --db analytics --output analytics.db
36468
+ $ ${CLI_NAME27} sql export --space applications --db xyz.tinycloud.listen/conversations --output listen.db
36410
36469
 
36411
36470
  Output:
36412
36471
  Writes the database file locally and returns JSON with the path and size.
@@ -36439,19 +36498,19 @@ Output:
36439
36498
  sql.command("copy").description("Copy rows between SQL databases (optionally across spaces)").requiredOption("--from-db <name>", "Source database name").requiredOption("--to-db <name>", "Destination database name").option("--from-space <name|uri>", "Source space (defaults to primary)").option("--to-space <name|uri>", "Destination space (defaults to primary)").option("--table <name...>", "Restrict copy to specific tables (repeat or comma-separated)").option("--dry-run", "Print the plan without writing", false).addHelpText("after", `
36440
36499
 
36441
36500
  Examples:
36442
- $ tc sql copy --from-db com.tinycloud.conversation-sync/conversations \\
36501
+ $ ${CLI_NAME27} sql copy --from-db com.tinycloud.conversation-sync/conversations \\
36443
36502
  --to-db xyz.tinycloud.listen/conversations \\
36444
36503
  --space applications --dry-run
36445
- $ tc sql copy --from-space applications --from-db com.foo/data \\
36504
+ $ ${CLI_NAME27} sql copy --from-space applications --from-db com.foo/data \\
36446
36505
  --to-space applications --to-db com.bar/data \\
36447
36506
  --table conversation --table participant
36448
36507
 
36449
36508
  Notes:
36450
36509
  - Refuses to run when (resolved space, db) is identical for source and destination.
36451
- - Does NOT create destination tables. Run the target app once (or use \`tc sql execute\`)
36510
+ - Does NOT create destination tables. Run the target app once (or use \`${CLI_NAME27} sql execute\`)
36452
36511
  to materialize the schema before copying.
36453
36512
  - One row at a time; suitable for small/medium datasets. Large copies should
36454
- use \`tc sql export\` + bulk import.
36513
+ use \`${CLI_NAME27} sql export\` + bulk import.
36455
36514
  - Authorization: the active session/delegation must cover sql/read on source
36456
36515
  AND sql/write on destination. Otherwise the relevant operation will fail.
36457
36516
  `).action(async (options, cmd) => {
@@ -36551,6 +36610,7 @@ init_errors();
36551
36610
  init_formatter();
36552
36611
  init_theme();
36553
36612
  init_permissions();
36613
+ import { CLI_NAME as CLI_NAME28 } from "@tinycloud/operations/cli-name";
36554
36614
  import {
36555
36615
  NodeWasmBindings as NodeWasmBindings2
36556
36616
  } from "@tinycloud/node-sdk";
@@ -36824,7 +36884,7 @@ function formatStatus(summary) {
36824
36884
  lines.push(`Default profile: ${theme.value(summary.defaultProfile)}`);
36825
36885
  lines.push("");
36826
36886
  if (summary.profiles.length === 0) {
36827
- lines.push(theme.muted("No profiles configured. Run: tc init"));
36887
+ lines.push(theme.muted(`No profiles configured. Run: ${CLI_NAME28} init`));
36828
36888
  return `${lines.join("\n")}
36829
36889
  `;
36830
36890
  }