superbee 0.4.3-pre.2 → 0.4.3-pre.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/superbee.mjs +246 -60
  2. package/package.json +1 -1
package/dist/superbee.mjs CHANGED
@@ -44,7 +44,7 @@ var __toESM = (mod, isNodeMode, target3) => (target3 = mod != null ? __create(__
44
44
  var define_SUPERBEE_BUILD_IDENTITY_default;
45
45
  var init_define_SUPERBEE_BUILD_IDENTITY = __esm({
46
46
  "<define:__SUPERBEE_BUILD_IDENTITY__>"() {
47
- define_SUPERBEE_BUILD_IDENTITY_default = { schema: "superbee.build-identity.v1", package: { name: "superbee", version: "0.4.3-pre.2" }, source: { commit: "9a0a564d4096ec7fe51a7f337e7e001542e8e6d5", dirty: false }, artifact: { channel: "npm-package" }, compatibility_contracts: { skill: 1, hook: 1, mcp: 1 } };
47
+ define_SUPERBEE_BUILD_IDENTITY_default = { schema: "superbee.build-identity.v1", package: { name: "superbee", version: "0.4.3-pre.3" }, source: { commit: "11561dfb62d36f61149e2655e8bebeb08c4e7c9f", dirty: false }, artifact: { channel: "npm-package" }, compatibility_contracts: { skill: 1, hook: 1, mcp: 1 } };
48
48
  }
49
49
  });
50
50
 
@@ -22730,7 +22730,13 @@ async function discoverIssuer(fetchImpl, issuer) {
22730
22730
  throw lastError instanceof CliError ? lastError : new CliError("RUNTIME", `could not read issuer metadata for ${issuer}`);
22731
22731
  }
22732
22732
  async function discoverHosted(fetchImpl, target3) {
22733
- const prm = await fetchJson(fetchImpl, target3.metadataUrl, "protected-resource metadata");
22733
+ let prm;
22734
+ try {
22735
+ prm = await fetchJson(fetchImpl, target3.metadataUrl, "protected-resource metadata");
22736
+ } catch (error51) {
22737
+ if (error51 instanceof CliError && error51.details?.status === 404) throw missingMetadataError(target3);
22738
+ throw error51;
22739
+ }
22734
22740
  const resource = optionalString(prm.resource);
22735
22741
  if (resource === void 0) {
22736
22742
  throw new CliError("RUNTIME", `protected-resource metadata at ${target3.metadataUrl} has no resource`);
@@ -22774,13 +22780,93 @@ function resolveClientId(sources) {
22774
22780
  details
22775
22781
  });
22776
22782
  }
22777
- var DEFAULT_RESOURCE_PATH, PUBLISHED_CLIENT_ID_FIELD, BUILT_IN_CLIENT_IDS, REQUESTED_SCOPE, HTTP_TIMEOUT_MS, CLIENT_ID, MAX_METADATA_BYTES;
22783
+ function parentDomain(hostname5) {
22784
+ if (hostname5.startsWith("[") || IPV4.test(hostname5)) return null;
22785
+ const labels = hostname5.split(".");
22786
+ if (labels.length < 3 || labels.some((label) => label === "")) return null;
22787
+ return labels.slice(1).join(".");
22788
+ }
22789
+ function mayBeWorkspaceOrigin(target3) {
22790
+ const url2 = new URL(target3.origin);
22791
+ return url2.protocol === "https:" && url2.port === "" && target3.audience === `${target3.origin}${DEFAULT_RESOURCE_PATH}` && parentDomain(url2.hostname) !== null;
22792
+ }
22793
+ function trustedPointerTarget(origin, resource) {
22794
+ if (typeof resource !== "string" || resource.length > MAX_POINTER_RESOURCE_LENGTH || resource.includes("@")) return null;
22795
+ let from;
22796
+ let to;
22797
+ try {
22798
+ from = new URL(origin);
22799
+ to = new URL(resource);
22800
+ } catch {
22801
+ return null;
22802
+ }
22803
+ if (from.protocol !== "https:" || to.protocol !== "https:") return null;
22804
+ if (to.username || to.password || to.port !== "" || from.port !== "" || to.search || to.hash) return null;
22805
+ if (to.hostname === from.hostname) return null;
22806
+ const parent = parentDomain(from.hostname);
22807
+ if (parent === null || to.hostname !== `mcp.${parent}`) return null;
22808
+ try {
22809
+ return resolveHostedTarget(resource);
22810
+ } catch {
22811
+ return null;
22812
+ }
22813
+ }
22814
+ function missingMetadataError(target3) {
22815
+ const hostname5 = new URL(target3.origin).hostname;
22816
+ const parent = parentDomain(hostname5);
22817
+ const label = hostname5.split(".")[0];
22818
+ const suggestion = parent !== null && label !== "mcp" && isWorkspaceSlug(label) ? { host: `https://mcp.${parent}`, workspace: label } : null;
22819
+ return new CliError("RUNTIME", `protected-resource metadata at ${target3.metadataUrl} returned HTTP 404`, {
22820
+ details: {
22821
+ status: 404,
22822
+ reason: "no_protected_resource_metadata",
22823
+ host: target3.origin,
22824
+ ...suggestion ? { suggested_host: suggestion.host, suggested_workspace: suggestion.workspace } : {}
22825
+ },
22826
+ help: suggestion ? `${target3.origin} may be a workspace address rather than the sign-in host; if so, re-run with --host ${commandToken(suggestion.host)} --workspace ${commandToken(suggestion.workspace)} (--workspace only where the command takes it)` : `${target3.origin} publishes no Superbee sign-in metadata; check the URL, or ask the host's operator which Superbee host to use`
22827
+ });
22828
+ }
22829
+ async function readWorkspacePointer(fetchImpl, target3) {
22830
+ let pointer;
22831
+ try {
22832
+ pointer = await fetchJson(fetchImpl, `${target3.origin}${WORKSPACE_POINTER_PATH}`, "workspace pointer");
22833
+ } catch {
22834
+ return null;
22835
+ }
22836
+ if (pointer.schema_version !== 1 || !isWorkspaceSlug(pointer.workspace_slug)) return null;
22837
+ if (pointer.workspace_slug !== new URL(target3.origin).hostname.split(".")[0]) return null;
22838
+ const gateway = trustedPointerTarget(target3.origin, pointer.resource);
22839
+ if (gateway === null) return null;
22840
+ return { target: gateway, workspaceSlug: pointer.workspace_slug, requestedOrigin: target3.origin };
22841
+ }
22842
+ async function followWorkspaceOrigin(fetchImpl, target3) {
22843
+ if (!mayBeWorkspaceOrigin(target3)) return null;
22844
+ let status2;
22845
+ try {
22846
+ const response = await fetchImpl(target3.metadataUrl, {
22847
+ headers: { accept: "application/json" },
22848
+ redirect: "error",
22849
+ signal: AbortSignal.timeout(HTTP_TIMEOUT_MS)
22850
+ });
22851
+ status2 = response.status;
22852
+ await response.body?.cancel().catch(() => void 0);
22853
+ } catch {
22854
+ return null;
22855
+ }
22856
+ if (status2 !== 404) return null;
22857
+ const followed = await readWorkspacePointer(fetchImpl, target3);
22858
+ if (followed === null) throw missingMetadataError(target3);
22859
+ return followed;
22860
+ }
22861
+ var DEFAULT_RESOURCE_PATH, PUBLISHED_CLIENT_ID_FIELD, BUILT_IN_CLIENT_IDS, REQUESTED_SCOPE, HTTP_TIMEOUT_MS, CLIENT_ID, MAX_METADATA_BYTES, WORKSPACE_POINTER_PATH, IPV4, MAX_POINTER_RESOURCE_LENGTH;
22778
22862
  var init_discovery = __esm({
22779
22863
  "../cli/src/hosted-auth/discovery.ts"() {
22780
22864
  "use strict";
22781
22865
  init_define_SUPERBEE_BUILD_IDENTITY();
22782
22866
  init_define_SUPERBEE_UPDATE_POLICY();
22783
22867
  init_errors4();
22868
+ init_command_text();
22869
+ init_reference();
22784
22870
  DEFAULT_RESOURCE_PATH = "/mcp";
22785
22871
  PUBLISHED_CLIENT_ID_FIELD = "superbee_cli_client_id";
22786
22872
  BUILT_IN_CLIENT_IDS = Object.freeze({});
@@ -22788,6 +22874,9 @@ var init_discovery = __esm({
22788
22874
  HTTP_TIMEOUT_MS = 1e4;
22789
22875
  CLIENT_ID = /^[\x21-\x7e]{1,256}$/;
22790
22876
  MAX_METADATA_BYTES = 256 * 1024;
22877
+ WORKSPACE_POINTER_PATH = "/.well-known/superbee-workspace";
22878
+ IPV4 = /^\d{1,3}(?:\.\d{1,3}){3}$/;
22879
+ MAX_POINTER_RESOURCE_LENGTH = 2048;
22791
22880
  }
22792
22881
  });
22793
22882
 
@@ -23010,8 +23099,11 @@ __export(session_exports, {
23010
23099
  readPending: () => readPending,
23011
23100
  readSession: () => readSession,
23012
23101
  requireHostedBundleHost: () => requireHostedBundleHost,
23102
+ resolveHostChoice: () => resolveHostChoice,
23103
+ resolveHostChoiceOrNull: () => resolveHostChoiceOrNull,
23013
23104
  resolveHostSelection: () => resolveHostSelection,
23014
23105
  resolveHostSelectionOrNull: () => resolveHostSelectionOrNull,
23106
+ resolveNamedHost: () => resolveNamedHost,
23015
23107
  sessionAccount: () => sessionAccount,
23016
23108
  sessionDirFor: () => sessionDirFor,
23017
23109
  storeForNewSession: () => storeForNewSession,
@@ -23022,6 +23114,8 @@ __export(session_exports, {
23022
23114
  waitForHostedSignIn: () => waitForHostedSignIn,
23023
23115
  waitingSignIns: () => waitingSignIns,
23024
23116
  withSessionLock: () => withSessionLock,
23117
+ workspaceForNamedHost: () => workspaceForNamedHost,
23118
+ workspaceOriginView: () => workspaceOriginView,
23025
23119
  writeDefaultHost: () => writeDefaultHost
23026
23120
  });
23027
23121
  import { mkdir as mkdir2, readdir as readdir3, realpath as realpath2, stat as stat3, unlink as unlink5 } from "node:fs/promises";
@@ -23125,10 +23219,31 @@ function notSignedInError(env = {}) {
23125
23219
  { details: { status: "not_signed_in", reason: "no_host", sign_in_command: command }, help: command }
23126
23220
  );
23127
23221
  }
23128
- async function requireHostedBundleHost(flag, home2, env = {}) {
23129
- const chosen = await hostedBundleHost(flag, home2);
23130
- if (!chosen) throw notSignedInError(env);
23131
- return resolveHostedTarget(chosen);
23222
+ async function requireHostedBundleHost(flag, deps) {
23223
+ if (flag && deps.fetch !== null) return resolveNamedHost(flag, { home: deps.home, fetch: deps.fetch });
23224
+ const chosen = await hostedBundleHost(flag, deps.home);
23225
+ if (!chosen) throw notSignedInError(deps.env);
23226
+ return { target: resolveHostedTarget(chosen), workspaceSlug: null, requestedOrigin: null };
23227
+ }
23228
+ async function resolveNamedHost(host, deps) {
23229
+ const target3 = resolveHostedTarget(host);
23230
+ const plain = { target: target3, workspaceSlug: null, requestedOrigin: null };
23231
+ if (await readSession(deps.home, target3) || await readPending(deps.home, target3)) return plain;
23232
+ const followed = await followWorkspaceOrigin(deps.fetch, target3);
23233
+ if (!followed) return plain;
23234
+ return { target: followed.target, workspaceSlug: followed.workspaceSlug, requestedOrigin: followed.requestedOrigin };
23235
+ }
23236
+ function workspaceOriginView(named) {
23237
+ if (named.requestedOrigin === null || named.workspaceSlug === null) return {};
23238
+ return { host_from: "workspace-origin", requested_host: named.requestedOrigin, workspace_slug: named.workspaceSlug };
23239
+ }
23240
+ function workspaceForNamedHost(named, flag) {
23241
+ if (named.workspaceSlug === null) return flag;
23242
+ if (flag === void 0 || flag === named.workspaceSlug) return named.workspaceSlug;
23243
+ throw new CliError("USAGE", `--host ${commandToken(named.requestedOrigin ?? "")} is the address of workspace '${named.workspaceSlug}', but --workspace names '${flag}'`, {
23244
+ details: { reason: "workspace_conflict", host_workspace: named.workspaceSlug, workspace: flag },
23245
+ help: `drop --workspace to use '${named.workspaceSlug}', or pass the other workspace's own address (or its slug) instead`
23246
+ });
23132
23247
  }
23133
23248
  async function storedSessionHosts(home2) {
23134
23249
  const root = hostedAuthRoot(home2);
@@ -23177,6 +23292,8 @@ function hostSourceText(source) {
23177
23292
  switch (source) {
23178
23293
  case "flag":
23179
23294
  return "--host";
23295
+ case "workspace-origin":
23296
+ return "the gateway the workspace address in --host points to";
23180
23297
  case "last-sign-in":
23181
23298
  return "your last sign-in, the only host with a session";
23182
23299
  case "only-session":
@@ -23185,11 +23302,14 @@ function hostSourceText(source) {
23185
23302
  return "your last sign-in; no session for it now";
23186
23303
  }
23187
23304
  }
23188
- async function hostedWriteHost(flag, home2, retry) {
23305
+ async function hostedWriteHost(flag, home2, retry, fetchImpl) {
23189
23306
  if (flag !== void 0) {
23190
23307
  if (flag.trim() === "") throw new CliError("USAGE", "--host is empty: name the hosted Superbee URL", { help: retry("<url>") });
23191
- return { target: resolveHostedTarget(flag), source: "flag" };
23308
+ if (fetchImpl === null) return { target: resolveHostedTarget(flag), source: "flag", workspaceSlug: null, requestedOrigin: null };
23309
+ const named = await resolveNamedHost(flag, { home: home2, fetch: fetchImpl });
23310
+ return { ...named, source: named.requestedOrigin !== null ? "workspace-origin" : "flag" };
23192
23311
  }
23312
+ const unnamed = { workspaceSlug: null, requestedOrigin: null };
23193
23313
  const remembered = await readDefaultHost(home2);
23194
23314
  const stored = await storedSessionHosts(home2);
23195
23315
  const candidates = new Set(stored);
@@ -23213,22 +23333,30 @@ async function hostedWriteHost(flag, home2, retry) {
23213
23333
  help: `re-run with --host set to the host you mean (one of: ${hosts.join(", ")}); the last sign-in is not used when sessions are held for more than one host or it has none`
23214
23334
  });
23215
23335
  }
23216
- if (rememberedHost) return { target: resolveHostedTarget(rememberedHost), source: stored.length === 0 ? "last-sign-in-signed-out" : "last-sign-in" };
23217
- if (stored.length === 1) return { target: resolveHostedTarget(stored[0]), source: "only-session" };
23336
+ if (rememberedHost) return { target: resolveHostedTarget(rememberedHost), source: stored.length === 0 ? "last-sign-in-signed-out" : "last-sign-in", ...unnamed };
23337
+ if (stored.length === 1) return { target: resolveHostedTarget(stored[0]), source: "only-session", ...unnamed };
23218
23338
  return null;
23219
23339
  }
23340
+ async function resolveHostChoiceOrNull(flag, deps) {
23341
+ const named = flag ?? (deps.env[HOST_ENV] || void 0);
23342
+ if (named !== void 0) return resolveNamedHost(named, deps);
23343
+ const remembered = await readDefaultHost(deps.home);
23344
+ return remembered ? { target: resolveHostedTarget(remembered), workspaceSlug: null, requestedOrigin: null } : null;
23345
+ }
23220
23346
  async function resolveHostSelectionOrNull(flag, deps) {
23221
- const chosen = flag ?? (deps.env[HOST_ENV] || void 0) ?? await readDefaultHost(deps.home) ?? void 0;
23222
- return chosen ? resolveHostedTarget(chosen) : null;
23347
+ return (await resolveHostChoiceOrNull(flag, deps))?.target ?? null;
23223
23348
  }
23224
- async function resolveHostSelection(flag, deps) {
23225
- const target3 = await resolveHostSelectionOrNull(flag, deps);
23226
- if (!target3) {
23349
+ async function resolveHostChoice(flag, deps) {
23350
+ const choice = await resolveHostChoiceOrNull(flag, deps);
23351
+ if (!choice) {
23227
23352
  throw new CliError("USAGE", "no hosted Superbee host selected", {
23228
23353
  help: `pass --host <url> (for example ${String(firstSignInCommand())}) or set ${HOST_ENV}`
23229
23354
  });
23230
23355
  }
23231
- return target3;
23356
+ return choice;
23357
+ }
23358
+ async function resolveHostSelection(flag, deps) {
23359
+ return (await resolveHostChoice(flag, deps)).target;
23232
23360
  }
23233
23361
  function directoryForAccount(home2) {
23234
23362
  return (account) => sessionDirFor(home2, account);
@@ -26474,8 +26602,10 @@ function jsonPure(value) {
26474
26602
  if (typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype) return Object.values(value).every(jsonPure);
26475
26603
  return false;
26476
26604
  }
26477
- function wholeDocumentRequest(bundleId, intent, okfVersion) {
26605
+ function wholeDocumentRequest(bundleId, intent, okfVersion, options = {}) {
26478
26606
  const operation = operationOf(intent);
26607
+ const importing = options.mode === "import";
26608
+ if (importing && operation !== "create") throw new WholeDocumentInputError(`'${intent.target}' is a ${operation}, and only a create may carry imported provenance`, "unsupported_operation");
26479
26609
  if (operation === "delete") return { kind: "delete", operationId: OPERATION_IDS.delete, payload: { bundleId, documentId: intent.target, expectedVersion: intent.base } };
26480
26610
  let parsed2;
26481
26611
  try {
@@ -26484,11 +26614,17 @@ function wholeDocumentRequest(bundleId, intent, okfVersion) {
26484
26614
  throw new WholeDocumentInputError(`'${intent.target}' does not parse: ${error51.message}`);
26485
26615
  }
26486
26616
  const frontmatter = {};
26617
+ const carried = [];
26618
+ const dropped = [];
26487
26619
  for (const [key2, value] of Object.entries(parsed2.frontmatter)) {
26488
26620
  if (!HOSTED_MANAGED_FIELDS.has(key2)) frontmatter[key2] = value;
26621
+ else if (importing && IMPORT_CARRIED_FIELDS.includes(key2)) {
26622
+ frontmatter[key2] = value;
26623
+ carried.push(key2);
26624
+ } else if (importing) dropped.push(key2);
26489
26625
  }
26490
26626
  if (!jsonPure(frontmatter)) throw new WholeDocumentInputError(`'${intent.target}' has frontmatter that is not plain JSON`);
26491
- const keys = Object.keys(frontmatter);
26627
+ const keys = Object.keys(frontmatter).filter((key2) => !HOSTED_MANAGED_FIELDS.has(key2));
26492
26628
  if (keys.length > FRONTMATTER_KEY_LIMIT) throw new WholeDocumentInputError(`'${intent.target}' has ${keys.length} frontmatter fields; at most ${FRONTMATTER_KEY_LIMIT} are accepted`);
26493
26629
  if (typeof frontmatter.type !== "string" || frontmatter.type.trim() === "") throw new WholeDocumentInputError(`'${intent.target}' has no type`);
26494
26630
  if (keys.some((key2) => UNSAFE_KEYS.has(key2))) throw new WholeDocumentInputError(`'${intent.target}' names a reserved object key in its frontmatter`);
@@ -26497,7 +26633,8 @@ function wholeDocumentRequest(bundleId, intent, okfVersion) {
26497
26633
  kind: "create",
26498
26634
  operationId: OPERATION_IDS.create,
26499
26635
  payload: { bundleId, documentId: intent.target, expectAbsent: true, frontmatter, body: parsed2.body },
26500
- ...intent.recreates !== void 0 ? { recreates: intent.recreates } : {}
26636
+ ...intent.recreates !== void 0 ? { recreates: intent.recreates } : {},
26637
+ ...importing ? { provenance: { carried, dropped } } : {}
26501
26638
  } : { kind: "replace", operationId: OPERATION_IDS.replace, payload: { ...common, expectedVersion: intent.base } };
26502
26639
  }
26503
26640
  function createWholeDocumentTransport(options) {
@@ -26667,7 +26804,7 @@ function createWholeDocumentTransport(options) {
26667
26804
  }
26668
26805
  };
26669
26806
  }
26670
- var HOSTED_MANAGED_FIELDS, FRONTMATTER_KEY_LIMIT, UNSAFE_KEYS, WHOLE_DOCUMENT_SETTLEMENT, WHOLE_DOCUMENT_BOUNDS, CURRENT_HOST_DOCUMENT_INPUT_BYTES, SYNC_WRITE_ROUTES, OPERATION_IDS, WHOLE_DOCUMENT_INTENT_KINDS, WholeDocumentInputError, UNKNOWN3, encoder2;
26807
+ var HOSTED_MANAGED_FIELDS, IMPORT_CARRIED_FIELDS, IMPORT_DROPPED_FIELDS, FRONTMATTER_KEY_LIMIT, UNSAFE_KEYS, WHOLE_DOCUMENT_SETTLEMENT, WHOLE_DOCUMENT_BOUNDS, CURRENT_HOST_DOCUMENT_INPUT_BYTES, SYNC_WRITE_ROUTES, OPERATION_IDS, WHOLE_DOCUMENT_INTENT_KINDS, WholeDocumentInputError, UNKNOWN3, encoder2;
26671
26808
  var init_whole_document_transport = __esm({
26672
26809
  "../core/src/hosted-transport/whole-document-transport.ts"() {
26673
26810
  "use strict";
@@ -26680,6 +26817,8 @@ var init_whole_document_transport = __esm({
26680
26817
  init_version_transport();
26681
26818
  init_read_adapter();
26682
26819
  HOSTED_MANAGED_FIELDS = /* @__PURE__ */ new Set(["actor", "superbee_updated_by", "generated", "verified", "timestamp", "okf_version"]);
26820
+ IMPORT_CARRIED_FIELDS = Object.freeze(["generated", "timestamp", "actor", "okf_version"]);
26821
+ IMPORT_DROPPED_FIELDS = Object.freeze([...HOSTED_MANAGED_FIELDS].filter((field) => !IMPORT_CARRIED_FIELDS.includes(field)));
26683
26822
  FRONTMATTER_KEY_LIMIT = 32;
26684
26823
  UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
26685
26824
  WHOLE_DOCUMENT_SETTLEMENT = "recorded-only";
@@ -129423,11 +129562,13 @@ async function bundleRetire(argv2, partial2 = {}) {
129423
129562
  if (!typed) {
129424
129563
  throw new CliError("USAGE", `'${positionals[0]}' is not a hosted bundle id or <workspace>/<bundle-id>`, { help: `${cliInvocation()} bundle retire --help` });
129425
129564
  }
129426
- const target3 = await requireHostedBundleHost(values.host, deps.auth.home, deps.auth.env);
129565
+ const named = await requireHostedBundleHost(values.host, deps.auth);
129566
+ const target3 = named.target;
129567
+ const workspace = workspaceForNamedHost(named, values.workspace);
129427
129568
  const host = commandToken(hostArgument(target3));
129428
- const command = (reference2) => commandFragment`${cliInvocation()} bundle retire ${commandToken(reference2)} --host ${host}${values.workspace !== void 0 ? commandFragment` --workspace ${commandToken(values.workspace)}` : commandFragment``}`;
129569
+ const command = (reference2) => commandFragment`${cliInvocation()} bundle retire ${commandToken(reference2)} --host ${host}${workspace !== void 0 ? commandFragment` --workspace ${commandToken(workspace)}` : commandFragment``}`;
129429
129570
  const resume2 = commandFragment`${command(hostedBundleReferenceText(typed))}${values.json ? commandFragment` --json` : commandFragment``}`;
129430
- const account = await connectHostedAccount(target3, { ...values.workspace !== void 0 ? { workspace: values.workspace } : {}, resume: resume2 }, { auth: deps.auth, ...deps.fetch ? { fetch: deps.fetch } : {} });
129571
+ const account = await connectHostedAccount(target3, { ...workspace !== void 0 ? { workspace } : {}, resume: resume2 }, { auth: deps.auth, ...deps.fetch ? { fetch: deps.fetch } : {} });
129431
129572
  const resolved = resolveBundleReference(typed, account, target3, command).reference;
129432
129573
  const client = resolved.slug === null ? account.client : account.client.within(resolved.slug);
129433
129574
  const reference = hostedBundleReferenceText(resolved);
@@ -129797,7 +129938,7 @@ async function catalogInner(argv2, deps) {
129797
129938
  }
129798
129939
  async function listHosted(values, deps, home2, stdout) {
129799
129940
  const auth = deps.auth ?? defaultHostedAuthDeps(home2);
129800
- const target3 = await requireHostedBundleHost(values.host, auth.home, auth.env);
129941
+ const { target: target3 } = await requireHostedBundleHost(values.host, auth);
129801
129942
  const host = hostArgument(target3);
129802
129943
  const resume2 = commandFragment`${cliInvocation()} catalog list --hosted --host ${commandToken(host)}${values.json ? commandFragment` --json` : commandFragment``}`;
129803
129944
  const { client, identity } = await connectHostedAccount(
@@ -131038,9 +131179,9 @@ async function setupHosted(argv2, partial2 = {}) {
131038
131179
  return;
131039
131180
  }
131040
131181
  const mode = resolveMode(values);
131041
- let target3;
131182
+ let choice;
131042
131183
  try {
131043
- target3 = await resolveHostSelection(values.url, auth);
131184
+ choice = await resolveHostChoice(values.url, auth);
131044
131185
  } catch (error51) {
131045
131186
  if (error51 instanceof CliError && error51.code === "USAGE" && values.url === void 0) {
131046
131187
  throw new CliError("USAGE", "no hosted Superbee URL: pass --url", { help: `${cliInvocation()} setup hosted --url <hosted-url>` });
@@ -131050,17 +131191,20 @@ async function setupHosted(argv2, partial2 = {}) {
131050
131191
  }
131051
131192
  throw error51;
131052
131193
  }
131194
+ const target3 = choice.target;
131195
+ const requested = workspaceForNamedHost(choice, values.workspace);
131053
131196
  const host = hostArgument(target3);
131054
- const resume2 = commandFragment`${cliInvocation()} setup hosted --url ${commandToken(host)}${values.workspace !== void 0 ? commandFragment` --workspace ${commandToken(values.workspace)}` : commandFragment``}${values.json ? commandFragment` --json` : commandFragment``}`;
131197
+ const resume2 = commandFragment`${cliInvocation()} setup hosted --url ${commandToken(host)}${requested !== void 0 ? commandFragment` --workspace ${commandToken(requested)}` : commandFragment``}${values.json ? commandFragment` --json` : commandFragment``}`;
131055
131198
  const { identity, workspace: chosen } = await connectHostedAccount(
131056
131199
  target3,
131057
- { workspace: values.workspace, resume: resume2, otherWorkspace: `${cliInvocation()} setup hosted --url ${commandToken(host)} --workspace <id>` },
131200
+ { workspace: requested, resume: resume2, otherWorkspace: `${cliInvocation()} setup hosted --url ${commandToken(host)} --workspace <id>` },
131058
131201
  { auth, ...partial2.fetch ? { fetch: partial2.fetch } : {} }
131059
131202
  );
131060
131203
  await writeDefaultHost(auth.home, host);
131061
131204
  const workspaces = identity.tenantIds;
131062
131205
  const base = {
131063
131206
  host: target3.origin,
131207
+ ...workspaceOriginView(choice),
131064
131208
  signed_in: true,
131065
131209
  principal: identity.principalId,
131066
131210
  workspaces
@@ -132123,7 +132267,8 @@ async function login(argv2, partial2 = {}) {
132123
132267
  const port = parsePort(values.port);
132124
132268
  const clientIdFlag = values["client-id"] || void 0;
132125
132269
  const auth = { ...deps.auth, env: { ...deps.auth.env, [ACCESS_TOKEN_ENV]: void 0 } };
132126
- const target3 = await resolveHostSelection(values.host, auth);
132270
+ const choice = await resolveHostChoice(values.host, auth);
132271
+ const target3 = choice.target;
132127
132272
  const signIn = { ...clientIdFlag ? { clientIdFlag } : {} };
132128
132273
  let token;
132129
132274
  if (values.loopback && await readSession(auth.home, target3)) {
@@ -132163,6 +132308,7 @@ ${url2}
132163
132308
  status: token.source === "sign-in" ? "signed_in" : "already_signed_in",
132164
132309
  host: target3.origin,
132165
132310
  audience: target3.audience,
132311
+ ...workspaceOriginView(choice),
132166
132312
  ...session ? sessionView(session) : {},
132167
132313
  ...deps.auth.env[ACCESS_TOKEN_ENV] ? { env_override: `${ACCESS_TOKEN_ENV} is set and takes precedence for hosted commands` } : {},
132168
132314
  help: [`${cliInvocation()} whoami --host ${commandToken(hostArgument(target3))}`]
@@ -132368,8 +132514,11 @@ and it completes sign-in. --wait polls instead, for at most --timeout seconds
132368
132514
  --loopback signs in through a browser redirect to 127.0.0.1 (PKCE), waits at most --timeout
132369
132515
  seconds, then falls back to device sign-in. The link is printed on stderr.
132370
132516
 
132371
- The host is --host, then ${HOST_ENV}, then the host of the last sign-in. The issuer comes from the
132372
- host's protected-resource metadata. The CLI client id comes from --client-id, then
132517
+ The host is --host, then ${HOST_ENV}, then the host of the last sign-in. A workspace address
132518
+ (<workspace>.<domain>) with no metadata of its own is followed, through its
132519
+ /.well-known/superbee-workspace pointer, to the gateway it names under the same domain; the
132520
+ session is kept for that gateway (reported as host_from: workspace-origin). The issuer comes from
132521
+ the host's protected-resource metadata. The CLI client id comes from --client-id, then
132373
132522
  ${CLIENT_ID_ENV}, then the host's metadata. The refresh token is kept in the OS credential store
132374
132523
  (macOS Keychain, Linux Secret Service); ${CREDENTIAL_STORE_ENV}=file opts in to a 0600 file
132375
132524
  instead. ${ACCESS_TOKEN_ENV} (for CI) is used as given by hosted commands and is never stored.
@@ -132389,10 +132538,12 @@ Options:
132389
132538
  Usage:
132390
132539
  superbee whoami [--host <url>] [--json]
132391
132540
 
132392
- Local and read-only: reports the host, issuer, client, the signed-in subject from the token's
132541
+ Read-only: reports the host, issuer, client, the signed-in subject from the token's
132393
132542
  claims (not yet confirmed by the gateway), scopes, token expiry, where the refresh token is kept,
132394
132543
  and any sign-in waiting on the person. Never prints a token. Not signed in is a successful result,
132395
132544
  including on a first run with no host selected yet (it names the sign-in command).
132545
+ It reads local state only, except that a host with no stored session that turns out to be a
132546
+ workspace's browser address is resolved to its gateway first (its metadata and pointer requests).
132396
132547
 
132397
132548
  Options:
132398
132549
  --host <url> Hosted Superbee URL (default: ${HOST_ENV}, then the last sign-in)
@@ -133085,18 +133236,18 @@ async function release(folderArg, deps, mode) {
133085
133236
  )
133086
133237
  );
133087
133238
  }
133088
- async function checkoutHost(flag, folder, typed, values, home2, env) {
133239
+ async function checkoutHost(flag, folder, typed, values, home2, env, fetchImpl) {
133089
133240
  if (flag === void 0) {
133090
133241
  const real = await realpath11(folder).catch(() => null);
133091
133242
  const bound = real ? await bindingForPath(home2, real).catch(() => null) : null;
133092
- if (bound) return checkoutTarget(bound);
133243
+ if (bound) return { target: checkoutTarget(bound), workspace: values.workspace, origin: {} };
133093
133244
  }
133094
133245
  const retry = (host) => String(
133095
133246
  commandFragment`${cliInvocation()} checkout ${commandToken(hostedBundleReferenceText(typed))} --host ${commandToken(host)} --dir ${commandToken(folder)}${values.workspace !== void 0 ? commandFragment` --workspace ${commandToken(values.workspace)}` : commandFragment``}${values.json ? commandFragment` --json` : commandFragment``}`
133096
133247
  );
133097
- const chosen = await hostedWriteHost(flag, home2, retry);
133248
+ const chosen = await hostedWriteHost(flag, home2, retry, fetchImpl);
133098
133249
  if (!chosen) throw notSignedInError(env);
133099
- return chosen.target;
133250
+ return { target: chosen.target, workspace: workspaceForNamedHost(chosen, values.workspace), origin: workspaceOriginView(chosen) };
133100
133251
  }
133101
133252
  async function checkout(argv2, partial2 = {}) {
133102
133253
  const deps = checkoutDeps(partial2);
@@ -133145,16 +133296,16 @@ async function checkout(argv2, partial2 = {}) {
133145
133296
  const bundleId = typed.bundleId;
133146
133297
  const folder = path53.resolve(deps.cwd, values.dir ?? bundleId);
133147
133298
  assertBundleOutsidePrivateState(folder, deps.auth.home);
133148
- const target3 = await checkoutHost(values.host, folder, typed, values, deps.auth.home, deps.auth.env);
133299
+ const { target: target3, workspace: workspaceFlag2, origin: hostOrigin } = await checkoutHost(values.host, folder, typed, values, deps.auth.home, deps.auth.env, deps.auth.fetch);
133149
133300
  const prefix = syncRoutePrefix(target3);
133150
- const resume2 = commandFragment`${cliInvocation()} checkout ${commandToken(hostedBundleReferenceText(typed))} --host ${commandToken(hostArgument(target3))} --dir ${commandToken(folder)}${values.workspace !== void 0 ? commandFragment` --workspace ${commandToken(values.workspace)}` : commandFragment``}${values.json ? commandFragment` --json` : commandFragment``}`;
133301
+ const resume2 = commandFragment`${cliInvocation()} checkout ${commandToken(hostedBundleReferenceText(typed))} --host ${commandToken(hostArgument(target3))} --dir ${commandToken(folder)}${workspaceFlag2 !== void 0 ? commandFragment` --workspace ${commandToken(workspaceFlag2)}` : commandFragment``}${values.json ? commandFragment` --json` : commandFragment``}`;
133151
133302
  const found = await entryKind(folder);
133152
133303
  if (found === "other") {
133153
133304
  throw new CliError("ALREADY_EXISTS", `${folder} exists and is not a folder`, { help: "pass --dir <new folder>" });
133154
133305
  }
133155
133306
  if (found === "dir") {
133156
133307
  const existing = await bindingForPath(deps.auth.home, await realpath11(folder));
133157
- const sameWorkspace = values.workspace === void 0 || values.workspace === existing?.workspace_slug || values.workspace === existing?.workspace;
133308
+ const sameWorkspace = workspaceFlag2 === void 0 || workspaceFlag2 === existing?.workspace_slug || workspaceFlag2 === existing?.workspace;
133158
133309
  const asked = typed.slug === null && sameWorkspace ? { slug: existing?.workspace_slug ?? null, bundleId } : typed;
133159
133310
  if (existing && bindsBundle(existing, target3, asked)) {
133160
133311
  deps.stdout(render({ checkout: "unchanged", ...bindingView(existing), help: nextSteps(existing.path) }, mode));
@@ -133168,7 +133319,7 @@ async function checkout(argv2, partial2 = {}) {
133168
133319
  });
133169
133320
  }
133170
133321
  await assertStandaloneFolder(folder);
133171
- const { identity, reader, listed: listed2, workspace, reference, definitionWrites, documentInputBytes } = await connectHostedBundle(typed, target3, values.workspace, deps, resume2);
133322
+ const { identity, reader, listed: listed2, workspace, reference, definitionWrites, documentInputBytes } = await connectHostedBundle(typed, target3, workspaceFlag2, deps, resume2);
133172
133323
  const canonical2 = await canonicalFolder(folder);
133173
133324
  let createdFolder = false;
133174
133325
  const placed = /* @__PURE__ */ new Map();
@@ -133274,6 +133425,7 @@ async function checkout(argv2, partial2 = {}) {
133274
133425
  {
133275
133426
  checkout: "created",
133276
133427
  ...bindingView(result3.binding),
133428
+ ...hostOrigin,
133277
133429
  catalog: cataloged,
133278
133430
  documents: result3.documents,
133279
133431
  root_index: result3.root,
@@ -134170,11 +134322,12 @@ async function exportCommand(argv2, partial2 = {}) {
134170
134322
  }
134171
134323
  let source;
134172
134324
  if (reference) {
134325
+ const named2 = await requireHostedBundleHost(values.host, deps.auth);
134173
134326
  source = {
134174
- target: await requireHostedBundleHost(values.host, deps.auth.home, deps.auth.env),
134327
+ target: named2.target,
134175
134328
  bundleId: reference.bundleId,
134176
134329
  slug: reference.slug,
134177
- workspace: values.workspace ?? null,
134330
+ workspace: workspaceForNamedHost(named2, values.workspace) ?? null,
134178
134331
  binding: null
134179
134332
  };
134180
134333
  } else {
@@ -134600,7 +134753,10 @@ function gitVersions(board, id, rel, current, okfVersion, now, documentInputByte
134600
134753
  label: `imported:git/${sha}`,
134601
134754
  author: cleanAuthor(author ?? ""),
134602
134755
  authoredAt: new Date(when).toISOString(),
134603
- frontmatter: parsed2.frontmatter,
134756
+ // An imported version never asserts verification or host attribution, as a current document does not.
134757
+ frontmatter: Object.fromEntries(
134758
+ Object.entries(parsed2.frontmatter).filter(([key2]) => !IMPORT_DROPPED_FIELDS.includes(key2))
134759
+ ),
134604
134760
  body: parsed2.body ?? ""
134605
134761
  });
134606
134762
  }
@@ -134663,6 +134819,10 @@ async function planPublish(folder, options) {
134663
134819
  const blockers = [];
134664
134820
  const extras = {};
134665
134821
  const documentFiles = [];
134822
+ const provenance2 = {
134823
+ carried: Object.fromEntries(IMPORT_CARRIED_FIELDS.map((field) => [field, 0])),
134824
+ dropped: Object.fromEntries(IMPORT_DROPPED_FIELDS.map((field) => [field, 0]))
134825
+ };
134666
134826
  const entries = await walkAll(folder);
134667
134827
  let rootIndex = null;
134668
134828
  try {
@@ -134734,7 +134894,7 @@ async function planPublish(folder, options) {
134734
134894
  }
134735
134895
  let request3;
134736
134896
  try {
134737
- request3 = wholeDocumentRequest("publish", { kind: "document.write", target: id, base: null, content: utf83(bytes) }, okfVersion);
134897
+ request3 = wholeDocumentRequest("publish", { kind: "document.write", target: id, base: null, content: utf83(bytes) }, okfVersion, { mode: "import" });
134738
134898
  } catch (error51) {
134739
134899
  if (error51 instanceof WholeDocumentInputError) {
134740
134900
  blockers.push({ path: entry.rel, reason: "not_sendable", message: error51.message });
@@ -134742,7 +134902,13 @@ async function planPublish(folder, options) {
134742
134902
  }
134743
134903
  throw error51;
134744
134904
  }
134745
- if (request3.kind === "delete") throw new Error(`'${id}' became a delete request`);
134905
+ if (request3.kind !== "create") throw new Error(`'${id}' became a ${request3.kind} request`);
134906
+ if (Buffer.byteLength(JSON.stringify(request3.payload.frontmatter)) > FRONTMATTER_JSON_BYTES) {
134907
+ blockers.push({ path: entry.rel, reason: "too_large", message: `'${id}' has more than the ${FRONTMATTER_JSON_BYTES / 1024} KiB of frontmatter the host stores, counting ${request3.provenance.carried.join(", ")}` });
134908
+ continue;
134909
+ }
134910
+ for (const field of request3.provenance.carried) provenance2.carried[field] = (provenance2.carried[field] ?? 0) + 1;
134911
+ for (const field of request3.provenance.dropped) provenance2.dropped[field] = (provenance2.dropped[field] ?? 0) + 1;
134746
134912
  documents.push({ id, frontmatter: request3.payload.frontmatter, body: request3.payload.body ?? "" });
134747
134913
  documentFiles.push({ id, rel: entry.rel, text: utf83(bytes) });
134748
134914
  }
@@ -134789,7 +134955,7 @@ async function planPublish(folder, options) {
134789
134955
  const draft = { documents, reserved, blobs: blobs2, history };
134790
134956
  const sendPath = publishPath(draft);
134791
134957
  if (sendPath.mode === "staged") blockers.push(...stagedBlockers(draft));
134792
- return { documents, reserved, blobs: blobs2, history, path: sendPath, skipped, blockers, historyPlan, extras };
134958
+ return { documents, reserved, blobs: blobs2, history, path: sendPath, skipped, blockers, historyPlan, extras, provenance: provenance2 };
134793
134959
  }
134794
134960
  function publishPath(plan) {
134795
134961
  const bounds = PUBLISH_BOUNDS;
@@ -135329,7 +135495,15 @@ function summary(plan) {
135329
135495
  reserved_files: plan.reserved.length,
135330
135496
  other_files: plan.blobs.length,
135331
135497
  sent: plan.path.mode === "one-shot" ? "one request" : `staged: ${plan.path.why}; a list of everything, parts of about 1 MiB, each file, then commits until created (resumable)`,
135332
- history: { mode: plan.historyPlan.mode, versions: plan.historyPlan.versions, ...plan.historyPlan.skipped > 0 ? { skipped: plan.historyPlan.skipped } : {}, note: plan.historyPlan.note }
135498
+ history: { mode: plan.historyPlan.mode, versions: plan.historyPlan.versions, ...plan.historyPlan.skipped > 0 ? { skipped: plan.historyPlan.skipped } : {}, note: plan.historyPlan.note },
135499
+ provenance: provenanceOf(plan)
135500
+ };
135501
+ }
135502
+ function provenanceOf(plan) {
135503
+ return {
135504
+ carried: plan.provenance.carried,
135505
+ dropped: plan.provenance.dropped,
135506
+ note: "provenance travels as each file states it (a claim, not a verification); verification events and the last-editor attribution stay in the folder, and the host attributes the creation to you"
135333
135507
  };
135334
135508
  }
135335
135509
  function createRefusal(code3, message, context) {
@@ -135521,15 +135695,17 @@ async function publish(argv2, partial2 = {}) {
135521
135695
  });
135522
135696
  }
135523
135697
  const withHistory = values["with-history"] === true;
135524
- const yesCommandFor = (host) => commandFragment`${cliInvocation()} publish --to hosted${values.dir !== void 0 ? commandFragment` --dir ${commandToken(canonical2)}` : commandFragment``}${host !== null ? commandFragment` --host ${commandToken(host)}` : commandFragment``}${values.workspace !== void 0 ? commandFragment` --workspace ${commandToken(values.workspace)}` : commandFragment``} --bundle-id ${commandToken(bundleId)}${values.name !== void 0 ? commandFragment` --name ${commandToken(name)}` : commandFragment``}${withHistory ? commandFragment` --with-history` : commandFragment``} --yes${values.json ? commandFragment` --json` : commandFragment``}`;
135698
+ let workspaceFlag2 = values.workspace;
135699
+ const yesCommandFor = (host) => commandFragment`${cliInvocation()} publish --to hosted${values.dir !== void 0 ? commandFragment` --dir ${commandToken(canonical2)}` : commandFragment``}${host !== null ? commandFragment` --host ${commandToken(host)}` : commandFragment``}${workspaceFlag2 !== void 0 ? commandFragment` --workspace ${commandToken(workspaceFlag2)}` : commandFragment``} --bundle-id ${commandToken(bundleId)}${values.name !== void 0 ? commandFragment` --name ${commandToken(name)}` : commandFragment``}${withHistory ? commandFragment` --with-history` : commandFragment``} --yes${values.json ? commandFragment` --json` : commandFragment``}`;
135525
135700
  let chosen = null;
135526
135701
  let ambiguous = null;
135527
135702
  try {
135528
- chosen = await hostedWriteHost(values.host, home2, (host) => String(yesCommandFor(host)));
135703
+ chosen = await hostedWriteHost(values.host, home2, (host) => String(yesCommandFor(host)), values.yes ? deps.auth.fetch : null);
135529
135704
  } catch (error51) {
135530
135705
  if (values.yes || !(error51 instanceof CliError) || error51.details?.reason !== "ambiguous_host") throw error51;
135531
135706
  ambiguous = error51;
135532
135707
  }
135708
+ if (chosen) workspaceFlag2 = workspaceForNamedHost(chosen, values.workspace);
135533
135709
  const target3 = chosen?.target ?? null;
135534
135710
  const planFor = (documentInputBytes) => planPublish(canonical2, withHistory ? { history: true, ...board ? { board } : {}, now: deps.auth.now(), documentInputBytes } : { history: false, documentInputBytes });
135535
135711
  let plan = await planFor(CURRENT_HOST_DOCUMENT_INPUT_BYTES);
@@ -135600,7 +135776,7 @@ async function publish(argv2, partial2 = {}) {
135600
135776
  const otherWorkspace = `${cliInvocation()} publish --to hosted --host ${commandToken(bindingHostArgument(target3))} --workspace <id> --bundle-id ${commandToken(bundleId)} --yes`;
135601
135777
  const { client, identity, workspace } = await connectHostedAccount(
135602
135778
  target3,
135603
- { workspace: values.workspace, resume: yesCommand, otherWorkspace, deadlineMs: CREATE_DEADLINE_MS },
135779
+ { workspace: workspaceFlag2, resume: yesCommand, otherWorkspace, deadlineMs: CREATE_DEADLINE_MS },
135604
135780
  { auth: deps.auth, ...deps.fetch ? { fetch: deps.fetch } : {} }
135605
135781
  );
135606
135782
  if (workspace === null) {
@@ -135636,7 +135812,8 @@ async function publish(argv2, partial2 = {}) {
135636
135812
  documents: created.documents ?? plan.documents.length,
135637
135813
  reserved_files: created.reserved ?? plan.reserved.length,
135638
135814
  other_files: created.blobs ?? plan.blobs.length,
135639
- history: created.history ?? { imported: plan.history.length, verified: false }
135815
+ history: created.history ?? { imported: plan.history.length, verified: false },
135816
+ provenance: { carried: plan.provenance.carried, dropped: plan.provenance.dropped }
135640
135817
  },
135641
135818
  folder: canonical2,
135642
135819
  home: facts.home,
@@ -135730,7 +135907,8 @@ async function publish(argv2, partial2 = {}) {
135730
135907
  documents: created.documents ?? plan.documents.length,
135731
135908
  reserved_files: created.reserved ?? plan.reserved.length,
135732
135909
  other_files: created.blobs ?? plan.blobs.length,
135733
- history: created.history ?? { imported: plan.history.length, verified: false }
135910
+ history: created.history ?? { imported: plan.history.length, verified: false },
135911
+ provenance: { carried: plan.provenance.carried, dropped: plan.provenance.dropped }
135734
135912
  },
135735
135913
  folder: canonical2,
135736
135914
  home: "hosted",
@@ -135799,6 +135977,10 @@ Without --yes, previews only, with no network: what travels (documents, reserved
135799
135977
  files), what stays (dot-files, links), how it is sent, every bound the host enforces, the history
135800
135978
  plan, and what will happen to the folder.
135801
135979
 
135980
+ Each document's provenance (generated, timestamp, actor, okf_version) travels as its file states
135981
+ it, a claim rather than a verification; verified and superbee_updated_by never travel. The
135982
+ preview and the receipt count both, per field.
135983
+
135802
135984
  A bundle within one request's bounds (at most 1,000 documents, 100 other files of 1 MB each,
135803
135985
  1,000 earlier versions, 1,500 objects in all, 3 MiB) is sent in one request. A larger one is sent
135804
135986
  staged: a list of everything, then parts of about 1 MiB, then each file, then commits until the
@@ -135909,10 +136091,12 @@ async function accessList(argv2, deps) {
135909
136091
  return;
135910
136092
  }
135911
136093
  const typed = typedReference(positionals[0]);
135912
- const target3 = await requireHostedBundleHost(values.host, deps.auth.home, deps.auth.env);
136094
+ const named = await requireHostedBundleHost(values.host, deps.auth);
136095
+ const target3 = named.target;
136096
+ const workspace = workspaceForNamedHost(named, values.workspace);
135913
136097
  const command = (reference) => commandFragment`${cliInvocation()} access list ${commandToken(reference)}${hostFlag(target3)}`;
135914
- const resume2 = commandFragment`${command(hostedBundleReferenceText(typed))}${workspaceFlag(values.workspace)}${values.json ? commandFragment` --json` : commandFragment``}`;
135915
- const reached = await reach(typed, target3, values.workspace, resume2, deps, command);
136098
+ const resume2 = commandFragment`${command(hostedBundleReferenceText(typed))}${workspaceFlag(workspace)}${values.json ? commandFragment` --json` : commandFragment``}`;
136099
+ const reached = await reach(typed, target3, workspace, resume2, deps, command);
135916
136100
  const answer2 = await postRoute({ client: reached.client, resume: resume2, reference: reached.reference }, "access-list", { bundleId: reached.bundleId });
135917
136101
  if (!answer2.ok) throw accessRefusal(answer2.code, answer2.message, { reference: reached.reference, host: target3, again: resume2 });
135918
136102
  const data = answer2.data;
@@ -135985,8 +136169,10 @@ async function accessChange(action, argv2, deps) {
135985
136169
  throw usage2(wanted === void 0 ? "grant needs --level read or --level write" : `'${wanted}' is not a level: read or write`);
135986
136170
  }
135987
136171
  const mode = resolveMode(values);
135988
- const target3 = await requireHostedBundleHost(values.host, deps.auth.home, deps.auth.env);
135989
- const command = (reference) => commandFragment`${cliInvocation()} access ${commandToken(action)} ${commandToken(reference)} ${commandToken(person)}${action === "grant" ? commandFragment` --level ${commandToken(wanted)}` : commandFragment``}${hostFlag(target3)}${workspaceFlag(values.workspace)} --yes`;
136172
+ const named = await requireHostedBundleHost(values.host, { ...deps.auth, fetch: values.yes ? deps.auth.fetch : null });
136173
+ const target3 = named.target;
136174
+ const workspace = workspaceForNamedHost(named, values.workspace);
136175
+ const command = (reference) => commandFragment`${cliInvocation()} access ${commandToken(action)} ${commandToken(reference)} ${commandToken(person)}${action === "grant" ? commandFragment` --level ${commandToken(wanted)}` : commandFragment``}${hostFlag(target3)}${workspaceFlag(workspace)} --yes`;
135990
136176
  const typedText = hostedBundleReferenceText(typed);
135991
136177
  const yesCommand = commandFragment`${command(typedText)}${values.json ? commandFragment` --json` : commandFragment``}`;
135992
136178
  if (!values.yes) {
@@ -135999,7 +136185,7 @@ async function accessChange(action, argv2, deps) {
135999
136185
  person,
136000
136186
  ...action === "grant" ? { level: wanted } : {},
136001
136187
  host: target3.origin,
136002
- ...values.workspace !== void 0 ? { workspace: values.workspace } : {},
136188
+ ...workspace !== void 0 ? { workspace } : {},
136003
136189
  will: action === "grant" ? `give ${person} ${wanted} access to '${typedText}' (or change their level to ${wanted}); they must already be a member of the workspace (invite them from the Members page in the Superbee app first)` : `take ${person}'s access to '${typedText}' away; they stay a member of the workspace`,
136004
136190
  needs: "a workspace admin, granting no more than your own level on the bundle",
136005
136191
  network: "none (preview)",
@@ -136010,7 +136196,7 @@ async function accessChange(action, argv2, deps) {
136010
136196
  );
136011
136197
  return;
136012
136198
  }
136013
- const reached = await reach(typed, target3, values.workspace, yesCommand, deps, (reference) => command(reference));
136199
+ const reached = await reach(typed, target3, workspace, yesCommand, deps, (reference) => command(reference));
136014
136200
  const route = action === "grant" ? "access-grant" : "access-revoke";
136015
136201
  const home2 = deps.auth.home;
136016
136202
  const requestId2 = await accessRequestId(home2, target3.origin, reached.reference, person, action === "grant" ? `grant:${wanted}` : "revoke", deps.auth.now());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "superbee",
3
- "version": "0.4.3-pre.2",
3
+ "version": "0.4.3-pre.3",
4
4
  "type": "module",
5
5
  "description": "Agent-facing Superbee CLI for reading and writing local OKF knowledge bundles: context notes, docs, cross-links, and live bundle Views.",
6
6
  "keywords": [