@tinycloud/cli 1.5.0-beta.32 → 1.5.0-beta.33

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.
@@ -10157,7 +10157,7 @@ var init_profiles = __esm({
10157
10157
  if (!profile) {
10158
10158
  throw new CLIError(
10159
10159
  "PROFILE_NOT_FOUND",
10160
- `Profile "${name}" does not exist. Create it with \`${CLI_NAME9} init --name ${name}\`.`
10160
+ `Profile "${name}" does not exist. Create it with \`${CLI_NAME9} init --key-only --name ${name}\`.`
10161
10161
  );
10162
10162
  }
10163
10163
  return profile;
@@ -17967,7 +17967,7 @@ function formatSpace(space) {
17967
17967
  init_profile_gate();
17968
17968
  init_dist();
17969
17969
  init_profiles();
17970
- import { CLI_NAME as CLI_NAME18 } from "@tinycloud/operations/cli-name";
17970
+ import { CLI_NAME as CLI_NAME19 } from "@tinycloud/operations/cli-name";
17971
17971
  import { get as httpGet } from "http";
17972
17972
  import { get as httpsGet } from "https";
17973
17973
  import { spawn } from "child_process";
@@ -35741,6 +35741,81 @@ function registerAuthGrantsCommand(auth, options = {}) {
35741
35741
  });
35742
35742
  }
35743
35743
 
35744
+ // src/commands/init.ts
35745
+ init_profiles();
35746
+ init_formatter();
35747
+ init_errors();
35748
+ init_constants();
35749
+ import { CLI_NAME as CLI_NAME18 } from "@tinycloud/operations/cli-name";
35750
+ async function createKeyOnlyProfile(profileName2, host, defaultSpace) {
35751
+ await ProfileManager.ensureConfigDir();
35752
+ const { jwk, did } = await generateKey2();
35753
+ await ProfileManager.setKey(profileName2, jwk);
35754
+ await ProfileManager.setProfile(profileName2, {
35755
+ name: profileName2,
35756
+ host,
35757
+ chainId: DEFAULT_CHAIN_ID,
35758
+ spaceName: "default",
35759
+ did,
35760
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
35761
+ ...defaultSpace ? { defaultSpace } : {}
35762
+ });
35763
+ const config = await ProfileManager.getConfig();
35764
+ if (profileName2 === "default" || !await ProfileManager.profileExists(config.defaultProfile)) {
35765
+ await ProfileManager.setConfig({ ...config, defaultProfile: profileName2 });
35766
+ }
35767
+ return { did };
35768
+ }
35769
+ function registerInitCommand(program) {
35770
+ 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) => {
35771
+ try {
35772
+ const globalOpts = cmd.optsWithGlobals();
35773
+ const profileName2 = options.name;
35774
+ const host = options.host ?? globalOpts.host ?? DEFAULT_HOST;
35775
+ const defaultSpace = options.defaultSpace;
35776
+ if (defaultSpace !== void 0 && !/^[A-Za-z0-9_-]+$/.test(defaultSpace)) {
35777
+ throw new CLIError(
35778
+ "INVALID_SPACE",
35779
+ `Invalid --default-space "${defaultSpace}". Use a short name ([A-Za-z0-9_-]).`,
35780
+ ExitCode.USAGE_ERROR
35781
+ );
35782
+ }
35783
+ if (await ProfileManager.profileExists(profileName2)) {
35784
+ throw new CLIError(
35785
+ "PROFILE_EXISTS",
35786
+ `Profile "${profileName2}" already exists. Use \`${CLI_NAME18} profile delete ${profileName2}\` first or choose a different name.`,
35787
+ ExitCode.ERROR
35788
+ );
35789
+ }
35790
+ const { did } = await withSpinner("Generating key...", () => createKeyOnlyProfile(profileName2, host, defaultSpace));
35791
+ if (options.keyOnly) {
35792
+ outputJson({
35793
+ profile: profileName2,
35794
+ did,
35795
+ host,
35796
+ authenticated: false
35797
+ });
35798
+ return;
35799
+ }
35800
+ const { delegationData } = await refreshOpenKeySession(profileName2, host, {
35801
+ paste: options.paste,
35802
+ noPopup: options.popup === false,
35803
+ persistHost: true
35804
+ });
35805
+ await ensureSpaceSetup({ profile: profileName2, host }, delegationData, delegationData.permissions);
35806
+ outputJson({
35807
+ profile: profileName2,
35808
+ did,
35809
+ host,
35810
+ spaceId: delegationData.spaceId,
35811
+ authenticated: true
35812
+ });
35813
+ } catch (error) {
35814
+ return handleError(error);
35815
+ }
35816
+ });
35817
+ }
35818
+
35744
35819
  // src/commands/auth.ts
