@tinycloud/cli 0.7.0-beta.22 → 0.7.0-beta.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import "./chunk-5CWOI54E.js";
2
- import "./chunk-43OSAOIQ.js";
1
+ import "./chunk-TWMXCCSD.js";
2
+ import "./chunk-725HE3UG.js";
3
3
  import {
4
4
  __commonJS,
5
5
  __esm,
@@ -5988,9 +5988,9 @@ var require_node_exports = __commonJS({
5988
5988
  }
5989
5989
  });
5990
5990
 
5991
- // ../../node_modules/@spruceid/siwe-parser/node_modules/@noble/hashes/_u64.js
5991
+ // ../../node_modules/@noble/hashes/_u64.js
5992
5992
  var require_u64 = __commonJS({
5993
- "../../node_modules/@spruceid/siwe-parser/node_modules/@noble/hashes/_u64.js"(exports) {
5993
+ "../../node_modules/@noble/hashes/_u64.js"(exports) {
5994
5994
  "use strict";
5995
5995
  Object.defineProperty(exports, "__esModule", { value: true });
5996
5996
  exports.toBig = exports.shrSL = exports.shrSH = exports.rotrSL = exports.rotrSH = exports.rotrBL = exports.rotrBH = exports.rotr32L = exports.rotr32H = exports.rotlSL = exports.rotlSH = exports.rotlBL = exports.rotlBH = exports.add5L = exports.add5H = exports.add4L = exports.add4H = exports.add3L = exports.add3H = void 0;
@@ -6084,9 +6084,9 @@ var require_u64 = __commonJS({
6084
6084
  }
6085
6085
  });
6086
6086
 
6087
- // ../../node_modules/@spruceid/siwe-parser/node_modules/@noble/hashes/cryptoNode.js
6087
+ // ../../node_modules/@noble/hashes/cryptoNode.js
6088
6088
  var require_cryptoNode = __commonJS({
6089
- "../../node_modules/@spruceid/siwe-parser/node_modules/@noble/hashes/cryptoNode.js"(exports) {
6089
+ "../../node_modules/@noble/hashes/cryptoNode.js"(exports) {
6090
6090
  "use strict";
6091
6091
  Object.defineProperty(exports, "__esModule", { value: true });
6092
6092
  exports.crypto = void 0;
@@ -6095,9 +6095,9 @@ var require_cryptoNode = __commonJS({
6095
6095
  }
6096
6096
  });
6097
6097
 
6098
- // ../../node_modules/@spruceid/siwe-parser/node_modules/@noble/hashes/utils.js
6098
+ // ../../node_modules/@noble/hashes/utils.js
6099
6099
  var require_utils = __commonJS({
6100
- "../../node_modules/@spruceid/siwe-parser/node_modules/@noble/hashes/utils.js"(exports) {
6100
+ "../../node_modules/@noble/hashes/utils.js"(exports) {
6101
6101
  "use strict";
6102
6102
  Object.defineProperty(exports, "__esModule", { value: true });
6103
6103
  exports.wrapXOFConstructorWithOpts = exports.wrapConstructorWithOpts = exports.wrapConstructor = exports.Hash = exports.nextTick = exports.swap32IfBE = exports.byteSwapIfBE = exports.swap8IfBE = exports.isLE = void 0;
@@ -6337,9 +6337,9 @@ var require_utils = __commonJS({
6337
6337
  }
6338
6338
  });
6339
6339
 
6340
- // ../../node_modules/@spruceid/siwe-parser/node_modules/@noble/hashes/sha3.js
6340
+ // ../../node_modules/@noble/hashes/sha3.js
6341
6341
  var require_sha3 = __commonJS({
6342
- "../../node_modules/@spruceid/siwe-parser/node_modules/@noble/hashes/sha3.js"(exports) {
6342
+ "../../node_modules/@noble/hashes/sha3.js"(exports) {
6343
6343
  "use strict";
6344
6344
  Object.defineProperty(exports, "__esModule", { value: true });
6345
6345
  exports.shake256 = exports.shake128 = exports.keccak_512 = exports.keccak_384 = exports.keccak_256 = exports.keccak_224 = exports.sha3_512 = exports.sha3_384 = exports.sha3_256 = exports.sha3_224 = exports.Keccak = void 0;
@@ -32317,81 +32317,6 @@ Open this URL in a browser to authenticate:
32317
32317
  });
32318
32318
  }
32319
32319
 
32320
- // src/commands/init.ts
32321
- function registerInitCommand(program2) {
32322
- program2.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) => {
32323
- try {
32324
- const globalOpts = cmd.optsWithGlobals();
32325
- const profileName = options.name;
32326
- const host = options.host ?? globalOpts.host ?? DEFAULT_HOST;
32327
- const defaultSpace = options.defaultSpace;
32328
- if (defaultSpace !== void 0 && !/^[A-Za-z0-9_-]+$/.test(defaultSpace)) {
32329
- throw new CLIError(
32330
- "INVALID_SPACE",
32331
- `Invalid --default-space "${defaultSpace}". Use a short name ([A-Za-z0-9_-]).`,
32332
- ExitCode.USAGE_ERROR
32333
- );
32334
- }
32335
- if (await ProfileManager.profileExists(profileName)) {
32336
- throw new CLIError(
32337
- "PROFILE_EXISTS",
32338
- `Profile "${profileName}" already exists. Use \`tc profile delete ${profileName}\` first or choose a different name.`,
32339
- ExitCode.ERROR
32340
- );
32341
- }
32342
- await ProfileManager.ensureConfigDir();
32343
- const { jwk, did } = await withSpinner("Generating key...", async () => {
32344
- return generateKey();
32345
- });
32346
- await ProfileManager.setKey(profileName, jwk);
32347
- const profileConfig = {
32348
- name: profileName,
32349
- host,
32350
- chainId: DEFAULT_CHAIN_ID,
32351
- spaceName: "default",
32352
- did,
32353
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
32354
- ...defaultSpace ? { defaultSpace } : {}
32355
- };
32356
- await ProfileManager.setProfile(profileName, profileConfig);
32357
- const config = await ProfileManager.getConfig();
32358
- if (profileName === "default" || !await ProfileManager.profileExists(config.defaultProfile)) {
32359
- await ProfileManager.setConfig({ ...config, defaultProfile: profileName });
32360
- }
32361
- if (options.keyOnly) {
32362
- outputJson({
32363
- profile: profileName,
32364
- did,
32365
- host,
32366
- authenticated: false
32367
- });
32368
- return;
32369
- }
32370
- const delegationData = await startAuthFlow(did, {
32371
- paste: options.paste,
32372
- noPopup: options.popup === false,
32373
- jwk,
32374
- host
32375
- });
32376
- await ProfileManager.setSession(profileName, delegationData);
32377
- await ProfileManager.setProfile(profileName, {
32378
- ...profileConfig,
32379
- spaceId: delegationData.spaceId,
32380
- ownerDid: delegationData.ownerDid
32381
- });
32382
- outputJson({
32383
- profile: profileName,
32384
- did,
32385
- host,
32386
- spaceId: delegationData.spaceId,
32387
- authenticated: true
32388
- });
32389
- } catch (error) {
32390
- handleError(error);
32391
- }
32392
- });
32393
- }
32394
-
32395
32320
  // src/commands/auth.ts
32396
32321
  import { get as httpGet } from "http";
32397
32322
  import { get as httpsGet } from "https";
@@ -42923,6 +42848,17 @@ function serviceFromActions(actions) {
42923
42848
  }
42924
42849
 
42925
42850
  // src/lib/sdk.ts
42851
+ function jwkHasPrivateParameter(jwk) {
42852
+ if (!jwk || typeof jwk !== "object") return false;
42853
+ const d = jwk.d;
42854
+ return typeof d === "string" && d.length > 0;
42855
+ }
42856
+ function selectSignerJwk(sessionJwk, key2) {
42857
+ if (jwkHasPrivateParameter(sessionJwk)) {
42858
+ return sessionJwk;
42859
+ }
42860
+ return key2 ?? void 0;
42861
+ }
42926
42862
  async function createSDKInstance(ctx, options) {
42927
42863
  const profile = options?.privateKey ? await ProfileManager.getProfile(ctx.profile).catch(() => null) : await ProfileManager.getProfile(ctx.profile);
42928
42864
  const session = await ProfileManager.getSession(ctx.profile);
@@ -42945,7 +42881,7 @@ async function createSDKInstance(ctx, options) {
42945
42881
  delegationHeader: session.delegationHeader,
42946
42882
  delegationCid: session.delegationCid,
42947
42883
  spaceId: session.spaceId,
42948
- jwk: session.jwk ?? key2,
42884
+ jwk: selectSignerJwk(session.jwk, key2),
42949
42885
  verificationMethod: session.verificationMethod ?? profile?.sessionDid ?? profile?.did,
42950
42886
  address: session.address,
42951
42887
  chainId: session.chainId,
@@ -42969,7 +42905,7 @@ async function createSDKInstance(ctx, options) {
42969
42905
  delegationHeader: session.delegationHeader,
42970
42906
  delegationCid: session.delegationCid,
42971
42907
  spaceId: session.spaceId,
42972
- jwk: session.jwk ?? key2,
42908
+ jwk: selectSignerJwk(session.jwk, key2),
42973
42909
  verificationMethod: session.verificationMethod ?? profile?.did,
42974
42910
  address: session.address,
42975
42911
  chainId: session.chainId,
@@ -43982,6 +43918,25 @@ async function handleOpenKeyAuth(profileName, host, options = {}) {
43982
43918
  authMethod: "openkey"
43983
43919
  });
43984
43920
  }
43921
+ function mergePrivateJwkIntoSession(session, key2) {
43922
+ const sessionJwk = session.jwk;
43923
+ if (!sessionJwk || typeof sessionJwk !== "object") {
43924
+ return session;
43925
+ }
43926
+ const sessionJwkRecord = sessionJwk;
43927
+ const sessionD = sessionJwkRecord.d;
43928
+ if (typeof sessionD === "string" && sessionD.length > 0) {
43929
+ return session;
43930
+ }
43931
+ const keyD = key2.d;
43932
+ if (typeof keyD !== "string" || keyD.length === 0) {
43933
+ return session;
43934
+ }
43935
+ return {
43936
+ ...session,
43937
+ jwk: { ...sessionJwkRecord, d: keyD }
43938
+ };
43939
+ }
43985
43940
  async function refreshOpenKeySession(profileName, host, options = {}) {
43986
43941
  const key2 = await ProfileManager.getKey(profileName);
43987
43942
  if (!key2) {
@@ -43999,7 +43954,8 @@ async function refreshOpenKeySession(profileName, host, options = {}) {
43999
43954
  host,
44000
43955
  openkeyHost: resolveOpenKeyHost(profile)
44001
43956
  });
44002
- await ProfileManager.setSession(profileName, delegationData);
43957
+ const sanitizedSession = mergePrivateJwkIntoSession(delegationData, key2);
43958
+ await ProfileManager.setSession(profileName, sanitizedSession);
44003
43959
  const updatedProfile = {
44004
43960
  ...profile,
44005
43961
  sessionDid: profile.sessionDid ?? profile.did,
@@ -44007,12 +43963,88 @@ async function refreshOpenKeySession(profileName, host, options = {}) {
44007
43963
  operatorType: profile.operatorType ?? "human",
44008
43964
  authMethod: "openkey"
44009
43965
  };
44010
- if (delegationData.spaceId) {
44011
- updatedProfile.spaceId = delegationData.spaceId;
44012
- updatedProfile.ownerDid = delegationData.ownerDid;
43966
+ if (sanitizedSession.spaceId) {
43967
+ updatedProfile.spaceId = sanitizedSession.spaceId;
43968
+ updatedProfile.ownerDid = sanitizedSession.ownerDid;
44013
43969
  }
44014
43970
  await ProfileManager.setProfile(profileName, updatedProfile);
44015
- return { profile: updatedProfile, delegationData };
43971
+ return { profile: updatedProfile, delegationData: sanitizedSession };
43972
+ }
43973
+
43974
+ // src/commands/init.ts
43975
+ function registerInitCommand(program2) {
43976
+ program2.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) => {
43977
+ try {
43978
+ const globalOpts = cmd.optsWithGlobals();
43979
+ const profileName = options.name;
43980
+ const host = options.host ?? globalOpts.host ?? DEFAULT_HOST;
43981
+ const defaultSpace = options.defaultSpace;
43982
+ if (defaultSpace !== void 0 && !/^[A-Za-z0-9_-]+$/.test(defaultSpace)) {
43983
+ throw new CLIError(
43984
+ "INVALID_SPACE",
43985
+ `Invalid --default-space "${defaultSpace}". Use a short name ([A-Za-z0-9_-]).`,
43986
+ ExitCode.USAGE_ERROR
43987
+ );
43988
+ }
43989
+ if (await ProfileManager.profileExists(profileName)) {
43990
+ throw new CLIError(
43991
+ "PROFILE_EXISTS",
43992
+ `Profile "${profileName}" already exists. Use \`tc profile delete ${profileName}\` first or choose a different name.`,
43993
+ ExitCode.ERROR
43994
+ );
43995
+ }
43996
+ await ProfileManager.ensureConfigDir();
43997
+ const { jwk, did } = await withSpinner("Generating key...", async () => {
43998
+ return generateKey();
43999
+ });
44000
+ await ProfileManager.setKey(profileName, jwk);
44001
+ const profileConfig = {
44002
+ name: profileName,
44003
+ host,
44004
+ chainId: DEFAULT_CHAIN_ID,
44005
+ spaceName: "default",
44006
+ did,
44007
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
44008
+ ...defaultSpace ? { defaultSpace } : {}
44009
+ };
44010
+ await ProfileManager.setProfile(profileName, profileConfig);
44011
+ const config = await ProfileManager.getConfig();
44012
+ if (profileName === "default" || !await ProfileManager.profileExists(config.defaultProfile)) {
44013
+ await ProfileManager.setConfig({ ...config, defaultProfile: profileName });
44014
+ }
44015
+ if (options.keyOnly) {
44016
+ outputJson({
44017
+ profile: profileName,
44018
+ did,
44019
+ host,
44020
+ authenticated: false
44021
+ });
44022
+ return;
44023
+ }
44024
+ const delegationData = await startAuthFlow(did, {
44025
+ paste: options.paste,
44026
+ noPopup: options.popup === false,
44027
+ jwk,
44028
+ host
44029
+ });
44030
+ const sanitizedSession = mergePrivateJwkIntoSession(delegationData, jwk);
44031
+ await ProfileManager.setSession(profileName, sanitizedSession);
44032
+ await ProfileManager.setProfile(profileName, {
44033
+ ...profileConfig,
44034
+ spaceId: sanitizedSession.spaceId,
44035
+ ownerDid: sanitizedSession.ownerDid
44036
+ });
44037
+ outputJson({
44038
+ profile: profileName,
44039
+ did,
44040
+ host,
44041
+ spaceId: sanitizedSession.spaceId,
44042
+ authenticated: true
44043
+ });
44044
+ } catch (error) {
44045
+ handleError(error);
44046
+ }
44047
+ });
44016
44048
  }
44017
44049
 
44018
44050
  // src/commands/kv.ts
@@ -45245,8 +45277,11 @@ function authOptions(options) {
45245
45277
  return privateKey ? { privateKey } : void 0;
45246
45278
  }
45247
45279
  function resolveSecretScope(options) {
45248
- const scope = options.scope ?? options.space;
45249
- return scope ? { scope } : void 0;
45280
+ return options.scope ? { scope: options.scope } : void 0;
45281
+ }
45282
+ function resolveSecretsSpace(options) {
45283
+ const space = options.space?.trim();
45284
+ return space && space.length > 0 ? space : SECRETS_SPACE2;
45250
45285
  }
45251
45286
  var SECRET_NAME_RE2 = /^[A-Z][A-Z0-9_]*$/;
45252
45287
  var RESERVED_SECRET_SCOPES2 = /* @__PURE__ */ new Set(["default", "global"]);
@@ -45335,6 +45370,7 @@ async function runSecretOperation(params) {
45335
45370
  action: params.action,
45336
45371
  name: params.name,
45337
45372
  options: params.scopeOptions,
45373
+ space: params.space,
45338
45374
  node: params.node
45339
45375
  });
45340
45376
  await withSpinner(
@@ -45712,7 +45748,7 @@ function secretPermissionEntries(params) {
45712
45748
  const path = params.action === "list" ? resolveSecretListPrefix(params.options) : resolveSecretPath2(params.name ?? "", params.options).permissionPaths.vault;
45713
45749
  const permissions = [{
45714
45750
  service: "tinycloud.kv",
45715
- space: SECRETS_SPACE2,
45751
+ space: params.space ?? SECRETS_SPACE2,
45716
45752
  path,
45717
45753
  actions: [secretKvAbility(params.action)],
45718
45754
  skipPrefix: true
@@ -45792,7 +45828,7 @@ function registerSecretsCommand(program2) {
45792
45828
  handleError(error);
45793
45829
  }
45794
45830
  });
45795
- secrets.command("doctor [name]").description("Check secrets setup and optional secret access").option("--scope <scope>", "Logical secret scope").option("--space <scope>", "Deprecated alias for --scope").option("--network <name>", "Encryption network name", "default").option("--private-key <hex>", "Ethereum private key (or set TC_PRIVATE_KEY)").action(async (name2, options, cmd) => {
45831
+ secrets.command("doctor [name]").description("Check secrets setup and optional secret access").option("--scope <scope>", "Logical secret scope").option("--space <space>", 'Override the secrets space (defaults to "secrets")').option("--network <name>", "Encryption network name", "default").option("--private-key <hex>", "Ethereum private key (or set TC_PRIVATE_KEY)").action(async (name2, options, cmd) => {
45796
45832
  try {
45797
45833
  const globalOpts = cmd.optsWithGlobals();
45798
45834
  const ctx = await ProfileManager.resolveContext(globalOpts);
@@ -45818,6 +45854,7 @@ function registerSecretsCommand(program2) {
45818
45854
  let secret;
45819
45855
  if (name2) {
45820
45856
  const scopeOptions = resolveSecretScope(options);
45857
+ const space = resolveSecretsSpace(options);
45821
45858
  const resolved = resolveSecretPath2(name2, scopeOptions);
45822
45859
  const result = await runSecretOperation({
45823
45860
  ctx,
@@ -45825,6 +45862,7 @@ function registerSecretsCommand(program2) {
45825
45862
  action: "get",
45826
45863
  name: name2,
45827
45864
  scopeOptions,
45865
+ space,
45828
45866
  label: `Checking secret ${name2}...`,
45829
45867
  operation: () => node.secrets.get(name2, scopeOptions)
45830
45868
  });
@@ -45879,17 +45917,19 @@ function registerSecretsCommand(program2) {
45879
45917
  handleError(error);
45880
45918
  }
45881
45919
  });
45882
- secrets.command("list").description("List secrets").option("--scope <scope>", "Logical secret scope").option("--space <scope>", "Deprecated alias for --scope").option("--private-key <hex>", "Ethereum private key (or set TC_PRIVATE_KEY)").action(async (options, cmd) => {
45920
+ secrets.command("list").description("List secrets").option("--scope <scope>", "Logical secret scope").option("--space <space>", 'Override the secrets space (defaults to "secrets")').option("--private-key <hex>", "Ethereum private key (or set TC_PRIVATE_KEY)").action(async (options, cmd) => {
45883
45921
  try {
45884
45922
  const globalOpts = cmd.optsWithGlobals();
45885
45923
  const ctx = await ProfileManager.resolveContext(globalOpts);
45886
45924
  const node = await ensureSecretsNode(ctx, options);
45887
45925
  const scopeOptions = resolveSecretScope(options);
45926
+ const space = resolveSecretsSpace(options);
45888
45927
  const result = await runSecretOperation({
45889
45928
  ctx,
45890
45929
  node,
45891
45930
  action: "list",
45892
45931
  scopeOptions,
45932
+ space,
45893
45933
  label: "Listing secrets...",
45894
45934
  operation: () => node.secrets.list(scopeOptions)
45895
45935
  });
@@ -45897,21 +45937,21 @@ function registerSecretsCommand(program2) {
45897
45937
  throw new CLIError(result.error.code, result.error.message, ExitCode.ERROR);
45898
45938
  }
45899
45939
  const secretNames = Array.isArray(result.data) ? result.data : [];
45900
- const scope = options.scope ?? options.space;
45901
45940
  outputJson({
45902
45941
  secrets: secretNames,
45903
45942
  count: secretNames.length,
45904
- ...scope ? { scope } : {}
45943
+ ...options.scope ? { scope: options.scope } : {}
45905
45944
  });
45906
45945
  } catch (error) {
45907
45946
  handleError(error);
45908
45947
  }
45909
45948
  });
45910
- secrets.command("get <name>").description("Get a secret value").option("--scope <scope>", "Logical secret scope").option("--space <scope>", "Deprecated alias for --scope").option("--raw", "Output raw value (no JSON wrapping)").option("--value-only", "Output only the secret value (alias for --raw)").option("-o, --output <file>", "Write value to file").option("--delegation <source>", "Delegation file path or imported profile name").option("--private-key <hex>", "Ethereum private key (or set TC_PRIVATE_KEY)").action(async (name2, options, cmd) => {
45949
+ secrets.command("get <name>").description("Get a secret value").option("--scope <scope>", "Logical secret scope").option("--space <space>", 'Override the secrets space (defaults to "secrets")').option("--raw", "Output raw value (no JSON wrapping)").option("--value-only", "Output only the secret value (alias for --raw)").option("-o, --output <file>", "Write value to file").option("--delegation <source>", "Delegation file path or imported profile name").option("--private-key <hex>", "Ethereum private key (or set TC_PRIVATE_KEY)").action(async (name2, options, cmd) => {
45911
45950
  try {
45912
45951
  const globalOpts = cmd.optsWithGlobals();
45913
45952
  const ctx = await ProfileManager.resolveContext(globalOpts);
45914
45953
  const scopeOptions = resolveSecretScope(options);
45954
+ const space = resolveSecretsSpace(options);
45915
45955
  const secretPath = resolveSecretPath2(name2, scopeOptions).permissionPaths.vault;
45916
45956
  if (options.delegation) {
45917
45957
  const delegated = await resolveDelegatedSecretSource(options.delegation, secretPath);
@@ -45948,6 +45988,7 @@ function registerSecretsCommand(program2) {
45948
45988
  action: "get",
45949
45989
  name: name2,
45950
45990
  scopeOptions,
45991
+ space,
45951
45992
  label: `Getting secret ${name2}...`,
45952
45993
  operation: () => node.secrets.get(name2, scopeOptions)
45953
45994
  });
@@ -45972,7 +46013,7 @@ function registerSecretsCommand(program2) {
45972
46013
  handleError(error);
45973
46014
  }
45974
46015
  });
45975
- secrets.command("put <name> [value]").description("Store a secret").option("--scope <scope>", "Logical secret scope").option("--space <scope>", "Deprecated alias for --scope").option("--file <path>", "Read value from file").option("--stdin", "Read value from stdin").option("--private-key <hex>", "Ethereum private key (or set TC_PRIVATE_KEY)").action(async (name2, value, options, cmd) => {
46016
+ secrets.command("put <name> [value]").description("Store a secret").option("--scope <scope>", "Logical secret scope").option("--space <space>", 'Override the secrets space (defaults to "secrets")').option("--file <path>", "Read value from file").option("--stdin", "Read value from stdin").option("--private-key <hex>", "Ethereum private key (or set TC_PRIVATE_KEY)").action(async (name2, value, options, cmd) => {
45976
46017
  try {
45977
46018
  const globalOpts = cmd.optsWithGlobals();
45978
46019
  const ctx = await ProfileManager.resolveContext(globalOpts);
@@ -45993,12 +46034,14 @@ function registerSecretsCommand(program2) {
45993
46034
  secretValue = value;
45994
46035
  }
45995
46036
  const scopeOptions = resolveSecretScope(options);
46037
+ const space = resolveSecretsSpace(options);
45996
46038
  const result = await runSecretOperation({
45997
46039
  ctx,
45998
46040
  node,
45999
46041
  action: "put",
46000
46042
  name: name2,
46001
46043
  scopeOptions,
46044
+ space,
46002
46045
  label: `Storing secret ${name2}...`,
46003
46046
  operation: () => node.secrets.put(name2, secretValue, scopeOptions)
46004
46047
  });
@@ -46010,18 +46053,20 @@ function registerSecretsCommand(program2) {
46010
46053
  handleError(error);
46011
46054
  }
46012
46055
  });
46013
- secrets.command("delete <name>").description("Delete a secret").option("--scope <scope>", "Logical secret scope").option("--space <scope>", "Deprecated alias for --scope").option("--private-key <hex>", "Ethereum private key (or set TC_PRIVATE_KEY)").action(async (name2, options, cmd) => {
46056
+ secrets.command("delete <name>").description("Delete a secret").option("--scope <scope>", "Logical secret scope").option("--space <space>", 'Override the secrets space (defaults to "secrets")').option("--private-key <hex>", "Ethereum private key (or set TC_PRIVATE_KEY)").action(async (name2, options, cmd) => {
46014
46057
  try {
46015
46058
  const globalOpts = cmd.optsWithGlobals();
46016
46059
  const ctx = await ProfileManager.resolveContext(globalOpts);
46017
46060
  const node = await ensureSecretsNode(ctx, options);
46018
46061
  const scopeOptions = resolveSecretScope(options);
46062
+ const space = resolveSecretsSpace(options);
46019
46063
  const result = await runSecretOperation({
46020
46064
  ctx,
46021
46065
  node,
46022
46066
  action: "del",
46023
46067
  name: name2,
46024
46068
  scopeOptions,
46069
+ space,
46025
46070
  label: `Deleting secret ${name2}...`,
46026
46071
  operation: () => node.secrets.delete(name2, scopeOptions)
46027
46072
  });
@@ -46738,6 +46783,432 @@ ${rowCount} row${rowCount === 1 ? "" : "s"} returned`) + "\n");
46738
46783
  var import_siwe = __toESM(require_siwe(), 1);
46739
46784
  var import_ms2 = __toESM(require_ms(), 1);
46740
46785
 
46786
+ // ../bootstrap/dist/index.js
46787
+ var DEFAULT_MANIFEST_SPACE2 = "applications";
46788
+ var ACCOUNT_REGISTRY_SPACE = "account";
46789
+ var ACCOUNT_REGISTRY_PATH = "applications/";
46790
+ var SECRETS_SPACE3 = "secrets";
46791
+ var BOOTSTRAP_DEFAULT_SPACE = "default";
46792
+ var BOOTSTRAP_PUBLIC_SPACE = "public";
46793
+ var BOOTSTRAP_ENCRYPTION_NETWORK_NAME = "default";
46794
+ var BOOTSTRAP_ENCRYPTION_NETWORK_RESOURCE_TEMPLATE = `urn:tinycloud:encryption:{ownerDid}:${BOOTSTRAP_ENCRYPTION_NETWORK_NAME}`;
46795
+ var DEFAULT_EXPIRY_MS = 30 * 24 * 60 * 60 * 1e3;
46796
+ var VAULT_PERMISSION_SERVICE2 = "tinycloud.vault";
46797
+ var ENCRYPTION_PERMISSION_SERVICE2 = "tinycloud.encryption";
46798
+ var ENCRYPTION_MANIFEST_SPACE2 = "encryption";
46799
+ var NETWORK_CREATE_ACTION = "tinycloud.encryption/network.create";
46800
+ var BOOTSTRAP_SPACE_NAMES = [
46801
+ BOOTSTRAP_DEFAULT_SPACE,
46802
+ DEFAULT_MANIFEST_SPACE2,
46803
+ ACCOUNT_REGISTRY_SPACE,
46804
+ SECRETS_SPACE3,
46805
+ BOOTSTRAP_PUBLIC_SPACE
46806
+ ];
46807
+ var TINYCLOUD_DEFAULT_SPACE_MANIFEST = {
46808
+ app_id: "xyz.tinycloud.default",
46809
+ name: "TinyCloud Default Space",
46810
+ space: BOOTSTRAP_DEFAULT_SPACE,
46811
+ prefix: "",
46812
+ defaults: false,
46813
+ includePublicSpace: false,
46814
+ permissions: [
46815
+ {
46816
+ service: "tinycloud.kv",
46817
+ space: BOOTSTRAP_DEFAULT_SPACE,
46818
+ path: "/",
46819
+ actions: ["get", "put", "del", "list", "metadata"]
46820
+ },
46821
+ {
46822
+ service: "tinycloud.sql",
46823
+ space: BOOTSTRAP_DEFAULT_SPACE,
46824
+ path: "/",
46825
+ actions: ["read", "write"]
46826
+ }
46827
+ ]
46828
+ };
46829
+ var TINYCLOUD_APPLICATIONS_SPACE_MANIFEST = {
46830
+ app_id: "xyz.tinycloud.applications",
46831
+ name: "TinyCloud Applications Space",
46832
+ space: DEFAULT_MANIFEST_SPACE2,
46833
+ prefix: "",
46834
+ defaults: false,
46835
+ includePublicSpace: false,
46836
+ permissions: [
46837
+ {
46838
+ service: "tinycloud.kv",
46839
+ space: DEFAULT_MANIFEST_SPACE2,
46840
+ path: "/",
46841
+ actions: ["get", "put", "del", "list", "metadata"]
46842
+ },
46843
+ {
46844
+ service: "tinycloud.sql",
46845
+ space: DEFAULT_MANIFEST_SPACE2,
46846
+ path: "/",
46847
+ actions: ["read", "write"]
46848
+ }
46849
+ ]
46850
+ };
46851
+ var TINYCLOUD_ACCOUNT_SPACE_MANIFEST = {
46852
+ app_id: "xyz.tinycloud.account",
46853
+ name: "TinyCloud Account Registry",
46854
+ space: ACCOUNT_REGISTRY_SPACE,
46855
+ prefix: "",
46856
+ defaults: false,
46857
+ includePublicSpace: false,
46858
+ permissions: [
46859
+ {
46860
+ service: "tinycloud.kv",
46861
+ space: ACCOUNT_REGISTRY_SPACE,
46862
+ path: "applications/",
46863
+ actions: ["get", "put", "list"]
46864
+ },
46865
+ {
46866
+ service: "tinycloud.kv",
46867
+ space: ACCOUNT_REGISTRY_SPACE,
46868
+ path: "spaces/",
46869
+ actions: ["get", "put", "list"]
46870
+ },
46871
+ {
46872
+ service: "tinycloud.sql",
46873
+ space: ACCOUNT_REGISTRY_SPACE,
46874
+ path: "account",
46875
+ actions: ["read", "write", "schema"]
46876
+ }
46877
+ ]
46878
+ };
46879
+ var TINYCLOUD_SECRETS_BOOTSTRAP_MANIFEST = {
46880
+ app_id: "xyz.tinycloud.secrets",
46881
+ name: "TinyCloud Secrets",
46882
+ space: SECRETS_SPACE3,
46883
+ prefix: "",
46884
+ defaults: false,
46885
+ includePublicSpace: false,
46886
+ permissions: [
46887
+ {
46888
+ service: "tinycloud.vault",
46889
+ space: SECRETS_SPACE3,
46890
+ path: "secrets/",
46891
+ actions: ["read"],
46892
+ skipPrefix: true
46893
+ },
46894
+ {
46895
+ service: "tinycloud.kv",
46896
+ space: SECRETS_SPACE3,
46897
+ path: "variables",
46898
+ actions: ["list", "metadata"],
46899
+ skipPrefix: true
46900
+ },
46901
+ {
46902
+ service: "tinycloud.kv",
46903
+ space: SECRETS_SPACE3,
46904
+ path: "variables/",
46905
+ actions: ["get", "put", "del", "list", "metadata"],
46906
+ skipPrefix: true
46907
+ },
46908
+ {
46909
+ service: "tinycloud.sql",
46910
+ space: SECRETS_SPACE3,
46911
+ path: "default",
46912
+ actions: ["read", "write", "schema"],
46913
+ skipPrefix: true
46914
+ },
46915
+ {
46916
+ service: "tinycloud.capabilities",
46917
+ space: SECRETS_SPACE3,
46918
+ path: "",
46919
+ actions: ["read"],
46920
+ skipPrefix: true
46921
+ }
46922
+ ]
46923
+ };
46924
+ var TINYCLOUD_PUBLIC_SPACE_MANIFEST = {
46925
+ app_id: "xyz.tinycloud.public",
46926
+ name: "TinyCloud Public Space",
46927
+ space: BOOTSTRAP_PUBLIC_SPACE,
46928
+ prefix: "",
46929
+ defaults: false,
46930
+ includePublicSpace: false,
46931
+ permissions: [
46932
+ {
46933
+ service: "tinycloud.kv",
46934
+ space: BOOTSTRAP_PUBLIC_SPACE,
46935
+ path: "/",
46936
+ actions: ["get", "list", "metadata"]
46937
+ }
46938
+ ]
46939
+ };
46940
+ var BOOTSTRAP_SPACE_MANIFESTS = {
46941
+ [BOOTSTRAP_DEFAULT_SPACE]: TINYCLOUD_DEFAULT_SPACE_MANIFEST,
46942
+ [DEFAULT_MANIFEST_SPACE2]: TINYCLOUD_APPLICATIONS_SPACE_MANIFEST,
46943
+ [ACCOUNT_REGISTRY_SPACE]: TINYCLOUD_ACCOUNT_SPACE_MANIFEST,
46944
+ [SECRETS_SPACE3]: TINYCLOUD_SECRETS_BOOTSTRAP_MANIFEST,
46945
+ [BOOTSTRAP_PUBLIC_SPACE]: TINYCLOUD_PUBLIC_SPACE_MANIFEST
46946
+ };
46947
+ var BOOTSTRAP_PERSISTED_APPLICATION_MANIFESTS = [
46948
+ TINYCLOUD_SECRETS_BOOTSTRAP_MANIFEST
46949
+ ];
46950
+ var ACCOUNT_INDEX_SCHEMA = [
46951
+ `CREATE TABLE IF NOT EXISTS applications (
46952
+ app_id TEXT PRIMARY KEY,
46953
+ name TEXT,
46954
+ description TEXT,
46955
+ updated_at TEXT,
46956
+ manifest_json TEXT NOT NULL
46957
+ )`,
46958
+ `CREATE TABLE IF NOT EXISTS application_state (
46959
+ app_id TEXT PRIMARY KEY,
46960
+ manifest_hash TEXT NOT NULL,
46961
+ indexed_at TEXT NOT NULL
46962
+ )`,
46963
+ `CREATE TABLE IF NOT EXISTS spaces (
46964
+ space_id TEXT PRIMARY KEY,
46965
+ name TEXT NOT NULL,
46966
+ owner_did TEXT NOT NULL,
46967
+ type TEXT NOT NULL,
46968
+ permissions_json TEXT NOT NULL,
46969
+ status TEXT NOT NULL,
46970
+ registered_at TEXT,
46971
+ updated_at TEXT NOT NULL,
46972
+ expires_at TEXT
46973
+ )`,
46974
+ `CREATE TABLE IF NOT EXISTS delegations (
46975
+ cid TEXT PRIMARY KEY,
46976
+ direction TEXT NOT NULL,
46977
+ space_id TEXT NOT NULL,
46978
+ space_name TEXT,
46979
+ counterparty_did TEXT NOT NULL,
46980
+ delegate_did TEXT NOT NULL,
46981
+ delegator_did TEXT,
46982
+ path TEXT NOT NULL,
46983
+ actions_json TEXT NOT NULL,
46984
+ expiry TEXT NOT NULL,
46985
+ status TEXT NOT NULL,
46986
+ created_at TEXT,
46987
+ updated_at TEXT NOT NULL
46988
+ )`,
46989
+ `CREATE TABLE IF NOT EXISTS sync_state (
46990
+ source TEXT PRIMARY KEY,
46991
+ synced_at TEXT NOT NULL,
46992
+ count INTEGER NOT NULL
46993
+ )`,
46994
+ "CREATE INDEX IF NOT EXISTS idx_delegations_direction ON delegations(direction)",
46995
+ "CREATE INDEX IF NOT EXISTS idx_delegations_space ON delegations(space_id)",
46996
+ "CREATE INDEX IF NOT EXISTS idx_delegations_counterparty ON delegations(counterparty_did)",
46997
+ "CREATE INDEX IF NOT EXISTS idx_spaces_owner ON spaces(owner_did)",
46998
+ "CREATE INDEX IF NOT EXISTS idx_spaces_type ON spaces(type)"
46999
+ ];
47000
+ var SECRET_RECORDS_SCHEMA = [
47001
+ `CREATE TABLE IF NOT EXISTS secret_records (
47002
+ scope TEXT NOT NULL,
47003
+ name TEXT NOT NULL,
47004
+ provider_id TEXT,
47005
+ custom_note TEXT,
47006
+ created_at TEXT NOT NULL,
47007
+ updated_at TEXT NOT NULL,
47008
+ last_tested TEXT,
47009
+ test_status TEXT,
47010
+ test_message TEXT,
47011
+ PRIMARY KEY(scope, name)
47012
+ )`
47013
+ ];
47014
+ var BOOTSTRAP_MANIFEST = {
47015
+ spaces: BOOTSTRAP_SPACE_NAMES.map((name2) => ({
47016
+ name: name2,
47017
+ manifest: BOOTSTRAP_SPACE_MANIFESTS[name2],
47018
+ persistedAsApplication: name2 === SECRETS_SPACE3
47019
+ })),
47020
+ applications: BOOTSTRAP_PERSISTED_APPLICATION_MANIFESTS,
47021
+ accountIndexSchema: ACCOUNT_INDEX_SCHEMA,
47022
+ secretRecordsSchema: SECRET_RECORDS_SCHEMA,
47023
+ encryptionNetwork: {
47024
+ name: BOOTSTRAP_ENCRYPTION_NETWORK_NAME
47025
+ }
47026
+ };
47027
+ function cloneManifest(manifest) {
47028
+ return {
47029
+ ...manifest,
47030
+ permissions: manifest.permissions?.map((permission) => ({
47031
+ ...permission,
47032
+ actions: [...permission.actions]
47033
+ }))
47034
+ };
47035
+ }
47036
+ function actionUrn(service, action) {
47037
+ return action.includes("/") ? action : `${service}/${action}`;
47038
+ }
47039
+ function applyPrefix2(prefix, path, skipPrefix) {
47040
+ if (skipPrefix === true || prefix === "" || path === "") {
47041
+ return path;
47042
+ }
47043
+ if (path === "/") {
47044
+ return `${prefix}/`;
47045
+ }
47046
+ const trimmedPrefix = prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
47047
+ const trimmedPath = path.startsWith("/") ? path.slice(1) : path;
47048
+ return `${trimmedPrefix}/${trimmedPath}`;
47049
+ }
47050
+ function expandVaultPermission(entry) {
47051
+ return entry.actions.map((action) => {
47052
+ const normalized = action.startsWith("tinycloud.vault/") ? action.slice("tinycloud.vault/".length) : action.startsWith("tinycloud.kv/") ? action.slice("tinycloud.kv/".length) : action;
47053
+ const mapped = normalized === "read" || normalized === "get" ? "tinycloud.kv/get" : normalized === "write" || normalized === "put" ? "tinycloud.kv/put" : normalized === "delete" || normalized === "del" ? "tinycloud.kv/del" : normalized === "list" ? "tinycloud.kv/list" : normalized === "metadata" ? "tinycloud.kv/metadata" : void 0;
47054
+ if (mapped === void 0) {
47055
+ throw new Error(`unknown vault action ${JSON.stringify(action)}`);
47056
+ }
47057
+ const normalizedPath = entry.path.startsWith("/") ? entry.path.slice(1) : entry.path;
47058
+ return {
47059
+ ...entry,
47060
+ service: "tinycloud.kv",
47061
+ path: `vault/${normalizedPath}`,
47062
+ actions: [mapped],
47063
+ skipPrefix: true
47064
+ };
47065
+ });
47066
+ }
47067
+ function expandPermissionEntry2(entry, prefix, inheritedSpace) {
47068
+ if (entry.service === VAULT_PERMISSION_SERVICE2) {
47069
+ return expandVaultPermission(entry).flatMap(
47070
+ (expanded) => expandPermissionEntry2(expanded, prefix, inheritedSpace)
47071
+ );
47072
+ }
47073
+ const skipPrefix = entry.skipPrefix === true || entry.service === ENCRYPTION_PERMISSION_SERVICE2;
47074
+ return [
47075
+ {
47076
+ service: entry.service,
47077
+ space: entry.service === ENCRYPTION_PERMISSION_SERVICE2 ? ENCRYPTION_MANIFEST_SPACE2 : entry.space ?? inheritedSpace,
47078
+ path: applyPrefix2(prefix, entry.path, skipPrefix),
47079
+ actions: entry.actions.map((action) => actionUrn(entry.service, action)),
47080
+ ...entry.description !== void 0 ? { description: entry.description } : {}
47081
+ }
47082
+ ];
47083
+ }
47084
+ function dedupeResources2(resources) {
47085
+ const byKey = /* @__PURE__ */ new Map();
47086
+ for (const resource of resources) {
47087
+ const key2 = `${resource.service}\0${resource.space}\0${resource.path}`;
47088
+ const existing = byKey.get(key2);
47089
+ if (!existing) {
47090
+ byKey.set(key2, { ...resource, actions: [...resource.actions] });
47091
+ continue;
47092
+ }
47093
+ for (const action of resource.actions) {
47094
+ if (!existing.actions.includes(action)) {
47095
+ existing.actions.push(action);
47096
+ }
47097
+ }
47098
+ }
47099
+ return [...byKey.values()];
47100
+ }
47101
+ function withCapabilitiesReadForSpaces2(resources) {
47102
+ const spaces = new Set(
47103
+ resources.filter((resource) => resource.service !== ENCRYPTION_PERMISSION_SERVICE2).map((resource) => resource.space)
47104
+ );
47105
+ return dedupeResources2([
47106
+ ...resources,
47107
+ ...[...spaces].map((space) => ({
47108
+ service: "tinycloud.capabilities",
47109
+ space,
47110
+ path: "",
47111
+ actions: ["tinycloud.capabilities/read"]
47112
+ }))
47113
+ ]);
47114
+ }
47115
+ function accountRegistryPermissions() {
47116
+ return [
47117
+ {
47118
+ service: "tinycloud.kv",
47119
+ space: ACCOUNT_REGISTRY_SPACE,
47120
+ path: ACCOUNT_REGISTRY_PATH,
47121
+ actions: ["tinycloud.kv/get", "tinycloud.kv/put", "tinycloud.kv/list"]
47122
+ },
47123
+ {
47124
+ service: "tinycloud.kv",
47125
+ space: ACCOUNT_REGISTRY_SPACE,
47126
+ path: "spaces/",
47127
+ actions: ["tinycloud.kv/get", "tinycloud.kv/put", "tinycloud.kv/list"]
47128
+ },
47129
+ {
47130
+ service: "tinycloud.sql",
47131
+ space: ACCOUNT_REGISTRY_SPACE,
47132
+ path: "account",
47133
+ actions: ["tinycloud.sql/read", "tinycloud.sql/write", "tinycloud.sql/schema"]
47134
+ }
47135
+ ];
47136
+ }
47137
+ function composeManifestRequest(inputs, options = {}) {
47138
+ if (!Array.isArray(inputs) || inputs.length === 0) {
47139
+ throw new Error("composeManifestRequest requires at least one manifest");
47140
+ }
47141
+ const includeAccountRegistryPermissions = options.includeAccountRegistryPermissions ?? true;
47142
+ const manifests = inputs.map(cloneManifest);
47143
+ const resources = manifests.flatMap((manifest) => {
47144
+ const prefix = manifest.prefix ?? manifest.app_id;
47145
+ const space = manifest.space ?? DEFAULT_MANIFEST_SPACE2;
47146
+ const explicit = manifest.permissions ?? [];
47147
+ return explicit.flatMap((entry) => expandPermissionEntry2(entry, prefix, space));
47148
+ });
47149
+ if (includeAccountRegistryPermissions) {
47150
+ resources.push(...accountRegistryPermissions());
47151
+ }
47152
+ const manifestsByAppId = /* @__PURE__ */ new Map();
47153
+ for (const manifest of manifests) {
47154
+ const current = manifestsByAppId.get(manifest.app_id) ?? [];
47155
+ current.push(cloneManifest(manifest));
47156
+ manifestsByAppId.set(manifest.app_id, current);
47157
+ }
47158
+ return {
47159
+ manifests,
47160
+ resources: withCapabilitiesReadForSpaces2(resources),
47161
+ delegationTargets: [],
47162
+ registryRecords: includeAccountRegistryPermissions ? [...manifestsByAppId.entries()].map(([app_id, appManifests]) => ({
47163
+ key: `${ACCOUNT_REGISTRY_PATH}${app_id}`,
47164
+ app_id,
47165
+ manifests: appManifests
47166
+ })) : [],
47167
+ expiryMs: DEFAULT_EXPIRY_MS,
47168
+ includePublicSpace: manifests.some(
47169
+ (manifest) => manifest.includePublicSpace ?? true
47170
+ )
47171
+ };
47172
+ }
47173
+ function composeBootstrapSpaceManifest(space) {
47174
+ return composeManifestRequest([BOOTSTRAP_SPACE_MANIFESTS[space]], {
47175
+ includeAccountRegistryPermissions: false
47176
+ });
47177
+ }
47178
+ var BOOTSTRAP_SESSION_REQUESTS = Object.freeze(
47179
+ Object.fromEntries(
47180
+ BOOTSTRAP_SPACE_NAMES.map((space) => [
47181
+ space,
47182
+ composeBootstrapSpaceManifest(space)
47183
+ ])
47184
+ )
47185
+ );
47186
+ var ACCOUNT_SESSION_RAW_ALLOWLIST = Object.freeze([
47187
+ {
47188
+ service: "tinycloud.encryption",
47189
+ resource: BOOTSTRAP_ENCRYPTION_NETWORK_RESOURCE_TEMPLATE,
47190
+ actions: [NETWORK_CREATE_ACTION]
47191
+ }
47192
+ ]);
47193
+ var BOOTSTRAP_ALLOWLIST = Object.freeze(
47194
+ BOOTSTRAP_SPACE_NAMES.flatMap((space) => [
47195
+ {
47196
+ kind: "session",
47197
+ service: "tinycloud.session",
47198
+ space,
47199
+ actions: ["siwe"],
47200
+ resources: BOOTSTRAP_SESSION_REQUESTS[space].resources,
47201
+ ...space === ACCOUNT_REGISTRY_SPACE ? { rawAbilities: ACCOUNT_SESSION_RAW_ALLOWLIST } : {}
47202
+ },
47203
+ {
47204
+ kind: "space/host",
47205
+ service: "tinycloud.space",
47206
+ space,
47207
+ actions: ["tinycloud.space/host"]
47208
+ }
47209
+ ])
47210
+ );
47211
+
46741
47212
  // ../../node_modules/uint8arrays/dist/src/equals.js
46742
47213
  function equals(a, b) {
46743
47214
  if (a === b) {
@@ -49653,7 +50124,7 @@ var SharingServiceConfigSchema = external_exports.object({
49653
50124
  message: "Expected an onRootDelegationNeeded function or undefined"
49654
50125
  }).optional()
49655
50126
  });
49656
- var DEFAULT_EXPIRY_MS = EXPIRY.SHARE_MS;
50127
+ var DEFAULT_EXPIRY_MS2 = EXPIRY.SHARE_MS;
49657
50128
  var AutoApproveSpaceCreationHandler = class {
49658
50129
  /**
49659
50130
  * Always returns true to auto-approve space creation.