superbee 0.4.4-pre.3 → 0.4.4-pre.4

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.
@@ -3397,6 +3397,11 @@ function stringifyDoc(frontmatter2, body) {
3397
3397
  return stringifyWithData(frontmatter2, body);
3398
3398
  }
3399
3399
 
3400
+ // ../core/src/code-unit-order.ts
3401
+ function compareCodeUnits(a, b) {
3402
+ return a < b ? -1 : a > b ? 1 : 0;
3403
+ }
3404
+
3400
3405
  // ../core/src/links.ts
3401
3406
  function normalizeSegments(segments) {
3402
3407
  const out = [];
@@ -3857,7 +3862,7 @@ async function scanMatching(backend, filter, onSkip) {
3857
3862
  for (const result of await readManyExisting(backend, ids, onSkip)) {
3858
3863
  if (matchesFilter(result.doc, filter)) results.push(result);
3859
3864
  }
3860
- results.sort((a, b) => a.doc.id.localeCompare(b.doc.id));
3865
+ results.sort((a, b) => compareCodeUnits(a.doc.id, b.doc.id));
3861
3866
  return results;
3862
3867
  }
3863
3868
  async function query(backend, filter = {}, options = {}) {
@@ -3866,7 +3871,7 @@ async function query(backend, filter = {}, options = {}) {
3866
3871
  async function queryHeads(backend, filter = {}, options = {}) {
3867
3872
  if (backend.queryHeads) {
3868
3873
  const rows = (await backend.queryHeads(filter, options.onSkip ? { onSkip: options.onSkip } : void 0)).filter((row) => matchesFilter(row, filter));
3869
- rows.sort((a, b) => a.id.localeCompare(b.id));
3874
+ rows.sort((a, b) => compareCodeUnits(a.id, b.id));
3870
3875
  return rows;
3871
3876
  }
3872
3877
  return (await scanMatching(backend, filter, options.onSkip)).map(({ doc, version: version2 }) => ({
@@ -3906,7 +3911,7 @@ async function queryEdges(backend, filter = {}, options = {}) {
3906
3911
  edges.push(link);
3907
3912
  }
3908
3913
  }
3909
- edges.sort((a, b) => a.from.localeCompare(b.from) || a.to.localeCompare(b.to) || a.text.localeCompare(b.text));
3914
+ edges.sort((a, b) => compareCodeUnits(a.from, b.from) || compareCodeUnits(a.to, b.to) || compareCodeUnits(a.text, b.text));
3910
3915
  return edges;
3911
3916
  }
3912
3917
 
@@ -5458,11 +5463,6 @@ async function queryEdges2(bundle, filter = {}, options = {}) {
5458
5463
  // ../core/src/bundle.ts
5459
5464
  setDefaultBackendFactory((root) => new FilesystemBackend(root));
5460
5465
 
5461
- // ../core/src/code-unit-order.ts
5462
- function compareCodeUnits(a, b) {
5463
- return a < b ? -1 : a > b ? 1 : 0;
5464
- }
5465
-
5466
5466
  // ../core/src/managed-document-metadata.ts
5467
5467
  var MANAGED_DOCUMENT_METADATA_FIELDS = /* @__PURE__ */ new Set([
5468
5468
  "generated",
@@ -6598,7 +6598,7 @@ function replyWithinLimit(reply) {
6598
6598
  }
6599
6599
  function skippedReply(skipped) {
6600
6600
  if (skipped.length === 0) return {};
6601
- return { skipped: [...skipped].sort((a, b) => a.id.localeCompare(b.id)).slice(0, MAX_QUERY_ROWS) };
6601
+ return { skipped: [...skipped].sort((a, b) => compareCodeUnits(a.id, b.id)).slice(0, MAX_QUERY_ROWS) };
6602
6602
  }
6603
6603
  function boundedRows(rows, params, kinds) {
6604
6604
  const requested = params.limit === 0 || params.limit === void 0 ? MAX_QUERY_ROWS : Math.min(params.limit, MAX_QUERY_ROWS);
@@ -6713,7 +6713,7 @@ var BridgeService = class {
6713
6713
  for (const id of subscription.baseline.keys()) {
6714
6714
  if (!next.has(id)) removed.push(id);
6715
6715
  }
6716
- changes.sort((a, b) => a.id.localeCompare(b.id));
6716
+ changes.sort((a, b) => compareCodeUnits(a.id, b.id));
6717
6717
  removed.sort();
6718
6718
  if (changes.length === 0 && removed.length === 0) return { status: "unchanged" };
6719
6719
  if (changes.length > MAX_CHANGE_ROWS || removed.length > MAX_CHANGE_ROWS) {
@@ -6742,7 +6742,7 @@ var BridgeService = class {
6742
6742
  throw new Error("the bundle is too large for the experimental View polling snapshot");
6743
6743
  }
6744
6744
  return new Map(
6745
- [...rows].sort((a, b) => a.id.localeCompare(b.id)).map((row) => [row.id, row.version])
6745
+ [...rows].sort((a, b) => compareCodeUnits(a.id, b.id)).map((row) => [row.id, row.version])
6746
6746
  );
6747
6747
  }
6748
6748
  /**
@@ -31351,6 +31351,11 @@ function stringifyDoc(frontmatter2, body) {
31351
31351
  return stringifyWithData(frontmatter2, body);
31352
31352
  }
31353
31353
 
31354
+ // ../core/src/code-unit-order.ts
31355
+ function compareCodeUnits(a, b) {
31356
+ return a < b ? -1 : a > b ? 1 : 0;
31357
+ }
31358
+
31354
31359
  // ../core/src/links.ts
31355
31360
  function normalizeSegments(segments) {
31356
31361
  const out = [];
@@ -31811,7 +31816,7 @@ async function scanMatching(backend, filter, onSkip) {
31811
31816
  for (const result of await readManyExisting(backend, ids, onSkip)) {
31812
31817
  if (matchesFilter(result.doc, filter)) results.push(result);
31813
31818
  }
31814
- results.sort((a, b) => a.doc.id.localeCompare(b.doc.id));
31819
+ results.sort((a, b) => compareCodeUnits(a.doc.id, b.doc.id));
31815
31820
  return results;
31816
31821
  }
31817
31822
  async function query(backend, filter = {}, options = {}) {
@@ -31820,7 +31825,7 @@ async function query(backend, filter = {}, options = {}) {
31820
31825
  async function queryHeads(backend, filter = {}, options = {}) {
31821
31826
  if (backend.queryHeads) {
31822
31827
  const rows = (await backend.queryHeads(filter, options.onSkip ? { onSkip: options.onSkip } : void 0)).filter((row) => matchesFilter(row, filter));
31823
- rows.sort((a, b) => a.id.localeCompare(b.id));
31828
+ rows.sort((a, b) => compareCodeUnits(a.id, b.id));
31824
31829
  return rows;
31825
31830
  }
31826
31831
  return (await scanMatching(backend, filter, options.onSkip)).map(({ doc, version: version2 }) => ({
@@ -31860,7 +31865,7 @@ async function queryEdges(backend, filter = {}, options = {}) {
31860
31865
  edges.push(link);
31861
31866
  }
31862
31867
  }
31863
- edges.sort((a, b) => a.from.localeCompare(b.from) || a.to.localeCompare(b.to) || a.text.localeCompare(b.text));
31868
+ edges.sort((a, b) => compareCodeUnits(a.from, b.from) || compareCodeUnits(a.to, b.to) || compareCodeUnits(a.text, b.text));
31864
31869
  return edges;
31865
31870
  }
31866
31871
 
@@ -33442,11 +33447,6 @@ async function queryEdges2(bundle, filter = {}, options = {}) {
33442
33447
  // ../core/src/bundle.ts
33443
33448
  setDefaultBackendFactory((root) => new FilesystemBackend(root));
33444
33449
 
33445
- // ../core/src/code-unit-order.ts
33446
- function compareCodeUnits(a, b) {
33447
- return a < b ? -1 : a > b ? 1 : 0;
33448
- }
33449
-
33450
33450
  // ../core/src/managed-document-metadata.ts
33451
33451
  var MANAGED_DOCUMENT_METADATA_FIELDS = /* @__PURE__ */ new Set([
33452
33452
  "generated",
@@ -43813,7 +43813,7 @@ function replyWithinLimit(reply) {
43813
43813
  }
43814
43814
  function skippedReply(skipped) {
43815
43815
  if (skipped.length === 0) return {};
43816
- return { skipped: [...skipped].sort((a, b) => a.id.localeCompare(b.id)).slice(0, MAX_QUERY_ROWS) };
43816
+ return { skipped: [...skipped].sort((a, b) => compareCodeUnits(a.id, b.id)).slice(0, MAX_QUERY_ROWS) };
43817
43817
  }
43818
43818
  function boundedRows(rows, params, kinds) {
43819
43819
  const requested = params.limit === 0 || params.limit === void 0 ? MAX_QUERY_ROWS : Math.min(params.limit, MAX_QUERY_ROWS);
@@ -43928,7 +43928,7 @@ var BridgeService = class {
43928
43928
  for (const id of subscription.baseline.keys()) {
43929
43929
  if (!next.has(id)) removed.push(id);
43930
43930
  }
43931
- changes.sort((a, b) => a.id.localeCompare(b.id));
43931
+ changes.sort((a, b) => compareCodeUnits(a.id, b.id));
43932
43932
  removed.sort();
43933
43933
  if (changes.length === 0 && removed.length === 0) return { status: "unchanged" };
43934
43934
  if (changes.length > MAX_CHANGE_ROWS || removed.length > MAX_CHANGE_ROWS) {
@@ -43957,7 +43957,7 @@ var BridgeService = class {
43957
43957
  throw new Error("the bundle is too large for the experimental View polling snapshot");
43958
43958
  }
43959
43959
  return new Map(
43960
- [...rows].sort((a, b) => a.id.localeCompare(b.id)).map((row) => [row.id, row.version])
43960
+ [...rows].sort((a, b) => compareCodeUnits(a.id, b.id)).map((row) => [row.id, row.version])
43961
43961
  );
43962
43962
  }
43963
43963
  /**
@@ -44560,22 +44560,22 @@ function buildSnapshot(first) {
44560
44560
  });
44561
44561
  relationships.push(...parseLinksFromDoc(doc).map((link) => ({ ...link })));
44562
44562
  }
44563
- documents.sort((a, b) => a.id.localeCompare(b.id));
44564
- relationships.sort((a, b) => a.from.localeCompare(b.from) || a.to.localeCompare(b.to) || a.text.localeCompare(b.text) || a.href.localeCompare(b.href));
44563
+ documents.sort((a, b) => compareCodeUnits(a.id, b.id));
44564
+ relationships.sort((a, b) => compareCodeUnits(a.from, b.from) || compareCodeUnits(a.to, b.to) || compareCodeUnits(a.text, b.text) || compareCodeUnits(a.href, b.href));
44565
44565
  const reserved = first.reserved.map((row) => ({
44566
44566
  dir: row.dir,
44567
44567
  name: row.name,
44568
44568
  version: row.version,
44569
44569
  object: addObject(objects, row.bytes, "text/markdown; charset=utf-8", "exact")
44570
44570
  }));
44571
- reserved.sort((a, b) => `${a.dir}/${a.name}`.localeCompare(`${b.dir}/${b.name}`));
44571
+ reserved.sort((a, b) => compareCodeUnits(`${a.dir}/${a.name}`, `${b.dir}/${b.name}`));
44572
44572
  const blobs = first.blobs.map((row) => ({
44573
44573
  key: row.key,
44574
44574
  version: row.version,
44575
44575
  contentType: row.contentType,
44576
44576
  object: addObject(objects, row.bytes, row.contentType, "exact")
44577
44577
  }));
44578
- blobs.sort((a, b) => a.key.localeCompare(b.key));
44578
+ blobs.sort((a, b) => compareCodeUnits(a.key, b.key));
44579
44579
  const blobsByKey = new Map(blobs.map((row) => [row.key, row]));
44580
44580
  const views = [];
44581
44581
  for (const { doc, version: version2 } of parsedDocs.values()) {
@@ -44617,7 +44617,7 @@ function buildSnapshot(first) {
44617
44617
  entryObject: blob.object
44618
44618
  });
44619
44619
  }
44620
- views.sort((a, b) => a.id.localeCompare(b.id));
44620
+ views.sort((a, b) => compareCodeUnits(a.id, b.id));
44621
44621
  const withoutDigest = {
44622
44622
  schema: PUBLICATION_SNAPSHOT_V1,
44623
44623
  schemaVersion: 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.4-pre.3" }, source: { commit: "bf9a2a2bb54c7d682853679a4c241533eb8de381", 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.4-pre.4" }, source: { commit: "128ccfcc43843e6dd97380a124b85e5bfe1d1711", dirty: false }, artifact: { channel: "npm-package" }, compatibility_contracts: { skill: 1, hook: 1, mcp: 1 } };
48
48
  }
49
49
  });
50
50
 
@@ -3582,6 +3582,18 @@ var init_frontmatter = __esm({
3582
3582
  }
3583
3583
  });
3584
3584
 
3585
+ // ../core/src/code-unit-order.ts
3586
+ function compareCodeUnits(a, b) {
3587
+ return a < b ? -1 : a > b ? 1 : 0;
3588
+ }
3589
+ var init_code_unit_order = __esm({
3590
+ "../core/src/code-unit-order.ts"() {
3591
+ "use strict";
3592
+ init_define_SUPERBEE_BUILD_IDENTITY();
3593
+ init_define_SUPERBEE_UPDATE_POLICY();
3594
+ }
3595
+ });
3596
+
3585
3597
  // ../core/src/links.ts
3586
3598
  function normalizeSegments(segments) {
3587
3599
  const out = [];
@@ -4885,7 +4897,7 @@ async function scanMatching(backend, filter, onSkip) {
4885
4897
  for (const result3 of await readManyExisting(backend, ids, onSkip)) {
4886
4898
  if (matchesFilter(result3.doc, filter)) results.push(result3);
4887
4899
  }
4888
- results.sort((a, b) => a.doc.id.localeCompare(b.doc.id));
4900
+ results.sort((a, b) => compareCodeUnits(a.doc.id, b.doc.id));
4889
4901
  return results;
4890
4902
  }
4891
4903
  async function query(backend, filter = {}, options = {}) {
@@ -4894,7 +4906,7 @@ async function query(backend, filter = {}, options = {}) {
4894
4906
  async function queryHeads(backend, filter = {}, options = {}) {
4895
4907
  if (backend.queryHeads) {
4896
4908
  const rows = (await backend.queryHeads(filter, options.onSkip ? { onSkip: options.onSkip } : void 0)).filter((row5) => matchesFilter(row5, filter));
4897
- rows.sort((a, b) => a.id.localeCompare(b.id));
4909
+ rows.sort((a, b) => compareCodeUnits(a.id, b.id));
4898
4910
  return rows;
4899
4911
  }
4900
4912
  return (await scanMatching(backend, filter, options.onSkip)).map(({ doc: doc2, version: version5 }) => ({
@@ -4937,7 +4949,7 @@ async function queryEdges(backend, filter = {}, options = {}) {
4937
4949
  edges.push(link4);
4938
4950
  }
4939
4951
  }
4940
- edges.sort((a, b) => a.from.localeCompare(b.from) || a.to.localeCompare(b.to) || a.text.localeCompare(b.text));
4952
+ edges.sort((a, b) => compareCodeUnits(a.from, b.from) || compareCodeUnits(a.to, b.to) || compareCodeUnits(a.text, b.text));
4941
4953
  return edges;
4942
4954
  }
4943
4955
  async function backlinks(backend, target3) {
@@ -4985,6 +4997,7 @@ var init_engine = __esm({
4985
4997
  "use strict";
4986
4998
  init_define_SUPERBEE_BUILD_IDENTITY();
4987
4999
  init_define_SUPERBEE_UPDATE_POLICY();
5000
+ init_code_unit_order();
4988
5001
  init_body_replace_guards();
4989
5002
  init_inventory_guard();
4990
5003
  init_version_transport();
@@ -9558,18 +9571,6 @@ var init_remote_error = __esm({
9558
9571
  }
9559
9572
  });
9560
9573
 
9561
- // ../core/src/code-unit-order.ts
9562
- function compareCodeUnits(a, b) {
9563
- return a < b ? -1 : a > b ? 1 : 0;
9564
- }
9565
- var init_code_unit_order = __esm({
9566
- "../core/src/code-unit-order.ts"() {
9567
- "use strict";
9568
- init_define_SUPERBEE_BUILD_IDENTITY();
9569
- init_define_SUPERBEE_UPDATE_POLICY();
9570
- }
9571
- });
9572
-
9573
9574
  // ../core/src/heads-digest.ts
9574
9575
  function sortHeads(heads) {
9575
9576
  return [...heads].sort((a, b) => compareCodeUnits(a.id, b.id));
@@ -32410,7 +32411,7 @@ var init_source_profiles = __esm({
32410
32411
  };
32411
32412
  }
32412
32413
  });
32413
- SOURCE_PLUGIN_CORE_VERSION = "0.2.0-pre.38";
32414
+ SOURCE_PLUGIN_CORE_VERSION = "0.2.0-pre.39";
32414
32415
  SOURCE_PROFILES = Object.freeze([restJsonProfile].map((profile) => Object.freeze({ id: profile.id, version: profile.version, kind: profile.kind })));
32415
32416
  }
32416
32417
  });
@@ -35565,6 +35566,7 @@ function decodeBlobWriteResult(raw, expected) {
35565
35566
  if (error51.code === "deletions_held") {
35566
35567
  if (operationId !== "blobs.delete.v1" || !count2(error51.deletions) || !Number.isSafeInteger(error51.baseline) || error51.baseline < 0) throw refuse3();
35567
35568
  } else if (error51.deletions !== void 0 || error51.baseline !== void 0) throw refuse3();
35569
+ if (error51.code === "path_collision" && operationId !== "blobs.create.v1") throw refuse3();
35568
35570
  return { ok: false, operationId, error: { ...error51 } };
35569
35571
  }
35570
35572
  function assertBlobKey(key4) {
@@ -35609,7 +35611,7 @@ var init_blob_contract = __esm({
35609
35611
  onlyKeys = (value, allowed) => Object.keys(value).every((key4) => allowed.includes(key4));
35610
35612
  count2 = (value) => Number.isSafeInteger(value) && value >= 1;
35611
35613
  BLOB_OPERATION_IDS = Object.freeze(["blobs.create.v1", "blobs.replace.v1", "blobs.delete.v1"]);
35612
- BLOB_ERROR_CODES = ["version_conflict", "insufficient_scope", "bundle_not_found", "concurrent_change", "backend_unavailable", "request_capacity", "deletions_held", "write_outcome_unknown"];
35614
+ BLOB_ERROR_CODES = ["version_conflict", "insufficient_scope", "bundle_not_found", "concurrent_change", "backend_unavailable", "request_capacity", "deletions_held", "path_collision", "write_outcome_unknown"];
35613
35615
  BLOB_ERROR_KEYS = ["code", "message", "retryable", "writeState", "expected", "actual", "expectedContentType", "actualContentType", "scope", "resetAt", "deletions", "baseline"];
35614
35616
  BLOB_CONFLICT_KEYS = ["expected", "actual", "expectedContentType", "actualContentType"];
35615
35617
  }
@@ -35832,6 +35834,9 @@ var init_answer_rows = __esm({
35832
35834
  { answer: "429 request_capacity", recorded: "no", outcome: "refused" },
35833
35835
  // The mass-delete hold, refused before dispatch on a delete; not pausing (see DELETIONS_HELD_REFUSAL_CODE).
35834
35836
  { answer: "428 deletions_held", recorded: "no", outcome: "refused" },
35837
+ // A blob create whose path folds onto an existing document or blob path (blob writes only):
35838
+ // refused before anything is written and not recorded under the identity, like the quota.
35839
+ { answer: "200 path_collision", recorded: "no", outcome: "refused" },
35835
35840
  { answer: "200 write_outcome_unknown", recorded: "maybe", outcome: "unknown" },
35836
35841
  { answer: "200 other", recorded: "unknown", outcome: "unknown" },
35837
35842
  { answer: "400", recorded: "no", outcome: "unknown" },
@@ -38280,7 +38285,7 @@ var init_blob_delivery = __esm({
38280
38285
  init_answer_rows();
38281
38286
  init_carrier();
38282
38287
  UNKNOWN5 = Object.freeze({ kind: "unknown" });
38283
- BLOB_UNRECORDED_REFUSAL_CODES = Object.freeze(["insufficient_scope", "bundle_not_found", "request_capacity"]);
38288
+ BLOB_UNRECORDED_REFUSAL_CODES = Object.freeze(["insufficient_scope", "bundle_not_found", "request_capacity", "path_collision"]);
38284
38289
  UNRECORDED_REFUSALS = new Set(BLOB_UNRECORDED_REFUSAL_CODES);
38285
38290
  sleepTimer = (ms, signal) => new Promise((resolve3) => {
38286
38291
  if (signal?.aborted) {
@@ -40280,6 +40285,7 @@ var init_storage = __esm({
40280
40285
  init_define_SUPERBEE_BUILD_IDENTITY();
40281
40286
  init_define_SUPERBEE_UPDATE_POLICY();
40282
40287
  init_errors();
40288
+ init_code_unit_order();
40283
40289
  init_frontmatter_contract();
40284
40290
  init_paths();
40285
40291
  init_version_transport();
@@ -55574,6 +55580,7 @@ __export(sync_exports2, {
55574
55580
  HOSTED_SYNC_USAGE: () => HOSTED_SYNC_USAGE,
55575
55581
  blobConflictHelp: () => blobConflictHelp,
55576
55582
  blobDeliveryFailure: () => blobDeliveryFailure,
55583
+ blobPathCollisionMessage: () => blobPathCollisionMessage,
55577
55584
  deliverHostedBlobRequests: () => deliverHostedBlobRequests,
55578
55585
  dirArgument: () => dirArgument,
55579
55586
  finishAdmittedBlob: () => finishAdmittedBlob,
@@ -56303,6 +56310,11 @@ async function driveBlobRequests(session2, deps2, options) {
56303
56310
  for (const row5 of out.rows) out.counts[row5.state]++;
56304
56311
  return out;
56305
56312
  }
56313
+ async function orphanedArtifactPublication(store, p) {
56314
+ if (p.state !== "blob_admitted" || await store.readBlobIntent(p.blobRequestId)) return false;
56315
+ const snapshot3 = await readBlobSyncState(store, p.entry, p.scope);
56316
+ return !snapshot3.map.entries.find((entry) => entry.key === p.entry)?.head && snapshot3.journal.intents.every((row5) => row5.receipt !== void 0);
56317
+ }
56306
56318
  async function queueHostedArtifact(binding2, input, partial2, resume2) {
56307
56319
  const deps2 = hostedDeps(partial2), signal = deps2.write?.signal;
56308
56320
  signal?.throwIfAborted();
@@ -56314,11 +56326,18 @@ async function queueHostedArtifact(binding2, input, partial2, resume2) {
56314
56326
  signal?.throwIfAborted();
56315
56327
  if (!session2.capabilities.operations || session2.capabilities.blobWrites !== "allowed") throw new CliError("CONFLICT", "host does not offer the identified blob/document writes Artifact needs");
56316
56328
  await assertActorAcceptedByBundle(local.bundle, input.actor);
56317
- const all2 = await publications(store);
56329
+ let all2 = await publications(store);
56318
56330
  const source2 = path44.resolve(deps2.cwd, input.file), rel = path44.relative(binding2.path, source2).split(path44.sep).join("/");
56319
56331
  let publication = all2.find((p) => p.entry === rel);
56320
56332
  if (publication) {
56321
56333
  assertPublicationBinding(publication, binding2);
56334
+ if (await orphanedArtifactPublication(store, publication)) {
56335
+ await store.removeMeta(publicationKey(publication.id), { expected: { present: true, value: publication } });
56336
+ all2 = all2.filter((p) => p.id !== publication.id);
56337
+ publication = void 0;
56338
+ }
56339
+ }
56340
+ if (publication) {
56322
56341
  if (publication.title !== input.title || publication.actor !== input.actor || publication.description !== input.description) throw new CliError("CONFLICT", "Artifact arguments differ from the frozen publication; no new identity was selected");
56323
56342
  } else {
56324
56343
  const heads = await queryHeads2(local.bundle, { prefix: "artifacts/" });
@@ -56350,9 +56369,12 @@ async function queueHostedArtifact(binding2, input, partial2, resume2) {
56350
56369
  assertPublicationSource(publication, binding2.path);
56351
56370
  if (publication.state === "blob_admitted") {
56352
56371
  const declared = declaredHostedSyncGate(binding2.path);
56353
- await driveBlobRequests(session2, deps2, { requestIds: [publication.blobRequestId], gatePresent: declared.kind !== "none", gate: async (fresh, count6) => {
56372
+ const delivered = await driveBlobRequests(session2, deps2, { requestIds: [publication.blobRequestId], gatePresent: declared.kind !== "none", gate: async (fresh, count6) => {
56354
56373
  await judgeHostedWrites(session2, declared, resume2, fresh, count6);
56355
56374
  } });
56375
+ const collided = delivered.rows.find((row5) => blobRefusalCode(row5) === "path_collision");
56376
+ if (collided) await store.removeMeta(publicationKey(publication.id), { expected: { present: true, value: publication } });
56377
+ if (collided) throw new CliError("CONFLICT", blobPathCollisionMessage(collided.key, "give the Artifact a title whose path differs from existing documents and files by more than letter case or Unicode form"), { details: { reason: "path_collision", entry: collided.key, blob_request_id: collided.request_id } });
56356
56378
  const version5 = await acknowledgedArtifactBlob(store, publication);
56357
56379
  if (!version5) return { artifact: "blob_pending", id: publication.id, entry: publication.entry, blob_request_id: publication.blobRequestId, status: "incomplete", help: String(resume2) };
56358
56380
  assertPublicationSource(publication, binding2.path);
@@ -56438,10 +56460,16 @@ function blobRefusalCode(row5) {
56438
56460
  const result3 = row5.result;
56439
56461
  return row5.state === "refused" && result3?.ok === false && typeof result3.error?.code === "string" ? result3.error.code : void 0;
56440
56462
  }
56463
+ function blobPathCollisionMessage(key4, next = "rename the file or its folder to a distinct path, then promote it again") {
56464
+ return `${key4} was not created: another file or document in this bundle differs from this path only by letter case or Unicode form, in its name or a folder, so the two would be one path on a case-insensitive filesystem. Nothing was written; ${next}.`;
56465
+ }
56441
56466
  function blobRefusalNote(row5) {
56442
56467
  const result3 = row5.receipt?.result;
56443
- if (row5.state !== "refused" || !result3 || result3.ok || !BLOB_UNRECORDED.has(result3.error.code)) return void 0;
56444
- return result3.error.code === "request_capacity" ? `${row5.target} was not sent: the sync quota is used up. Nothing was lost; run sync again later and it is sent again.` : `${row5.target} was not sent: the host refused writes to this bundle for this sign-in. Nothing was lost; it is sent again on a sync once access returns.`;
56468
+ if (row5.state !== "refused" || !result3 || result3.ok) return void 0;
56469
+ if (result3.error.code === "path_collision") return blobPathCollisionMessage(row5.target);
56470
+ if (!BLOB_UNRECORDED.has(result3.error.code)) return void 0;
56471
+ const again = result3.operationId === "blobs.create.v1" ? "promote it again" : "sync sends it again";
56472
+ return result3.error.code === "request_capacity" ? `${row5.target} was not sent: the sync quota is used up. Nothing was lost; later, ${again}.` : `${row5.target} was not sent: the host refused writes to this bundle for this sign-in. Nothing was lost; once access returns, ${again}.`;
56445
56473
  }
56446
56474
  function blobDeliveryFailure(report) {
56447
56475
  if (report.rows.every((row5) => row5.state === "committed") && !report.kept_local_edits?.length) return null;
@@ -57492,7 +57520,7 @@ unless SUPERBEE_VIA says otherwise. SUPERBEE_ACTOR does not set it.
57492
57520
  GIT_ONLY_FLAGS = ["establish", "pull-only", "show-incoming", "yes", "body-out", "migrate"];
57493
57521
  busyRefusal = (row5) => row5.refusal !== void 0 && BUSY_REFUSAL_CODES.has(row5.refusal.code);
57494
57522
  BLOB_ACCESS_REFUSALS = /* @__PURE__ */ new Set(["insufficient_scope", "bundle_not_found"]);
57495
- BLOB_UNRECORDED = new Set(BLOB_UNRECORDED_REFUSAL_CODES);
57523
+ BLOB_UNRECORDED = new Set(BLOB_UNRECORDED_REFUSAL_CODES.filter((code3) => code3 !== "path_collision"));
57496
57524
  }
57497
57525
  });
57498
57526
 
@@ -97273,7 +97301,7 @@ function buildRouter(options) {
97273
97301
  let page = heads;
97274
97302
  if (cursor) {
97275
97303
  const idx = page.findIndex((r) => r.id === cursor);
97276
- page = idx >= 0 ? page.slice(idx + 1) : page.filter((r) => r.id.localeCompare(cursor) > 0);
97304
+ page = idx >= 0 ? page.slice(idx + 1) : page.filter((r) => compareCodeUnits(r.id, cursor) > 0);
97277
97305
  }
97278
97306
  const limited = page.slice(0, limit);
97279
97307
  const nextCursor = page.length > limit ? limited[limited.length - 1]?.id ?? null : null;
@@ -98565,7 +98593,7 @@ function projectCandidates(heads) {
98565
98593
  }
98566
98594
  });
98567
98595
  }
98568
- candidates.sort((a, b) => a.row.id.localeCompare(b.row.id));
98596
+ candidates.sort((a, b) => compareCodeUnits(a.row.id, b.row.id));
98569
98597
  return { candidates, invalidRegistrations };
98570
98598
  }
98571
98599
  function cachedAdmission(admitEntry) {
@@ -98626,7 +98654,7 @@ async function listViewCatalogPage(bundle, options) {
98626
98654
  const { candidates, invalidRegistrations } = projectCandidates(heads);
98627
98655
  const supported = new Set(options.access);
98628
98656
  const compatible = candidates.filter((candidate) => supported.has(candidate.row.access));
98629
- const offset = options.afterId === void 0 ? 0 : compatible.findIndex((candidate) => candidate.row.id.localeCompare(options.afterId) > 0);
98657
+ const offset = options.afterId === void 0 ? 0 : compatible.findIndex((candidate) => compareCodeUnits(candidate.row.id, options.afterId) > 0);
98630
98658
  let index2 = offset < 0 ? compatible.length : offset;
98631
98659
  let examined = 0;
98632
98660
  let unavailableEntries = 0;
@@ -98889,7 +98917,7 @@ function replyWithinLimit(reply) {
98889
98917
  }
98890
98918
  function skippedReply(skipped) {
98891
98919
  if (skipped.length === 0) return {};
98892
- return { skipped: [...skipped].sort((a, b) => a.id.localeCompare(b.id)).slice(0, MAX_QUERY_ROWS) };
98920
+ return { skipped: [...skipped].sort((a, b) => compareCodeUnits(a.id, b.id)).slice(0, MAX_QUERY_ROWS) };
98893
98921
  }
98894
98922
  function boundedRows(rows, params, kinds2) {
98895
98923
  const requested = params.limit === 0 || params.limit === void 0 ? MAX_QUERY_ROWS : Math.min(params.limit, MAX_QUERY_ROWS);
@@ -99074,7 +99102,7 @@ var init_bridge = __esm({
99074
99102
  for (const id of subscription.baseline.keys()) {
99075
99103
  if (!next.has(id)) removed.push(id);
99076
99104
  }
99077
- changes.sort((a, b) => a.id.localeCompare(b.id));
99105
+ changes.sort((a, b) => compareCodeUnits(a.id, b.id));
99078
99106
  removed.sort();
99079
99107
  if (changes.length === 0 && removed.length === 0) return { status: "unchanged" };
99080
99108
  if (changes.length > MAX_CHANGE_ROWS || removed.length > MAX_CHANGE_ROWS) {
@@ -99103,7 +99131,7 @@ var init_bridge = __esm({
99103
99131
  throw new Error("the bundle is too large for the experimental View polling snapshot");
99104
99132
  }
99105
99133
  return new Map(
99106
- [...rows].sort((a, b) => a.id.localeCompare(b.id)).map((row5) => [row5.id, row5.version])
99134
+ [...rows].sort((a, b) => compareCodeUnits(a.id, b.id)).map((row5) => [row5.id, row5.version])
99107
99135
  );
99108
99136
  }
99109
99137
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "superbee",
3
- "version": "0.4.4-pre.3",
3
+ "version": "0.4.4-pre.4",
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": [
@@ -379,7 +379,10 @@ bundle for everyone.
379
379
  the `superbee sync --accept-deletes blobs:<count>:<digest>` command it names.
380
380
  - **Receipt:** `blobs.rows` has one row per request, keyed by file and request id: `committed`,
381
381
  `conflict`, `refused`, `unknown` or `held`. `blobs.counts` totals them. An `unknown` row is
382
- looked up by the same request on the next sync; it is never sent twice.
382
+ looked up by the same request on the next sync; it is never sent twice. A `refused` row whose
383
+ `result.error.code` is `path_collision` is a new file whose path, or one of its folders, differs
384
+ from an existing document or file only by letter case or Unicode form; nothing was written, and
385
+ sync exits 5. Rename the file or folder to a distinct path, then promote it again.
383
386
  - **Conflicts:** after a `conflict` row (the host's version changed), the file is held until it is
384
387
  resolved. `superbee sync --inspect --doc <key>` shows the recorded versions and MIME types.
385
388
  `superbee sync --resolve keep --doc <key>` keeps your file: the next sync sends it as it is over