35745
35820
  init_sdk();
35746
35821
  init_session_expired();
@@ -36020,7 +36095,7 @@ async function prepareProfileRemoteLogout(ctx, expectedSessionCid, discardLocalC
36020
36095
  "REVOCATION_AUTHORITY_UNAVAILABLE",
36021
36096
  "OpenKey owner CID revocation requires a verified signed revoke-control grant or wallet proof. No CID was revoked; session, key and replica files remain for retry, while local replica reads stay denied.",
36022
36097
  ExitCode.AUTH_REQUIRED,
36023
- { hint: `This sign-in can't be revoked from the CLI yet. Revoke it at https://account.tinycloud.xyz/delegations. To sign out on this computer only, run \`${CLI_NAME18} auth logout\`.` }
36098
+ { hint: `This sign-in can't be revoked from the CLI yet. Revoke it at https://account.tinycloud.xyz/delegations. To sign out on this computer only, run \`${CLI_NAME19} auth logout\`.` }
36024
36099
  );
36025
36100
  }
36026
36101
  const signerDid = addressToDID(
@@ -36064,7 +36139,7 @@ async function revokeForLogout(ctx, discardLocalChanges) {
36064
36139
  "REVOCATION_FAILED",
36065
36140
  `Revocation failed for ${cid}: ${result.error.message}. Session, key, and replica files are retained for retry; local reads stay denied.`,
36066
36141
  ExitCode.ERROR,
36067
- { cid, hint: `Retry \`${CLI_NAME18} auth logout --revoke\` when the node is available.` }
36142
+ { cid, hint: `Retry \`${CLI_NAME19} auth logout --revoke\` when the node is available.` }
36068
36143
  );
36069
36144
  }
36070
36145
  if (result.data.cid !== cid || result.data.revoked !== true) {
@@ -36083,7 +36158,7 @@ async function revokeForLogout(ctx, discardLocalChanges) {
36083
36158
  "REVOCATION_FAILED",
36084
36159
  `Revocation failed before local logout: ${error instanceof Error ? error.message : String(error)}. Session, key, and replica files are retained for retry; local reads stay denied.`,
36085
36160
  ExitCode.ERROR,
36086
- { hint: `Retry \`${CLI_NAME18} auth logout --revoke\` when online authority is available.` }
36161
+ { hint: `Retry \`${CLI_NAME19} auth logout --revoke\` when online authority is available.` }
36087
36162
  );
36088
36163
  }
36089
36164
  }
