@tinycloud/operations 0.1.0-beta.1 → 0.1.0-beta.2

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
@@ -6526,9 +6526,9 @@ function evaluateAuthority(granted, required) {
6526
6526
  missing: canonicalizeCapabilities(result.missing)
6527
6527
  };
6528
6528
  }
6529
- function evaluateOperationAuthority(granted, required, resolveSpace) {
6530
- const canonicalGranted = canonicalizeOperationCapabilities(granted, resolveSpace);
6531
- const canonicalRequired = canonicalizeOperationCapabilities(required, resolveSpace);
6529
+ function evaluateOperationAuthority(granted, required, resolveSpace2) {
6530
+ const canonicalGranted = canonicalizeOperationCapabilities(granted, resolveSpace2);
6531
+ const canonicalRequired = canonicalizeOperationCapabilities(required, resolveSpace2);
6532
6532
  const missing = [];
6533
6533
  for (const requested of canonicalRequired) {
6534
6534
  const covered = canonicalGranted.some(
@@ -6541,21 +6541,21 @@ function evaluateOperationAuthority(granted, required, resolveSpace) {
6541
6541
  missing: canonicalizeCapabilities(missing)
6542
6542
  };
6543
6543
  }
6544
- function isExactCapabilityMemberSubset(hinted, planned, resolveSpace) {
6545
- const canonicalHinted = canonicalizeOperationCapabilities(hinted, resolveSpace);
6546
- const canonicalPlanned = canonicalizeOperationCapabilities(planned, resolveSpace);
6544
+ function isExactCapabilityMemberSubset(hinted, planned, resolveSpace2) {
6545
+ const canonicalHinted = canonicalizeOperationCapabilities(hinted, resolveSpace2);
6546
+ const canonicalPlanned = canonicalizeOperationCapabilities(planned, resolveSpace2);
6547
6547
  return canonicalHinted.length > 0 && canonicalHinted.every((hint) => canonicalPlanned.some(
6548
6548
  (plan) => JSON.stringify(hint) === JSON.stringify(plan)
6549
6549
  ));
6550
6550
  }
6551
- function canonicalizeOperationCapabilities(permissions, resolveSpace) {
6551
+ function canonicalizeOperationCapabilities(permissions, resolveSpace2) {
6552
6552
  return canonicalizeCapabilities(permissions.map((permission) => {
6553
6553
  const canonicalPath = canonicalizeOperationPath(permission);
6554
- if (permission.space === void 0 || resolveSpace === void 0) {
6554
+ if (permission.space === void 0 || resolveSpace2 === void 0) {
6555
6555
  return canonicalPath;
6556
6556
  }
6557
6557
  try {
6558
- return { ...canonicalPath, space: resolveSpace(permission.space) };
6558
+ return { ...canonicalPath, space: resolveSpace2(permission.space) };
6559
6559
  } catch {
6560
6560
  return canonicalPath;
6561
6561
  }
@@ -6609,7 +6609,7 @@ function isExactPermission(value) {
6609
6609
  if (!isExactRecord(value) || Object.getOwnPropertyNames(value).some((key) => !EXACT_PERMISSION_KEYS.has(key)) || Object.getOwnPropertySymbols(value).length > 0) {
6610
6610
  return false;
6611
6611
  }
6612
- if (!isExactText(value.service) || !isExactPath(value.path) || value.space !== void 0 && !isExactText(value.space) || !Array.isArray(value.actions) || value.actions.length === 0 || !value.actions.every(isExactText) || new Set(value.actions).size !== value.actions.length || value.skipPrefix === true || value.skipPrefix !== void 0 && value.skipPrefix !== false || value.expiry !== void 0 && !isExactText(value.expiry) || value.description !== void 0 && !isExactText(value.description)) {
6612
+ if (!isExactText(value.service) || !isExactPath(value.path, value.actions) || value.space !== void 0 && !isExactText(value.space) || !Array.isArray(value.actions) || value.actions.length === 0 || !value.actions.every(isExactText) || new Set(value.actions).size !== value.actions.length || value.skipPrefix === true || value.skipPrefix !== void 0 && value.skipPrefix !== false || value.expiry !== void 0 && !isExactText(value.expiry) || value.description !== void 0 && !isExactText(value.description)) {
6613
6613
  return false;
6614
6614
  }
6615
6615
  return !("caveats" in value);
@@ -6622,8 +6622,12 @@ function isExactRecord(value) {
6622
6622
  function isExactText(value) {
6623
6623
  return typeof value === "string" && value.length > 0 && !value.includes("*");
6624
6624
  }
6625
- function isExactPath(value) {
6626
- return isExactText(value) && value !== "/" && !value.endsWith("/");
6625
+ function isExactPath(value, actions) {
6626
+ if (typeof value !== "string" || value === "/" || value.includes("*")) return false;
6627
+ if (value === "" || value.endsWith("/")) {
6628
+ return Array.isArray(actions) && actions.includes("tinycloud.kv/list");
6629
+ }
6630
+ return true;
6627
6631
  }
6628
6632
  function canonicalizeCaveats(caveats) {
6629
6633
  return [...caveats].map((caveat) => ({
@@ -7133,8 +7137,8 @@ function permissionRequestArtifactIdentity(record) {
7133
7137
  missing: record.requested
7134
7138
  });
7135
7139
  }
7136
- function evaluateArtifactAuthority(granted, required, resolveSpace) {
7137
- return resolveSpace === void 0 ? evaluateAuthority(granted, required) : evaluateOperationAuthority(granted, required, resolveSpace);
7140
+ function evaluateArtifactAuthority(granted, required, resolveSpace2) {
7141
+ return resolveSpace2 === void 0 ? evaluateAuthority(granted, required) : evaluateOperationAuthority(granted, required, resolveSpace2);
7138
7142
  }
7139
7143
  function defaultRequestId(now) {
7140
7144
  return `req_${now.getTime().toString(36)}_${randomUUID2().replace(/-/g, "")}`;
@@ -7263,7 +7267,7 @@ function operationSpaceResolver(node, ownerSpace) {
7263
7267
  function resolveOperationSpace(space, node, ownerSpace) {
7264
7268
  if (space.startsWith("tinycloud:")) return canonicalizeSpaceUri(space);
7265
7269
  const ownerSpaceId = ownerSpace === void 0 ? void 0 : ownedSpaceForName(ownerSpace, space);
7266
- if (ownerSpaceId !== void 0) return ownerSpaceId;
7270
+ if (ownerSpaceId !== void 0) return canonicalizeSpaceUri(ownerSpaceId);
7267
7271
  const candidate = node;
7268
7272
  try {
7269
7273
  const resolved = candidate.resolveOwnedSpace?.(space);
@@ -7274,7 +7278,7 @@ function resolveOperationSpace(space, node, ownerSpace) {
7274
7278
  }
7275
7279
  if (typeof candidate.spaceId === "string") {
7276
7280
  const resolved = ownedSpaceForName(candidate.spaceId, space);
7277
- if (resolved !== void 0) return resolved;
7281
+ if (resolved !== void 0) return canonicalizeSpaceUri(resolved);
7278
7282
  }
7279
7283
  const did = typeof candidate.did === "string" ? candidate.did : void 0;
7280
7284
  const pkh = did === void 0 ? null : parsePkhDid(did);
@@ -7513,14 +7517,14 @@ async function importRequestBoundDelegation(context, input) {
7513
7517
  );
7514
7518
  }
7515
7519
  const effectivePermissions = canonicalizeCapabilities(activated.effectivePermissions);
7516
- const resolveSpace = operationSpaceResolver(
7520
+ const resolveSpace2 = operationSpaceResolver(
7517
7521
  context.runtime.node,
7518
7522
  context.summary.space
7519
7523
  );
7520
7524
  if (request.requested.length === 0 || !evaluateOperationAuthority(
7521
7525
  request.requested,
7522
7526
  effectivePermissions,
7523
- resolveSpace
7527
+ resolveSpace2
7524
7528
  ).satisfied) {
7525
7529
  return operationFailure(
7526
7530
  "DELEGATION_REJECTED",
@@ -7540,7 +7544,7 @@ async function importRequestBoundDelegation(context, input) {
7540
7544
  result: audienceMismatch(state.sessionDid, sessionDid)
7541
7545
  };
7542
7546
  }
7543
- if (state.request.profile !== context.summary.profile || !samePrincipal(state.request.sessionDid, sessionDid) || normalizeHost(state.request.host) !== normalizeHost(host) || JSON.stringify(canonicalizeOperationCapabilities(state.request.requested, resolveSpace)) !== JSON.stringify(canonicalizeOperationCapabilities(request.requested, resolveSpace))) {
7547
+ if (state.request.profile !== context.summary.profile || !samePrincipal(state.request.sessionDid, sessionDid) || normalizeHost(state.request.host) !== normalizeHost(host) || JSON.stringify(canonicalizeOperationCapabilities(state.request.requested, resolveSpace2)) !== JSON.stringify(canonicalizeOperationCapabilities(request.requested, resolveSpace2))) {
7544
7548
  return {
7545
7549
  records,
7546
7550
  result: operationFailure(
@@ -7816,8 +7820,376 @@ var init_auth = __esm({
7816
7820
  }
7817
7821
  });
7818
7822
 
7819
- // src/operations/secrets-get.ts
7823
+ // src/operations/exploration.ts
7820
7824
  import { z as z4 } from "zod";
7825
+ async function planAccountRegistryRead(context, path) {
7826
+ return [{
7827
+ service: "tinycloud.kv",
7828
+ space: resolveSpace(context, "account"),
7829
+ path,
7830
+ actions: ["tinycloud.kv/get", "tinycloud.kv/list"]
7831
+ }];
7832
+ }
7833
+ async function planKvList(context, input) {
7834
+ const space = resolveNonSecretSpace(context, input.space);
7835
+ return [{
7836
+ service: "tinycloud.kv",
7837
+ space,
7838
+ path: input.prefix ?? "",
7839
+ actions: ["tinycloud.kv/list"]
7840
+ }];
7841
+ }
7842
+ async function planKvGet(context, input) {
7843
+ const space = resolveNonSecretSpace(context, input.space);
7844
+ return [{
7845
+ service: "tinycloud.kv",
7846
+ space,
7847
+ path: input.key,
7848
+ actions: ["tinycloud.kv/get"]
7849
+ }];
7850
+ }
7851
+ async function executeAccountSpacesList(context, _input) {
7852
+ try {
7853
+ const entries = await readAccountRegistry(context, "spaces/");
7854
+ if (!entries.ok) return nodeFailure("list account spaces");
7855
+ const spaces = entries.records.map(({ key, value }) => projectAccountSpace(key, value)).sort((left, right) => left.name.localeCompare(right.name) || left.spaceId.localeCompare(right.spaceId));
7856
+ return { status: "ok", output: { spaces, count: spaces.length } };
7857
+ } catch {
7858
+ return nodeFailure("list account spaces");
7859
+ }
7860
+ }
7861
+ async function executeAccountApplicationsList(context, _input) {
7862
+ try {
7863
+ const entries = await readAccountRegistry(context, "applications/");
7864
+ if (!entries.ok) return nodeFailure("list account applications");
7865
+ const applications = entries.records.map(({ key, value }) => projectAccountApplication(key, value)).sort((left, right) => left.appId.localeCompare(right.appId));
7866
+ return { status: "ok", output: { applications, count: applications.length } };
7867
+ } catch {
7868
+ return nodeFailure("list account applications");
7869
+ }
7870
+ }
7871
+ async function executeKvList(context, input) {
7872
+ try {
7873
+ const runtime = runtimeContext(context);
7874
+ const space = resolveNonSecretSpace(runtime, input.space);
7875
+ const result = await runtimeNode(runtime).kvForSpace(space).list(
7876
+ input.prefix === void 0 ? void 0 : { prefix: input.prefix }
7877
+ );
7878
+ if (!result.ok) return nodeFailure("list KV keys");
7879
+ const keys = [...result.data.keys];
7880
+ return {
7881
+ status: "ok",
7882
+ output: { space, prefix: input.prefix ?? "", keys, count: keys.length }
7883
+ };
7884
+ } catch (error) {
7885
+ if (error instanceof OperationInvocationError) {
7886
+ return { status: "error", error: error.operationError };
7887
+ }
7888
+ return nodeFailure("list KV keys");
7889
+ }
7890
+ }
7891
+ async function executeKvGet(context, input) {
7892
+ try {
7893
+ const runtime = runtimeContext(context);
7894
+ const space = resolveNonSecretSpace(runtime, input.space);
7895
+ const result = await runtimeNode(runtime).kvForSpace(space).get(input.key);
7896
+ if (!result.ok) return nodeFailure("read the KV value");
7897
+ const encoded = encodeKvValue(result.data.data);
7898
+ return {
7899
+ status: "ok",
7900
+ output: {
7901
+ space,
7902
+ key: input.key,
7903
+ value: encoded.value,
7904
+ encoding: encoded.encoding,
7905
+ metadata: {
7906
+ ...result.data.headers.etag === void 0 ? {} : { etag: result.data.headers.etag },
7907
+ ...result.data.headers.contentType === void 0 ? {} : { contentType: result.data.headers.contentType },
7908
+ ...result.data.headers.lastModified === void 0 ? {} : { lastModified: result.data.headers.lastModified },
7909
+ ...result.data.headers.contentLength === void 0 ? {} : { contentLength: result.data.headers.contentLength }
7910
+ }
7911
+ }
7912
+ };
7913
+ } catch (error) {
7914
+ if (error instanceof OperationInvocationError) {
7915
+ return { status: "error", error: error.operationError };
7916
+ }
7917
+ return nodeFailure("read the KV value");
7918
+ }
7919
+ }
7920
+ function runtimeContext(context) {
7921
+ if (context.runtime === void 0) {
7922
+ throw new TypeError("Authenticated operation runtime is unavailable.");
7923
+ }
7924
+ return context;
7925
+ }
7926
+ function runtimeNode(context) {
7927
+ return runtimeContext(context).runtime.node;
7928
+ }
7929
+ function resolveSpace(context, space) {
7930
+ return operationSpaceResolver(context.runtime.node, context.summary.space)(space);
7931
+ }
7932
+ function resolveNonSecretSpace(context, space) {
7933
+ const resolved = resolveSpace(context, space);
7934
+ if (resolved.split(":").at(-1)?.toLowerCase() === "secrets") {
7935
+ throw new OperationInvocationError(operationError(
7936
+ "INPUT_INVALID",
7937
+ "Generic KV operations cannot access the TinyCloud secrets space; use tinycloud.secrets.get."
7938
+ ));
7939
+ }
7940
+ return resolved;
7941
+ }
7942
+ async function readAccountRegistry(context, prefix) {
7943
+ const runtime = runtimeContext(context);
7944
+ const accountSpace = resolveSpace(runtime, "account");
7945
+ const kv = runtimeNode(runtime).kvForSpace(accountSpace);
7946
+ const listed = await kv.list({ prefix });
7947
+ if (!listed.ok) return { ok: false };
7948
+ const records = [];
7949
+ for (const key of listed.data.keys) {
7950
+ const loaded = await kv.get(key);
7951
+ if (!loaded.ok || !isRecord2(loaded.data.data)) return { ok: false };
7952
+ records.push({ key, value: loaded.data.data });
7953
+ }
7954
+ return { ok: true, records };
7955
+ }
7956
+ function projectAccountSpace(key, record) {
7957
+ const suffix = key.startsWith("spaces/") ? key.slice("spaces/".length) : key;
7958
+ const rawSpaceId = stringField2(record, "space_id", "spaceId") ?? suffix;
7959
+ const rawName = stringField2(record, "name") ?? rawSpaceId.split(":").at(-1) ?? rawSpaceId;
7960
+ const rawType = stringField2(record, "type");
7961
+ const rawStatus = stringField2(record, "status");
7962
+ const rawExpiresAt = record.expires_at ?? record.expiresAt;
7963
+ const expiresAt = rawExpiresAt instanceof Date ? rawExpiresAt.toISOString() : typeof rawExpiresAt === "string" && !Number.isNaN(new Date(rawExpiresAt).getTime()) ? new Date(rawExpiresAt).toISOString() : void 0;
7964
+ return {
7965
+ spaceId: rawSpaceId,
7966
+ name: rawName,
7967
+ ownerDid: stringField2(record, "owner_did", "ownerDid", "owner") ?? "",
7968
+ type: rawType === "owned" || rawType === "delegated" ? rawType : "discovered",
7969
+ permissions: Array.isArray(record.permissions) ? record.permissions.filter((value) => typeof value === "string") : [],
7970
+ status: rawStatus === "archived" ? "archived" : "active",
7971
+ ...stringField2(record, "registered_at", "registeredAt") === void 0 ? {} : { registeredAt: stringField2(record, "registered_at", "registeredAt") },
7972
+ ...stringField2(record, "updated_at", "updatedAt") === void 0 ? {} : { updatedAt: stringField2(record, "updated_at", "updatedAt") },
7973
+ ...expiresAt === void 0 ? {} : { expiresAt }
7974
+ };
7975
+ }
7976
+ function projectAccountApplication(key, record) {
7977
+ const manifests = Array.isArray(record.manifests) ? record.manifests.filter(isRecord2) : [];
7978
+ const first = manifests[0];
7979
+ return {
7980
+ appId: stringField2(record, "app_id", "appId") ?? stringField2(first, "app_id") ?? (key.startsWith("applications/") ? key.slice("applications/".length) : key),
7981
+ manifests,
7982
+ ...stringField2(record, "updated_at", "updatedAt") === void 0 ? {} : { updatedAt: stringField2(record, "updated_at", "updatedAt") },
7983
+ ...stringField2(first, "name") === void 0 ? {} : { name: stringField2(first, "name") },
7984
+ ...stringField2(first, "description") === void 0 ? {} : { description: stringField2(first, "description") },
7985
+ ...stringField2(record, "manifest_hash", "manifestHash") === void 0 ? {} : { manifestHash: stringField2(record, "manifest_hash", "manifestHash") }
7986
+ };
7987
+ }
7988
+ function stringField2(record, ...keys) {
7989
+ if (record === void 0) return void 0;
7990
+ for (const key of keys) {
7991
+ if (typeof record[key] === "string") return record[key];
7992
+ }
7993
+ return void 0;
7994
+ }
7995
+ function isRecord2(value) {
7996
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7997
+ }
7998
+ function encodeKvValue(value) {
7999
+ if (value instanceof Uint8Array) {
8000
+ return { value: Buffer.from(value).toString("base64"), encoding: "base64" };
8001
+ }
8002
+ return {
8003
+ value,
8004
+ encoding: typeof value === "string" ? "text" : "json"
8005
+ };
8006
+ }
8007
+ function nodeFailure(action) {
8008
+ return {
8009
+ status: "error",
8010
+ error: operationError(
8011
+ "NODE_ERROR",
8012
+ `The TinyCloud node could not ${action}.`,
8013
+ { retryable: true }
8014
+ )
8015
+ };
8016
+ }
8017
+ var EmptyInputSchema2, SpaceSchema, PrefixSchema, KeySchema, AccountSpaceSchema, AccountSpacesOutputSchema, AccountApplicationSchema, AccountApplicationsOutputSchema, KvListInputSchema, KvListOutputSchema, KvGetInputSchema, KvGetOutputSchema, AUTHENTICATED_POSTURES, EXPLORATION_EXPOSURE, ACCOUNT_SPACES_SENSITIVITY, ACCOUNT_APPLICATIONS_SENSITIVITY, KV_LIST_SENSITIVITY, KV_GET_SENSITIVITY, explorationOperationDefinitions;
8018
+ var init_exploration = __esm({
8019
+ "src/operations/exploration.ts"() {
8020
+ "use strict";
8021
+ init_errors();
8022
+ init_secrets();
8023
+ EmptyInputSchema2 = z4.object({}).strict();
8024
+ SpaceSchema = z4.string().min(1).refine(
8025
+ (space) => (/^[A-Za-z0-9_-]+$/.test(space) || space.startsWith("tinycloud:")) && !space.includes("*"),
8026
+ "Invalid TinyCloud space."
8027
+ );
8028
+ PrefixSchema = z4.string().refine(
8029
+ (prefix) => prefix !== "/" && !prefix.includes("*"),
8030
+ "Invalid KV prefix."
8031
+ );
8032
+ KeySchema = z4.string().min(1).refine(
8033
+ (key) => key !== "/" && !key.endsWith("/") && !key.includes("*"),
8034
+ "Invalid KV key."
8035
+ );
8036
+ AccountSpaceSchema = z4.object({
8037
+ spaceId: z4.string().min(1),
8038
+ name: z4.string().min(1),
8039
+ ownerDid: z4.string(),
8040
+ type: z4.enum(["owned", "delegated", "discovered"]),
8041
+ permissions: z4.array(z4.string()),
8042
+ status: z4.enum(["active", "archived"]),
8043
+ registeredAt: z4.string().optional(),
8044
+ updatedAt: z4.string().optional(),
8045
+ expiresAt: z4.string().datetime({ offset: true }).optional()
8046
+ }).strict();
8047
+ AccountSpacesOutputSchema = z4.object({
8048
+ spaces: z4.array(AccountSpaceSchema),
8049
+ count: z4.number().int().nonnegative()
8050
+ }).strict();
8051
+ AccountApplicationSchema = z4.object({
8052
+ appId: z4.string().min(1),
8053
+ manifests: z4.array(z4.record(z4.unknown())),
8054
+ updatedAt: z4.string().optional(),
8055
+ name: z4.string().optional(),
8056
+ description: z4.string().optional(),
8057
+ manifestHash: z4.string().optional()
8058
+ }).strict();
8059
+ AccountApplicationsOutputSchema = z4.object({
8060
+ applications: z4.array(AccountApplicationSchema),
8061
+ count: z4.number().int().nonnegative()
8062
+ }).strict();
8063
+ KvListInputSchema = z4.object({
8064
+ space: SpaceSchema,
8065
+ prefix: PrefixSchema.optional()
8066
+ }).strict();
8067
+ KvListOutputSchema = z4.object({
8068
+ space: z4.string().min(1),
8069
+ prefix: z4.string(),
8070
+ keys: z4.array(z4.string()),
8071
+ count: z4.number().int().nonnegative()
8072
+ }).strict();
8073
+ KvGetInputSchema = z4.object({
8074
+ space: SpaceSchema,
8075
+ key: KeySchema
8076
+ }).strict();
8077
+ KvGetOutputSchema = z4.object({
8078
+ space: z4.string().min(1),
8079
+ key: z4.string().min(1),
8080
+ value: z4.union([
8081
+ z4.string(),
8082
+ z4.number(),
8083
+ z4.boolean(),
8084
+ z4.null(),
8085
+ z4.array(z4.unknown()),
8086
+ z4.record(z4.unknown())
8087
+ ]),
8088
+ encoding: z4.enum(["json", "text", "base64"]),
8089
+ metadata: z4.object({
8090
+ etag: z4.string().optional(),
8091
+ contentType: z4.string().optional(),
8092
+ lastModified: z4.string().optional(),
8093
+ contentLength: z4.number().int().nonnegative().optional()
8094
+ }).strict()
8095
+ }).strict();
8096
+ AUTHENTICATED_POSTURES = [
8097
+ "owner-openkey",
8098
+ "delegate-session",
8099
+ "local-owner-key"
8100
+ ];
8101
+ EXPLORATION_EXPOSURE = {
8102
+ cli: {
8103
+ status: "excluded",
8104
+ reason: "Existing account and KV Commander commands remain the CLI surface."
8105
+ },
8106
+ mcp: { status: "required" },
8107
+ skill: { status: "required" },
8108
+ docs: { status: "required" }
8109
+ };
8110
+ ACCOUNT_SPACES_SENSITIVITY = {
8111
+ input: [],
8112
+ output: ["/spaces"]
8113
+ };
8114
+ ACCOUNT_APPLICATIONS_SENSITIVITY = {
8115
+ input: [],
8116
+ output: ["/applications"]
8117
+ };
8118
+ KV_LIST_SENSITIVITY = {
8119
+ input: ["/prefix"],
8120
+ output: ["/keys"]
8121
+ };
8122
+ KV_GET_SENSITIVITY = {
8123
+ input: ["/key"],
8124
+ output: ["/value"]
8125
+ };
8126
+ explorationOperationDefinitions = [
8127
+ {
8128
+ id: "tinycloud.account.spaces.list",
8129
+ version: 1,
8130
+ title: "List TinyCloud account spaces",
8131
+ description: "List the spaces registered in the selected owner's TinyCloud account.",
8132
+ input: EmptyInputSchema2,
8133
+ output: AccountSpacesOutputSchema,
8134
+ effects: ["read"],
8135
+ runtime: "authenticated",
8136
+ postures: AUTHENTICATED_POSTURES,
8137
+ exposure: EXPLORATION_EXPOSURE,
8138
+ sensitivity: ACCOUNT_SPACES_SENSITIVITY,
8139
+ authority: (context) => planAccountRegistryRead(context, "spaces/"),
8140
+ execute: executeAccountSpacesList
8141
+ },
8142
+ {
8143
+ id: "tinycloud.account.applications.list",
8144
+ version: 1,
8145
+ title: "List TinyCloud account applications",
8146
+ description: "List the application manifests registered in the selected owner's TinyCloud account.",
8147
+ input: EmptyInputSchema2,
8148
+ output: AccountApplicationsOutputSchema,
8149
+ effects: ["read"],
8150
+ runtime: "authenticated",
8151
+ postures: AUTHENTICATED_POSTURES,
8152
+ exposure: EXPLORATION_EXPOSURE,
8153
+ sensitivity: ACCOUNT_APPLICATIONS_SENSITIVITY,
8154
+ authority: (context) => planAccountRegistryRead(context, "applications/"),
8155
+ execute: executeAccountApplicationsList
8156
+ },
8157
+ {
8158
+ id: "tinycloud.kv.list",
8159
+ version: 1,
8160
+ title: "List TinyCloud KV keys",
8161
+ description: "List keys at one exact prefix in a delegated TinyCloud space.",
8162
+ input: KvListInputSchema,
8163
+ output: KvListOutputSchema,
8164
+ effects: ["read"],
8165
+ runtime: "authenticated",
8166
+ postures: AUTHENTICATED_POSTURES,
8167
+ exposure: EXPLORATION_EXPOSURE,
8168
+ sensitivity: KV_LIST_SENSITIVITY,
8169
+ authority: planKvList,
8170
+ execute: executeKvList
8171
+ },
8172
+ {
8173
+ id: "tinycloud.kv.get",
8174
+ version: 1,
8175
+ title: "Get a TinyCloud KV value",
8176
+ description: "Read one exact key from a delegated non-secrets TinyCloud space.",
8177
+ input: KvGetInputSchema,
8178
+ output: KvGetOutputSchema,
8179
+ effects: ["read"],
8180
+ runtime: "authenticated",
8181
+ postures: AUTHENTICATED_POSTURES,
8182
+ exposure: EXPLORATION_EXPOSURE,
8183
+ sensitivity: KV_GET_SENSITIVITY,
8184
+ authority: planKvGet,
8185
+ execute: executeKvGet
8186
+ }
8187
+ ];
8188
+ }
8189
+ });
8190
+
8191
+ // src/operations/secrets-get.ts
8192
+ import { z as z5 } from "zod";
7821
8193
  async function planSecretGet(context, input) {
7822
8194
  const reference = resolveSecretReferenceForOperation(
7823
8195
  input,
@@ -7975,19 +8347,19 @@ var init_secrets_get = __esm({
7975
8347
  "use strict";
7976
8348
  init_errors();
7977
8349
  init_secrets();
7978
- SecretsGetInputSchema = z4.object({
7979
- name: z4.string(),
7980
- scope: z4.string().optional(),
7981
- space: z4.string().optional()
8350
+ SecretsGetInputSchema = z5.object({
8351
+ name: z5.string(),
8352
+ scope: z5.string().optional(),
8353
+ space: z5.string().optional()
7982
8354
  }).strict().superRefine((input, context) => {
7983
8355
  try {
7984
8356
  resolveSecretReference(input);
7985
8357
  } catch {
7986
- context.addIssue({ code: z4.ZodIssueCode.custom, message: "Invalid secret reference." });
8358
+ context.addIssue({ code: z5.ZodIssueCode.custom, message: "Invalid secret reference." });
7987
8359
  }
7988
8360
  }).transform(normalizeSecretsGetInput);
7989
- SecretsGetOutputSchema = z4.object({
7990
- value: z4.string()
8361
+ SecretsGetOutputSchema = z5.object({
8362
+ value: z5.string()
7991
8363
  }).strict();
7992
8364
  SECRETS_GET_POSTURES = [
7993
8365
  "owner-openkey",
@@ -8026,7 +8398,7 @@ var init_secrets_get = __esm({
8026
8398
  });
8027
8399
 
8028
8400
  // src/operations/status.ts
8029
- import { z as z5 } from "zod";
8401
+ import { z as z6 } from "zod";
8030
8402
  function createStatusDefinition(params) {
8031
8403
  return {
8032
8404
  id: params.id,
@@ -8081,7 +8453,7 @@ async function inspectPinnedProfileStatus(context, _input) {
8081
8453
  async function pinnedProfileExists(profile) {
8082
8454
  try {
8083
8455
  const storedProfile = await readProfile(profile);
8084
- return isRecord2(storedProfile);
8456
+ return isRecord3(storedProfile);
8085
8457
  } catch {
8086
8458
  return false;
8087
8459
  }
@@ -8101,7 +8473,7 @@ async function countLiveAdditionalDelegations(profile) {
8101
8473
  }
8102
8474
  function summarizeSession(session) {
8103
8475
  if (session === null) return { present: false, expired: null, expiresAt: null };
8104
- if (!isRecord2(session)) throw new TypeError("Invalid session store.");
8476
+ if (!isRecord3(session)) throw new TypeError("Invalid session store.");
8105
8477
  const expiry = extractSessionExpiry(session);
8106
8478
  if (expiry === null) return { present: true, expired: null, expiresAt: null };
8107
8479
  return {
@@ -8111,7 +8483,7 @@ function summarizeSession(session) {
8111
8483
  };
8112
8484
  }
8113
8485
  function storedDelegationExpiry(entry) {
8114
- if (!isRecord2(entry) || !isRecord2(entry.delegation) || !("expiry" in entry.delegation)) {
8486
+ if (!isRecord3(entry) || !isRecord3(entry.delegation) || !("expiry" in entry.delegation)) {
8115
8487
  throw new TypeError("Invalid stored delegation.");
8116
8488
  }
8117
8489
  return parseExpiry(entry.delegation.expiry);
@@ -8140,7 +8512,7 @@ function profileNotFound(profile) {
8140
8512
  )
8141
8513
  };
8142
8514
  }
8143
- function isRecord2(value) {
8515
+ function isRecord3(value) {
8144
8516
  return typeof value === "object" && value !== null && !Array.isArray(value);
8145
8517
  }
8146
8518
  var StatusInputSchema, StatusOutputSchema, STATUS_POSTURES, STATUS_EXPOSURE, STATUS_SENSITIVITY, statusOperationDefinitions;
@@ -8149,27 +8521,27 @@ var init_status = __esm({
8149
8521
  "use strict";
8150
8522
  init_errors();
8151
8523
  init_state();
8152
- StatusInputSchema = z5.object({}).strict();
8153
- StatusOutputSchema = z5.object({
8154
- profile: z5.string().min(1),
8155
- host: z5.string().min(1),
8156
- posture: z5.enum([
8524
+ StatusInputSchema = z6.object({}).strict();
8525
+ StatusOutputSchema = z6.object({
8526
+ profile: z6.string().min(1),
8527
+ host: z6.string().min(1),
8528
+ posture: z6.enum([
8157
8529
  "owner-openkey",
8158
8530
  "delegate-session",
8159
8531
  "local-owner-key",
8160
8532
  "unauthenticated"
8161
8533
  ]),
8162
- operatorType: z5.enum(["human", "agent"]).optional(),
8163
- principalDid: z5.string().min(1).optional(),
8164
- sessionDid: z5.string().min(1).optional(),
8165
- ownerDid: z5.string().min(1).optional(),
8166
- space: z5.string().min(1).optional(),
8167
- session: z5.object({
8168
- present: z5.boolean(),
8169
- expired: z5.boolean().nullable(),
8170
- expiresAt: z5.string().datetime({ offset: true }).nullable()
8534
+ operatorType: z6.enum(["human", "agent"]).optional(),
8535
+ principalDid: z6.string().min(1).optional(),
8536
+ sessionDid: z6.string().min(1).optional(),
8537
+ ownerDid: z6.string().min(1).optional(),
8538
+ space: z6.string().min(1).optional(),
8539
+ session: z6.object({
8540
+ present: z6.boolean(),
8541
+ expired: z6.boolean().nullable(),
8542
+ expiresAt: z6.string().datetime({ offset: true }).nullable()
8171
8543
  }).strict(),
8172
- liveAdditionalDelegationCount: z5.number().int().nonnegative()
8544
+ liveAdditionalDelegationCount: z6.number().int().nonnegative()
8173
8545
  }).strict();
8174
8546
  STATUS_POSTURES = [
8175
8547
  "owner-openkey",
@@ -8209,6 +8581,7 @@ function registeredOperationDefinitions() {
8209
8581
  operationDefinitions ?? (operationDefinitions = [
8210
8582
  ...statusOperationDefinitions,
8211
8583
  ...authOperationDefinitions,
8584
+ ...explorationOperationDefinitions,
8212
8585
  ...secretsGetOperationDefinitions
8213
8586
  ]);
8214
8587
  return operationDefinitions;
@@ -8239,6 +8612,7 @@ var init_registry = __esm({
8239
8612
  "src/registry.ts"() {
8240
8613
  "use strict";
8241
8614
  init_auth();
8615
+ init_exploration();
8242
8616
  init_secrets_get();
8243
8617
  init_status();
8244
8618
  }
@@ -8319,9 +8693,9 @@ function isOperatorType(value) {
8319
8693
  return value === "human" || value === "agent";
8320
8694
  }
8321
8695
  function isStoredProfile(value) {
8322
- return isRecord3(value) && isNonEmptyString(value.name) && isNonEmptyString(value.host) && typeof value.chainId === "number" && Number.isFinite(value.chainId) && isNonEmptyString(value.spaceName) && isNonEmptyString(value.did) && isNonEmptyString(value.createdAt) && isOptionalNonEmptyString(value.sessionDid) && isOptionalNonEmptyString(value.ownerDid) && isOptionalNonEmptyString(value.spaceId) && isOptionalPosture(value.posture) && isOptionalOperatorType(value.operatorType) && isOptionalAuthMethod(value.authMethod) && isOptionalNonEmptyString(value.defaultSpace) && isOptionalNonEmptyString(value.privateKey) && isOptionalNonEmptyString(value.address) && isOptionalNonEmptyString(value.openkeyHost);
8696
+ return isRecord4(value) && isNonEmptyString(value.name) && isNonEmptyString(value.host) && typeof value.chainId === "number" && Number.isFinite(value.chainId) && isNonEmptyString(value.spaceName) && isNonEmptyString(value.did) && isNonEmptyString(value.createdAt) && isOptionalNonEmptyString(value.sessionDid) && isOptionalNonEmptyString(value.ownerDid) && isOptionalNonEmptyString(value.spaceId) && isOptionalPosture(value.posture) && isOptionalOperatorType(value.operatorType) && isOptionalAuthMethod(value.authMethod) && isOptionalNonEmptyString(value.defaultSpace) && isOptionalNonEmptyString(value.privateKey) && isOptionalNonEmptyString(value.address) && isOptionalNonEmptyString(value.openkeyHost);
8323
8697
  }
8324
- function isRecord3(value) {
8698
+ function isRecord4(value) {
8325
8699
  return typeof value === "object" && value !== null && !Array.isArray(value);
8326
8700
  }
8327
8701
  function isNonEmptyString(value) {
@@ -8486,7 +8860,7 @@ function spaceForAuthenticatedPrincipal(principal2) {
8486
8860
  function normalizeSession(session, key) {
8487
8861
  const header = session.delegationHeader;
8488
8862
  const jwk = hasPrivateParameter(session.jwk) ? session.jwk : key;
8489
- if (!isRecord4(header) || typeof header.Authorization !== "string" || typeof session.delegationCid !== "string" || typeof session.spaceId !== "string" || !hasPrivateParameter(jwk) || typeof session.verificationMethod !== "string") {
8863
+ if (!isRecord5(header) || typeof header.Authorization !== "string" || typeof session.delegationCid !== "string" || typeof session.spaceId !== "string" || !hasPrivateParameter(jwk) || typeof session.verificationMethod !== "string") {
8490
8864
  return void 0;
8491
8865
  }
8492
8866
  return {
@@ -8504,7 +8878,7 @@ function normalizeSession(session, key) {
8504
8878
  }
8505
8879
  function normalizeStoredDelegation(entry) {
8506
8880
  const raw = entry.delegation;
8507
- if (!isRecord4(raw) || !isRecord4(raw.delegationHeader)) return void 0;
8881
+ if (!isRecord5(raw) || !isRecord5(raw.delegationHeader)) return void 0;
8508
8882
  const expiry = parseExpiry2(raw.expiry);
8509
8883
  if (expiry === void 0 || typeof raw.cid !== "string" || typeof raw.spaceId !== "string" || typeof raw.path !== "string" || !Array.isArray(raw.actions) || !raw.actions.every((action) => typeof action === "string") || typeof raw.delegateDID !== "string" || typeof raw.ownerAddress !== "string" || typeof raw.chainId !== "number" || typeof raw.delegationHeader.Authorization !== "string") {
8510
8884
  return void 0;
@@ -8516,13 +8890,13 @@ function parseExpiry2(value) {
8516
8890
  return expiry !== void 0 && !Number.isNaN(expiry.getTime()) ? expiry : void 0;
8517
8891
  }
8518
8892
  function hasPrivateParameter(value) {
8519
- return isRecord4(value) && typeof value.d === "string" && value.d.length > 0;
8893
+ return isRecord5(value) && typeof value.d === "string" && value.d.length > 0;
8520
8894
  }
8521
8895
  function normalizeDid(value) {
8522
8896
  if (typeof value !== "string" || value.length === 0) return void 0;
8523
8897
  return value.split("#", 1)[0];
8524
8898
  }
8525
- function isRecord4(value) {
8899
+ function isRecord5(value) {
8526
8900
  return typeof value === "object" && value !== null && !Array.isArray(value);
8527
8901
  }
8528
8902
  function failed(context, error) {
@@ -9020,14 +9394,14 @@ async function prepareInvocation(operationId, operationVersion, invocationTarget
9020
9394
  }
9021
9395
  async function executePreparedInvocation(prepared, options = {}) {
9022
9396
  const { operation, definition, parsedInput, runtimeResolution } = prepared;
9023
- const runtimeContext = runtimeResolution.context.runtime === void 0 ? void 0 : runtimeResolution.context;
9024
- const resolveSpace = runtimeContext === void 0 ? void 0 : operationSpaceResolver(
9025
- runtimeContext.runtime.node,
9026
- runtimeContext.summary.space
9397
+ const runtimeContext2 = runtimeResolution.context.runtime === void 0 ? void 0 : runtimeResolution.context;
9398
+ const resolveSpace2 = runtimeContext2 === void 0 ? void 0 : operationSpaceResolver(
9399
+ runtimeContext2.runtime.node,
9400
+ runtimeContext2.summary.space
9027
9401
  );
9028
9402
  try {
9029
9403
  const planned = await definition.authority(
9030
- runtimeContext ?? runtimeResolution.context,
9404
+ runtimeContext2 ?? runtimeResolution.context,
9031
9405
  parsedInput.data
9032
9406
  );
9033
9407
  const required = exactCapabilities2(planned);
@@ -9042,12 +9416,12 @@ async function executePreparedInvocation(prepared, options = {}) {
9042
9416
  );
9043
9417
  }
9044
9418
  const evaluation = evaluateOperationAuthority(
9045
- runtimeContext?.runtime.granted ?? [],
9419
+ runtimeContext2?.runtime.granted ?? [],
9046
9420
  required,
9047
- resolveSpace
9421
+ resolveSpace2
9048
9422
  );
9049
9423
  if (!evaluation.satisfied) {
9050
- if (runtimeContext === void 0) {
9424
+ if (runtimeContext2 === void 0) {
9051
9425
  return errorResult(
9052
9426
  operation,
9053
9427
  runtimeResolution.context.summary,
@@ -9057,13 +9431,13 @@ async function executePreparedInvocation(prepared, options = {}) {
9057
9431
  if (options.deferAuthorityRequest) {
9058
9432
  try {
9059
9433
  const request = buildPermissionRequestArtifact({
9060
- profile: runtimeContext.summary.profile,
9061
- host: runtimeContext.summary.host,
9062
- sessionDid: runtimeContext.summary.sessionDid,
9063
- posture: runtimeContext.summary.posture,
9064
- operatorType: runtimeContext.summary.operatorType ?? "human",
9065
- ...runtimeContext.summary.ownerDid === void 0 ? {} : { ownerDid: runtimeContext.summary.ownerDid },
9066
- ...runtimeContext.summary.space === void 0 ? {} : { spaceId: runtimeContext.summary.space },
9434
+ profile: runtimeContext2.summary.profile,
9435
+ host: runtimeContext2.summary.host,
9436
+ sessionDid: runtimeContext2.summary.sessionDid,
9437
+ posture: runtimeContext2.summary.posture,
9438
+ operatorType: runtimeContext2.summary.operatorType ?? "human",
9439
+ ...runtimeContext2.summary.ownerDid === void 0 ? {} : { ownerDid: runtimeContext2.summary.ownerDid },
9440
+ ...runtimeContext2.summary.space === void 0 ? {} : { spaceId: runtimeContext2.summary.space },
9067
9441
  missing: evaluation.missing
9068
9442
  });
9069
9443
  return authorityRequiredResult(
@@ -9072,7 +9446,7 @@ async function executePreparedInvocation(prepared, options = {}) {
9072
9446
  parsedInput.data,
9073
9447
  request,
9074
9448
  evaluation.missing,
9075
- runtimeContext.runtime.node
9449
+ runtimeContext2.runtime.node
9076
9450
  );
9077
9451
  } catch {
9078
9452
  return errorResult(
@@ -9083,7 +9457,7 @@ async function executePreparedInvocation(prepared, options = {}) {
9083
9457
  }
9084
9458
  }
9085
9459
  const authority = await persistAuthorityRequest(
9086
- runtimeContext,
9460
+ runtimeContext2,
9087
9461
  evaluation.missing
9088
9462
  );
9089
9463
  if (authority.status === "error") {
@@ -9099,7 +9473,7 @@ async function executePreparedInvocation(prepared, options = {}) {
9099
9473
  parsedInput.data,
9100
9474
  authority.request,
9101
9475
  authority.missing,
9102
- runtimeContext.runtime.node
9476
+ runtimeContext2.runtime.node
9103
9477
  );
9104
9478
  }
9105
9479
  const outcome = await definition.execute(
@@ -9131,7 +9505,7 @@ async function executePreparedInvocation(prepared, options = {}) {
9131
9505
  if (hinted === void 0 || !isExactCapabilityMemberSubset(
9132
9506
  hinted,
9133
9507
  required,
9134
- resolveSpace
9508
+ resolveSpace2
9135
9509
  )) {
9136
9510
  return errorResult(
9137
9511
  operation,
@@ -9142,7 +9516,7 @@ async function executePreparedInvocation(prepared, options = {}) {
9142
9516
  )
9143
9517
  );
9144
9518
  }
9145
- if (runtimeContext === void 0) {
9519
+ if (runtimeContext2 === void 0) {
9146
9520
  return errorResult(
9147
9521
  operation,
9148
9522
  runtimeResolution.context.summary,
@@ -9152,13 +9526,13 @@ async function executePreparedInvocation(prepared, options = {}) {
9152
9526
  if (options.deferAuthorityRequest) {
9153
9527
  try {
9154
9528
  const request = buildPermissionRequestArtifact({
9155
- profile: runtimeContext.summary.profile,
9156
- host: runtimeContext.summary.host,
9157
- sessionDid: runtimeContext.summary.sessionDid,
9158
- posture: runtimeContext.summary.posture,
9159
- operatorType: runtimeContext.summary.operatorType ?? "human",
9160
- ...runtimeContext.summary.ownerDid === void 0 ? {} : { ownerDid: runtimeContext.summary.ownerDid },
9161
- ...runtimeContext.summary.space === void 0 ? {} : { spaceId: runtimeContext.summary.space },
9529
+ profile: runtimeContext2.summary.profile,
9530
+ host: runtimeContext2.summary.host,
9531
+ sessionDid: runtimeContext2.summary.sessionDid,
9532
+ posture: runtimeContext2.summary.posture,
9533
+ operatorType: runtimeContext2.summary.operatorType ?? "human",
9534
+ ...runtimeContext2.summary.ownerDid === void 0 ? {} : { ownerDid: runtimeContext2.summary.ownerDid },
9535
+ ...runtimeContext2.summary.space === void 0 ? {} : { spaceId: runtimeContext2.summary.space },
9162
9536
  missing: hinted
9163
9537
  });
9164
9538
  return authorityRequiredResult(
@@ -9167,7 +9541,7 @@ async function executePreparedInvocation(prepared, options = {}) {
9167
9541
  parsedInput.data,
9168
9542
  request,
9169
9543
  hinted,
9170
- runtimeContext.runtime.node,
9544
+ runtimeContext2.runtime.node,
9171
9545
  outcome.requiresCallerInput ?? false
9172
9546
  );
9173
9547
  } catch {
@@ -9179,7 +9553,7 @@ async function executePreparedInvocation(prepared, options = {}) {
9179
9553
  }
9180
9554
  }
9181
9555
  const authority = await persistAuthorityRequest(
9182
- runtimeContext,
9556
+ runtimeContext2,
9183
9557
  hinted,
9184
9558
  true
9185
9559
  );
@@ -9196,7 +9570,7 @@ async function executePreparedInvocation(prepared, options = {}) {
9196
9570
  parsedInput.data,
9197
9571
  authority.request,
9198
9572
  authority.missing,
9199
- runtimeContext.runtime.node,
9573
+ runtimeContext2.runtime.node,
9200
9574
  outcome.requiresCallerInput ?? false
9201
9575
  );
9202
9576
  }
@@ -9299,12 +9673,12 @@ async function persistAuthorityRequest(context, missing, force = false) {
9299
9673
  };
9300
9674
  }
9301
9675
  try {
9302
- const resolveSpace = operationSpaceResolver(
9676
+ const resolveSpace2 = operationSpaceResolver(
9303
9677
  context.runtime.node,
9304
9678
  context.summary.space
9305
9679
  );
9306
- const canonicalMissing = canonicalizeOperationCapabilities(missing, resolveSpace);
9307
- const canonicalGranted = canonicalizeOperationCapabilities(context.runtime.granted, resolveSpace);
9680
+ const canonicalMissing = canonicalizeOperationCapabilities(missing, resolveSpace2);
9681
+ const canonicalGranted = canonicalizeOperationCapabilities(context.runtime.granted, resolveSpace2);
9308
9682
  const resolution = await createOrReusePermissionRequest({
9309
9683
  profile: context.summary.profile,
9310
9684
  posture: context.summary.posture,
@@ -9315,7 +9689,7 @@ async function persistAuthorityRequest(context, missing, force = false) {
9315
9689
  ...context.summary.space === void 0 ? {} : { spaceId: context.summary.space },
9316
9690
  missing: canonicalMissing,
9317
9691
  granted: force ? [] : canonicalGranted,
9318
- resolveSpace
9692
+ resolveSpace: resolveSpace2
9319
9693
  });
9320
9694
  if (resolution.status !== "created") {
9321
9695
  return {