@@ -36282,7 +36357,7 @@ async function finishProfileLogout(ctx, options = {}) {
36282
36357
  function registerAuthCommand(program, options) {
36283
36358
  const auth = program.command("auth").description("Authentication management");
36284
36359
  registerAuthGrantsCommand(auth, { openKeyAcquisition: options?.openKeyAcquisition });
36285
- 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; OpenKey return codes expire after 5 minutes").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_NAME18} 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("--force", "Replica-enabled OpenKey login: replace the stored session key even when recorded shares could not be checked or hold unexpired shares that need the current key").option("--keys <folder>", "Also let this sign-in create and use encryption keys in this folder (for example `qa`). The node must support named keys. With OpenKey, the first time on a profile also needs `--owner`.").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) => {
36360
+ 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; OpenKey return codes expire after 5 minutes").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_NAME19} 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("--force", "Replica-enabled OpenKey login: replace the stored session key even when recorded shares could not be checked or hold unexpired shares that need the current key").option("--keys <folder>", "Also let this sign-in create and use encryption keys in this folder (for example `qa`). The node must support named keys. With OpenKey, the first time on a profile also needs `--owner`.").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) => {
36286
36361
  try {
36287
36362
  if (options2.device && options2.paste) {
36288
36363
  throw new CLIError("INVALID_ARGUMENT", "--device and --paste are mutually exclusive.", ExitCode.USAGE_ERROR);
@@ -36380,6 +36455,13 @@ function registerAuthCommand(program, options) {
36380
36455
  await persistReplicationLogin(ctx.profile, replicationOptions);
36381
36456
  if (replicationOptions.allowSecrets) writeReplicationSecretsWarning();
36382
36457
  } else {
36458
+ const created = await ProfileManager.withLock(ctx.profile, async () => {
36459
+ if (await ProfileManager.profileExists(ctx.profile)) return false;
36460
+ await createKeyOnlyProfile(ctx.profile, globalOpts.host ?? DEFAULT_HOST);
36461
+ return true;
36462
+ });
36463
+ if (created) process.stderr.write(`Created profile "${ctx.profile}"
36464
+ `);
36383
36465
  const preparedCommitted = await handleOpenKeyAuth(ctx.profile, ctx.host, {
36384
36466
  paste: options2.paste,
36385
36467
  noPopup: options2.popup === false,
@@ -36440,7 +36522,7 @@ function registerAuthCommand(program, options) {
36440
36522
  authenticated: false,
36441
36523
  replicasRemoved,
36442
36524
  replicasKept: options2.keepReplicas === true,
36443
- warning: online ? "The node confirmed revocation of the listed CIDs before local logout." : options2.keepReplicas ? "Legacy replica files remain on disk; this local logout clears the session but does not revoke node grants. Purge the files before a future sign-in if they must not be reused." : `Logout is local; delegations and grants on the node stay valid until they expire. Use \`${CLI_NAME18} delegation revoke <cid>\` to end access now.`,
36525
+ warning: online ? "The node confirmed revocation of the listed CIDs before local logout." : options2.keepReplicas ? "Legacy replica files remain on disk; this local logout clears the session but does not revoke node grants. Purge the files before a future sign-in if they must not be reused." : `Logout is local; delegations and grants on the node stay valid until they expire. Use \`${CLI_NAME19} delegation revoke <cid>\` to end access now.`,
36444
36526
  ...online === void 0 ? {} : {
36445
36527
  revokedCids: online.plan.cids,
36446
36528
  revocationExcluded: online.plan.excluded
@@ -36585,7 +36667,7 @@ ${appsAgentScopeNotice(preset.mode, preset.appIds)}
36585
36667
  if (profile.authMethod === "openkey" || options2.device) {
36586
36668
  const key = await ProfileManager.getKey(ctx.profile);
36587
36669
  if (!key) {
36588
- throw new CLIError("NO_KEY", `No key found for profile "${ctx.profile}". Run \`${CLI_NAME18} --profile ${ctx.profile} auth rotate\` to create a new key and sign in.`, ExitCode.AUTH_REQUIRED);
36670
+ throw new CLIError("NO_KEY", `No key found for profile "${ctx.profile}". Run \`${CLI_NAME19} --profile ${ctx.profile} auth rotate\` to create a new key and sign in.`, ExitCode.AUTH_REQUIRED);
36589
36671
  }
36590
36672
  const openkeyHost = resolveOpenKeyHost(profile);
36591
36673
  const grants = [];
@@ -36605,7 +36687,7 @@ ${appsAgentScopeNotice(preset.mode, preset.appIds)}
36605
36687
  if (notices) process.stderr.write(`${notices.prompts[index]}
36606
36688
  `);
36607
36689
  const reason = permissionGrantReason(
36608
- `Grant requested TinyCloud permissions from \`${CLI_NAME18} auth request --grant\`.`,
36690
+ `Grant requested TinyCloud permissions from \`${CLI_NAME19} auth request --grant\`.`,
36609
36691
  group
36610
36692
  );
36611
36693
  const request = grantRequestPermissions(group, profile.spaceId ?? profile.spaceName);
@@ -36717,7 +36799,7 @@ ${appsAgentScopeNotice(preset.mode, preset.appIds)}
36717
36799
  kind: parsed.kind,
36718
36800
  requestId: parsed.requestId,
36719
36801
  requested: parsed.requested,
36720
- next: `${CLI_NAME18} auth retry ${parsed.requestId}`
36802
+ next: `${CLI_NAME19} auth retry ${parsed.requestId}`
36721
36803
  });
36722
36804
  return;
36723
36805
  }
@@ -37338,7 +37420,7 @@ async function acquireOpenKeyApproval(params) {
37338
37420
  if (!key) {
37339
37421
  throw new CLIError(
37340
37422
  "NO_KEY",
37341
- `No key found for profile "${params.ctx.profile}". Run \`${CLI_NAME18} --profile ${params.ctx.profile} auth rotate\` to create a new key and sign in.`,
37423
+ `No key found for profile "${params.ctx.profile}". Run \`${CLI_NAME19} --profile ${params.ctx.profile} auth rotate\` to create a new key and sign in.`,
37342
37424
  ExitCode.AUTH_REQUIRED
37343
37425
  );
37344
37426
  }
@@ -37414,7 +37496,7 @@ async function ensureDelegationAuthority(params) {
37414
37496
  if (!key) {
37415
37497
  throw new CLIError(
37416
37498
  "NO_KEY",
37417
- `No key found for profile "${params.ctx.profile}". Run \`${CLI_NAME18} --profile ${params.ctx.profile} auth rotate\` to create a new key and sign in.`,
37499
+ `No key found for profile "${params.ctx.profile}". Run \`${CLI_NAME19} --profile ${params.ctx.profile} auth rotate\` to create a new key and sign in.`,
37418
37500
  ExitCode.AUTH_REQUIRED
37419
37501
  );
37420
37502
  }
@@ -37671,7 +37753,7 @@ async function rotateAuthKey(profileName2, host, options = {}) {
37671
37753
  if (!profile.privateKey) {
37672
37754
  throw new CLIError(
37673
37755
  "LOCAL_OWNER_KEY_REQUIRED",
37674
- `Profile "${profileName2}" does not have a local owner private key. Run \`${CLI_NAME18} auth login --method local\` first.`,
37756
+ `Profile "${profileName2}" does not have a local owner private key. Run \`${CLI_NAME19} auth login --method local\` first.`,
37675
37757
  ExitCode.AUTH_REQUIRED
37676
37758
  );
37677
37759
  }
@@ -38036,9 +38118,9 @@ async function refreshPreparedOpenKeySession(params) {
38036
38118
  }
38037
38119
  var KEYS_APPROVAL_NOTE = (folder) => `On the OpenKey page, the row that mentions tinycloud.encryption lets this profile create and use keys in the folder "${folder}/". Keep every row ticked. To sign in without keys, untick that whole row and nothing else; any other change makes OpenKey refuse the sign-in.
38038
38120
  `;
38039
- var keysNotGrantedAfterLogin = (profileName2) => `You're signed in, but without named keys: the tinycloud.encryption permission wasn't approved. To add them, sign in again with \`${CLI_NAME18} --profile ${profileName2} auth login --keys <folder>\` and leave the row that mentions tinycloud.encryption ticked.
38121
+ var keysNotGrantedAfterLogin = (profileName2) => `You're signed in, but without named keys: the tinycloud.encryption permission wasn't approved. To add them, sign in again with \`${CLI_NAME19} --profile ${profileName2} auth login --keys <folder>\` and leave the row that mentions tinycloud.encryption ticked.
38040
38122
  `;
38041
- var KEYS_FOLDER_NOT_READY = `You're signed in, but your encryption keys aren't set up yet. Try \`${CLI_NAME18} keys ensure <folder>/<name>\` again in a minute.
38123
+ var KEYS_FOLDER_NOT_READY = `You're signed in, but your encryption keys aren't set up yet. Try \`${CLI_NAME19} keys ensure <folder>/<name>\` again in a minute.
38042
38124
  `;
38043
38125
  async function readyNamedKeysNetwork(node) {
38044
38126
  try {
@@ -38250,7 +38332,7 @@ async function refreshOpenKeySession(profileName2, host, options = {}) {
38250
38332
  }
38251
38333
 
38252
38334
  // src/commands/completion.ts
38253
- import { CLI_NAME as CLI_NAME19 } from "@tinycloud/operations/cli-name";
38335
+ import { CLI_NAME as CLI_NAME20 } from "@tinycloud/operations/cli-name";
38254
38336
  function registerCompletionCommand(program) {
38255
38337
  const completion = program.command("completion").description("Generate shell completions");
38256
38338
  completion.command("bash").description("Output bash completions").action(() => {
@@ -38267,7 +38349,7 @@ function registerCompletionCommand(program) {
38267
38349
  });
38268
38350
  }
38269
38351
  function generateBashCompletion() {
38270
- return `# ${CLI_NAME19} bash completion
38352
+ return `# ${CLI_NAME20} bash completion
38271
38353
  _tc_completions() {
38272
38354
  local cur prev commands subcommands
38273
38355
  COMPREPLY=()
@@ -38292,11 +38374,11 @@ _tc_completions() {
38292
38374
  COMPREPLY=( $(compgen -W "\${subcommands}" -- "\${cur}") )
38293
38375
  fi
38294
38376
  }
38295
- complete -F _tc_completions ${CLI_NAME19}
38377
+ complete -F _tc_completions ${CLI_NAME20}
38296
38378
  `;
38297
38379
  }
38298
38380
  function generateZshCompletion() {
38299
- return `#compdef ${CLI_NAME19}
38381
+ return `#compdef ${CLI_NAME20}
38300
38382
 
38301
38383
  _tc() {
38302
38384
  local -a commands
@@ -38347,50 +38429,50 @@ _tc
38347
38429
  `;
38348
38430
  }
38349
38431
  function generateFishCompletion() {
38350
- return `# ${CLI_NAME19} fish completion
38432
+ return `# ${CLI_NAME20} fish completion
38351
38433
  set -l commands init auth kv space delegation share node profile completion
38352
38434
 
38353
38435
  # Disable file completion by default
38354
- complete -c ${CLI_NAME19} -f
38436
+ complete -c ${CLI_NAME20} -f
38355
38437
 
38356
38438
  # Top-level commands
38357
- complete -c ${CLI_NAME19} -n "not __fish_seen_subcommand_from $commands" -a init -d "Initialize a new TinyCloud profile"
38358
- complete -c ${CLI_NAME19} -n "not __fish_seen_subcommand_from $commands" -a auth -d "Authentication management"
38359
- complete -c ${CLI_NAME19} -n "not __fish_seen_subcommand_from $commands" -a kv -d "Key-value store operations"
38360
- complete -c ${CLI_NAME19} -n "not __fish_seen_subcommand_from $commands" -a space -d "Space management"
38361
- complete -c ${CLI_NAME19} -n "not __fish_seen_subcommand_from $commands" -a delegation -d "Manage delegations"
38362
- complete -c ${CLI_NAME19} -n "not __fish_seen_subcommand_from $commands" -a share -d "Share data with others"
38363
- complete -c ${CLI_NAME19} -n "not __fish_seen_subcommand_from $commands" -a node -d "Node health and info"
38364
- complete -c ${CLI_NAME19} -n "not __fish_seen_subcommand_from $commands" -a profile -d "Profile management"
38365
- complete -c ${CLI_NAME19} -n "not __fish_seen_subcommand_from $commands" -a completion -d "Generate shell completions"
38439
+ complete -c ${CLI_NAME20} -n "not __fish_seen_subcommand_from $commands" -a init -d "Initialize a new TinyCloud profile"
38440
+ complete -c ${CLI_NAME20} -n "not __fish_seen_subcommand_from $commands" -a auth -d "Authentication management"
38441
+ complete -c ${CLI_NAME20} -n "not __fish_seen_subcommand_from $commands" -a kv -d "Key-value store operations"
38442
+ complete -c ${CLI_NAME20} -n "not __fish_seen_subcommand_from $commands" -a space -d "Space management"
38443
+ complete -c ${CLI_NAME20} -n "not __fish_seen_subcommand_from $commands" -a delegation -d "Manage delegations"
38444
+ complete -c ${CLI_NAME20} -n "not __fish_seen_subcommand_from $commands" -a share -d "Share data with others"
38445
+ complete -c ${CLI_NAME20} -n "not __fish_seen_subcommand_from $commands" -a node -d "Node health and info"
38446
+ complete -c ${CLI_NAME20} -n "not __fish_seen_subcommand_from $commands" -a profile -d "Profile management"
38447
+ complete -c ${CLI_NAME20} -n "not __fish_seen_subcommand_from $commands" -a completion -d "Generate shell completions"
38366
38448
 
38367
38449
  # Subcommands
38368
- complete -c ${CLI_NAME19} -n "__fish_seen_subcommand_from auth" -a "login logout rotate status whoami"
38369
- complete -c ${CLI_NAME19} -n "__fish_seen_subcommand_from kv" -a "get put delete list head"
38370
- complete -c ${CLI_NAME19} -n "__fish_seen_subcommand_from space" -a "list create info switch"
38371
- complete -c ${CLI_NAME19} -n "__fish_seen_subcommand_from delegation" -a "create list info revoke"
38372
- complete -c ${CLI_NAME19} -n "__fish_seen_subcommand_from share" -a "create receive list revoke"
38373
- complete -c ${CLI_NAME19} -n "__fish_seen_subcommand_from node" -a "health version status"
38374
- complete -c ${CLI_NAME19} -n "__fish_seen_subcommand_from profile" -a "list create show switch delete"
38375
- complete -c ${CLI_NAME19} -n "__fish_seen_subcommand_from completion" -a "bash zsh fish"
38450
+ complete -c ${CLI_NAME20} -n "__fish_seen_subcommand_from auth" -a "login logout rotate status whoami"
38451
+ complete -c ${CLI_NAME20} -n "__fish_seen_subcommand_from kv" -a "get put delete list head"
38452
+ complete -c ${CLI_NAME20} -n "__fish_seen_subcommand_from space" -a "list create info switch"
38453
+ complete -c ${CLI_NAME20} -n "__fish_seen_subcommand_from delegation" -a "create list info revoke"
38454
+ complete -c ${CLI_NAME20} -n "__fish_seen_subcommand_from share" -a "create receive list revoke"
38455
+ complete -c ${CLI_NAME20} -n "__fish_seen_subcommand_from node" -a "health version status"
38456
+ complete -c ${CLI_NAME20} -n "__fish_seen_subcommand_from profile" -a "list create show switch delete"
38457
+ complete -c ${CLI_NAME20} -n "__fish_seen_subcommand_from completion" -a "bash zsh fish"
38376
38458
 
38377
38459
  # Global options
38378
- complete -c ${CLI_NAME19} -l profile -s p -d "Profile to use"
38379
- complete -c ${CLI_NAME19} -l host -s H -d "TinyCloud node URL"
38380
- complete -c ${CLI_NAME19} -l verbose -s v -d "Enable verbose output"
38381
- complete -c ${CLI_NAME19} -l no-cache -d "Disable caching"
38382
- complete -c ${CLI_NAME19} -l quiet -s q -d "Suppress non-essential output"
38383
- complete -c ${CLI_NAME19} -l replication -d "Enable read-through replication"
38384
- complete -c ${CLI_NAME19} -l no-replication -d "Disable replication"
38385
- complete -c ${CLI_NAME19} -l replication-debug -d "Write replication diagnostics to stderr"
38460
+ complete -c ${CLI_NAME20} -l profile -s p -d "Profile to use"
38461
+ complete -c ${CLI_NAME20} -l host -s H -d "TinyCloud node URL"
38462
+ complete -c ${CLI_NAME20} -l verbose -s v -d "Enable verbose output"
38463
+ complete -c ${CLI_NAME20} -l no-cache -d "Disable caching"
38464
+ complete -c ${CLI_NAME20} -l quiet -s q -d "Suppress non-essential output"
38465
+ complete -c ${CLI_NAME20} -l replication -d "Enable read-through replication"
38466
+ complete -c ${CLI_NAME20} -l no-replication -d "Disable replication"
38467
+ complete -c ${CLI_NAME20} -l replication-debug -d "Write replication diagnostics to stderr"
38386
38468
  `;
38387
38469
  }
38388
38470
 
38389
38471
  // src/commands/courier.ts
38390
- import { CLI_NAME as CLI_NAME20 } from "@tinycloud/operations/cli-name";
38391
- var TC_OPTIONS_BEFORE_COURIER = `${CLI_NAME20} courier takes no ${CLI_NAME20} options and does not use ${CLI_NAME20} profiles; Courier keeps its own profile in $COURIER_HOME (default ~/.courier). Put flags after "courier", e.g. ${CLI_NAME20} courier init --host <url>.`;
38472
+ import { CLI_NAME as CLI_NAME21 } from "@tinycloud/operations/cli-name";
38473
+ var TC_OPTIONS_BEFORE_COURIER = `${CLI_NAME21} courier takes no ${CLI_NAME21} options and does not use ${CLI_NAME21} profiles; Courier keeps its own profile in $COURIER_HOME (default ~/.courier). Put flags after "courier", e.g. ${CLI_NAME21} courier init --host <url>.`;
38392
38474
  function registerCourierCommand(program) {
38393
- const courier = program.command("courier").description(`Agent-to-agent threads over TinyCloud; run \`${CLI_NAME20} courier --help\` (beta)`).argument("[args...]").allowUnknownOption().helpOption(false);
38475
+ const courier = program.command("courier").description(`Agent-to-agent threads over TinyCloud; run \`${CLI_NAME21} courier --help\` (beta)`).argument("[args...]").allowUnknownOption().helpOption(false);
38394
38476
  courier.action(() => courier.error(TC_OPTIONS_BEFORE_COURIER, { exitCode: 2, code: "tc.courier.options" }));
38395
38477
  }
38396
38478
 
@@ -38435,7 +38517,7 @@ init_formatter();
38435
38517
  init_errors();
38436
38518
  init_constants();
38437
38519
  init_sdk();
38438
- import { CLI_NAME as CLI_NAME21 } from "@tinycloud/operations/cli-name";
38520
+ import { CLI_NAME as CLI_NAME22 } from "@tinycloud/operations/cli-name";
38439
38521
  import { PermissionNotInManifestError } from "@tinycloud/node-sdk";
38440
38522
  async function queryDelegations(node, options, until) {
38441
38523
  const found = [];
@@ -38446,7 +38528,7 @@ async function queryDelegations(node, options, until) {
38446
38528
  if (page.error.code === "PERMISSION_DENIED") {
38447
38529
  throw new CLIError(
38448
38530
  "PERMISSION_DENIED",
38449
- `This session cannot read delegations: it lacks tinycloud.delegation/list. Run \`${CLI_NAME21} auth login\` again to grant it.`,
38531
+ `This session cannot read delegations: it lacks tinycloud.delegation/list. Run \`${CLI_NAME22} auth login\` again to grant it.`,
38450
38532
  ExitCode.PERMISSION_DENIED
38451
38533
  );
38452
38534
  }
@@ -38509,7 +38591,7 @@ async function revokeIssuedDelegation(node, ctx, cid) {
38509
38591
  ExitCode.PERMISSION_DENIED,
38510
38592
  {
38511
38593
  status: result.error.meta?.status,
38512
- hint: `A profile can revoke only the delegations its own key issued. See them with \`${CLI_NAME21} --profile ${ctx.profile} delegation list --granted\`.`
38594
+ hint: `A profile can revoke only the delegations its own key issued. See them with \`${CLI_NAME22} --profile ${ctx.profile} delegation list --granted\`.`
38513
38595
  }
38514
38596
  );
38515
38597
  }
@@ -38682,7 +38764,7 @@ init_constants();
38682
38764
  init_formatter();
38683
38765
  init_theme();
38684
38766
  init_errors();
38685
- import { CLI_NAME as CLI_NAME22 } from "@tinycloud/operations/cli-name";
38767
+ import { CLI_NAME as CLI_NAME23 } from "@tinycloud/operations/cli-name";
38686
38768
  init_session_expired();
38687
38769
  init_types();
38688
38770
  function registerDoctorCommand(program) {
@@ -38716,7 +38798,7 @@ function registerDoctorCommand(program) {
38716
38798
  const profile = await ProfileManager.getProfile(profileName2);
38717
38799
  keyDetail = profile.did ? `${profile.did.slice(0, 20)}...` : "key found";
38718
38800
  } else {
38719
- keyDetail = `no key \u2014 run ${CLI_NAME22} init`;
38801
+ keyDetail = `no key \u2014 run ${CLI_NAME23} init`;
38720
38802
  }
38721
38803
  } catch {
38722
38804
  keyDetail = "error reading key";
@@ -38738,7 +38820,7 @@ function registerDoctorCommand(program) {
38738
38820
  } else if (state2 === "unverified") {
38739
38821
  sessionDetail = `not usable (no signed OpenKey proof) \u2014 ${signInAgainHint(profileName2, resolveProfilePosture(profile))}`;
38740
38822
  } else {
38741
- sessionDetail = sessionOk ? "active" : `no session \u2014 run ${CLI_NAME22} auth login`;
38823
+ sessionDetail = sessionOk ? "active" : `no session \u2014 run ${CLI_NAME23} auth login`;
38742
38824
  }
38743
38825
  } catch {
38744
38826
  sessionDetail = "error reading session";
@@ -38766,7 +38848,7 @@ function registerDoctorCommand(program) {
38766
38848
  try {
38767
38849
  const profile = await ProfileManager.getProfile(profileName2);
38768
38850
  spaceOk = Boolean(profile.spaceId);
38769
- spaceDetail = spaceOk ? `${profile.spaceId.slice(0, 16)}...` : `no space \u2014 run ${CLI_NAME22} space create`;
38851
+ spaceDetail = spaceOk ? `${profile.spaceId.slice(0, 16)}...` : `no space \u2014 run ${CLI_NAME23} space create`;
38770
38852
  } catch {
38771
38853
  spaceDetail = "error checking space";
38772
38854
  }
@@ -38956,7 +39038,7 @@ ${rowCount} row${rowCount === 1 ? "" : "s"} returned`) + "\n");
38956
39038
  }
38957
39039
 
38958
39040
  // src/commands/enable.ts
38959
- import { CLI_NAME as CLI_NAME23 } from "@tinycloud/operations/cli-name";
39041
+ import { CLI_NAME as CLI_NAME24 } from "@tinycloud/operations/cli-name";
38960
39042
  init_constants();
38961
39043
  init_profiles();
38962
39044
  init_errors();
@@ -38964,7 +39046,7 @@ init_formatter();
38964
39046
  init_publishing_manifest();
38965
39047
  function registerEnableCommand(program) {
38966
39048
  const enable = program.command("enable").description("Enable a narrowly scoped TinyCloud service");
38967
- enable.command("share").description(`Approve Share publishing scope through OpenKey device authorization (same as \`${CLI_NAME23} auth login --device --manifest builtin:share-publishing\`). Use a dedicated profile, e.g. \`${CLI_NAME23} init --name publisher --key-only && ${CLI_NAME23} --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) => {
39049
+ enable.command("share").description(`Approve Share publishing scope through OpenKey device authorization (same as \`${CLI_NAME24} auth login --device --manifest builtin:share-publishing\`). Use a dedicated profile, e.g. \`${CLI_NAME24} init --name publisher --key-only && ${CLI_NAME24} --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) => {
38968
39050
  try {
38969
39051
  const globalOptions = command.optsWithGlobals();
38970
39052
  const context2 = await ProfileManager.resolveContext(globalOptions, { storedSession: "unused" });
@@ -38999,7 +39081,7 @@ function registerEnableCommand(program) {
38999
39081
  init_profiles();
39000
39082
  init_constants();
39001
39083
  init_sdk();
39002
- import { CLI_NAME as CLI_NAME24 } from "@tinycloud/operations/cli-name";
39084
+ import { CLI_NAME as CLI_NAME25 } from "@tinycloud/operations/cli-name";
39003
39085
  import { operationSpaceResolver as operationSpaceResolver2 } from "@tinycloud/operations/delegation-binding";
39004
39086
 
39005
39087
  // src/lib/knowledge-input.ts
@@ -39265,7 +39347,7 @@ function registerAppsCommand(program) {
39265
39347
  "after",
39266
39348
  `
39267
39349
  Examples:
39268
- $ ${CLI_NAME24} apps install xyz.tinycloud.sample.healthlog
39350
+ $ ${CLI_NAME25} apps install xyz.tinycloud.sample.healthlog
39269
39351
  `
39270
39352
  ).action(async (appIdInput, _options, cmd) => {
39271
39353
  try {
@@ -40355,81 +40437,6 @@ slash prefix and output are explicit; source get/sync grants are separate from f
40355
40437
  });
40356
40438
  }
40357
40439
 
40358
- // src/commands/init.ts
40359
- init_profiles();
40360
- init_formatter();
40361
- init_errors();
40362
- init_constants();
40363
- import { CLI_NAME as CLI_NAME25 } from "@tinycloud/operations/cli-name";
40364
- async function createKeyOnlyProfile(profileName2, host, defaultSpace) {
40365
- await ProfileManager.ensureConfigDir();
40366
- const { jwk, did } = await generateKey2();
40367
- await ProfileManager.setKey(profileName2, jwk);
40368
- await ProfileManager.setProfile(profileName2, {
40369
- name: profileName2,
40370
- host,
40371
- chainId: DEFAULT_CHAIN_ID,
40372
- spaceName: "default",
40373
- did,
40374
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
40375
- ...defaultSpace ? { defaultSpace } : {}
40376
- });
40377
- const config = await ProfileManager.getConfig();
40378
- if (profileName2 === "default" || !await ProfileManager.profileExists(config.defaultProfile)) {
40379
- await ProfileManager.setConfig({ ...config, defaultProfile: profileName2 });
40380
- }
40381
- return { did };
40382
- }
40383
- function registerInitCommand(program) {
40384
- 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) => {
40385
- try {
40386
- const globalOpts = cmd.optsWithGlobals();
40387
- const profileName2 = options.name;
40388
- const host = options.host ?? globalOpts.host ?? DEFAULT_HOST;
40389
- const defaultSpace = options.defaultSpace;
40390
- if (defaultSpace !== void 0 && !/^[A-Za-z0-9_-]+$/.test(defaultSpace)) {
40391
- throw new CLIError(
40392
- "INVALID_SPACE",
40393
- `Invalid --default-space "${defaultSpace}". Use a short name ([A-Za-z0-9_-]).`,
40394
- ExitCode.USAGE_ERROR
40395
- );
40396
- }
40397
- if (await ProfileManager.profileExists(profileName2)) {
40398
- throw new CLIError(
40399
- "PROFILE_EXISTS",
40400
- `Profile "${profileName2}" already exists. Use \`${CLI_NAME25} profile delete ${profileName2}\` first or choose a different name.`,
40401
- ExitCode.ERROR
40402
- );
40403
- }
40404
- const { did } = await withSpinner("Generating key...", () => createKeyOnlyProfile(profileName2, host, defaultSpace));
40405
- if (options.keyOnly) {
40406
- outputJson({
40407
- profile: profileName2,
40408
- did,
40409
- host,
40410
- authenticated: false
40411
- });
40412
- return;
40413
- }
40414
- const { delegationData } = await refreshOpenKeySession(profileName2, host, {
40415
- paste: options.paste,
40416
- noPopup: options.popup === false,
40417
- persistHost: true
40418
- });
40419
- await ensureSpaceSetup({ profile: profileName2, host }, delegationData, delegationData.permissions);
40420
- outputJson({
40421
- profile: profileName2,
40422
- did,
40423
- host,
40424
- spaceId: delegationData.spaceId,
40425
- authenticated: true
40426
- });
40427
- } catch (error) {
40428
- return handleError(error);
40429
- }
40430
- });
40431
- }
40432
-
40433
40440
  // src/commands/knowledge.ts
40434
40441
  init_session_expired();
40435
40442
  init_constants();