@mulmoclaude/core 2.1.0 → 3.0.0

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 (35) hide show
  1. package/dist/collection/registry/server/client.d.ts +4 -4
  2. package/dist/collection/registry/server/collectionFiles.d.ts +3 -2
  3. package/dist/collection/registry/server/importCollection.d.ts +3 -2
  4. package/dist/collection/registry/server/index.cjs +27 -26
  5. package/dist/collection/registry/server/index.cjs.map +1 -1
  6. package/dist/collection/registry/server/index.d.ts +3 -2
  7. package/dist/collection/registry/server/index.js +27 -26
  8. package/dist/collection/registry/server/index.js.map +1 -1
  9. package/dist/collection/registry/server/registriesConfig.d.ts +11 -4
  10. package/dist/collection/server/host.d.ts +42 -5
  11. package/dist/collection/server/index.cjs +5 -3
  12. package/dist/collection/server/index.d.ts +1 -1
  13. package/dist/collection/server/index.js +3 -3
  14. package/dist/collection/server/paths.d.ts +0 -3
  15. package/dist/collection-watchers/index.cjs +79 -12
  16. package/dist/collection-watchers/index.cjs.map +1 -1
  17. package/dist/collection-watchers/index.d.ts +1 -1
  18. package/dist/collection-watchers/index.js +79 -13
  19. package/dist/collection-watchers/index.js.map +1 -1
  20. package/dist/collection-watchers/watcher.d.ts +23 -4
  21. package/dist/{discovery-BvnXyUel.js → discovery-4Z-ZWFam.js} +50 -21
  22. package/dist/discovery-4Z-ZWFam.js.map +1 -0
  23. package/dist/{discovery-B_sHig7n.cjs → discovery-CtiZMlsX.cjs} +67 -26
  24. package/dist/discovery-CtiZMlsX.cjs.map +1 -0
  25. package/dist/feeds/server/index.cjs +2 -2
  26. package/dist/feeds/server/index.js +2 -2
  27. package/dist/google/index.cjs +1 -1
  28. package/dist/google/index.js +1 -1
  29. package/dist/{server-DJt6USBQ.js → server-CedIocRS.js} +2 -2
  30. package/dist/{server-DJt6USBQ.js.map → server-CedIocRS.js.map} +1 -1
  31. package/dist/{server-DoyGZMPS.cjs → server-DOZFzx5l.cjs} +2 -2
  32. package/dist/{server-DoyGZMPS.cjs.map → server-DOZFzx5l.cjs.map} +1 -1
  33. package/package.json +1 -1
  34. package/dist/discovery-B_sHig7n.cjs.map +0 -1
  35. package/dist/discovery-BvnXyUel.js.map +0 -1
@@ -45,6 +45,22 @@ function createForwardingLogger(getLogger) {
45
45
  }
46
46
  //#endregion
47
47
  //#region src/collection/server/host.ts
48
+ /** `err.code` on the throw from `getWorkspaceRoot()` under an explicit-root
49
+ * binding: this CALL is missing its `workspaceRoot` option. Exported because
50
+ * the fix differs from a watcher root conflict — that one means another root's
51
+ * watcher is already running — and a host catching both in one place should
52
+ * not have to match on message text to tell them apart. */
53
+ var COLLECTION_ROOT_REQUIRED = "COLLECTION_ROOT_REQUIRED";
54
+ /** Build a change payload, attaching `root` only when the engine call carried
55
+ * an explicit one. Centralised so every publish site states the root the same
56
+ * way, and so a single-workspace host's payload shape stays byte-identical to
57
+ * what it saw before multi-root support. */
58
+ function collectionChangePayload(base, root) {
59
+ return root === void 0 ? base : {
60
+ ...base,
61
+ root
62
+ };
63
+ }
48
64
  var hostSlot = createHostSlot("@mulmoclaude/core/collection/server: configureCollectionHost()");
49
65
  var changePublisher = null;
50
66
  /** Wire the engine to a host. Call once at server startup, before any
@@ -73,9 +89,23 @@ function publishCollectionChange(payload) {
73
89
  function requireHost() {
74
90
  return hostSlot.get();
75
91
  }
76
- /** The configured workspace root. Throws if the host never configured one. */
92
+ /** The configured workspace root. Throws if the host never configured one —
93
+ * and, under an explicit-root binding (`workspaceRoot: null`), throws rather
94
+ * than guessing, which is the whole point of that mode: on a multi-root host
95
+ * a missing `opts.workspaceRoot` must fail loudly instead of silently
96
+ * resolving against some other project. */
77
97
  function getWorkspaceRoot() {
78
- return requireHost().workspaceRoot;
98
+ const root = requireHost().workspaceRoot;
99
+ if (root === null) throw Object.assign(/* @__PURE__ */ new Error("@mulmoclaude/core/collection/server: the host is bound in explicit-root mode (workspaceRoot: null), so there is no ambient workspace root — pass an explicit `workspaceRoot` in this call's options."), { code: COLLECTION_ROOT_REQUIRED });
100
+ return root;
101
+ }
102
+ /** The configured workspace root, or `null` under an explicit-root binding /
103
+ * before the host configures one. Never throws — for callers that need to
104
+ * COMPARE roots (is this the one we are already running for?) rather than
105
+ * operate on one. Anything that will touch the filesystem wants
106
+ * `getWorkspaceRoot()` and its loud failure instead. */
107
+ function peekWorkspaceRoot() {
108
+ return hostSlot.peek()?.workspaceRoot ?? null;
79
109
  }
80
110
  function userSkillsDir() {
81
111
  return requireHost().paths.userSkillsDir;
@@ -92,10 +122,11 @@ function skillsStagingDir(workspaceRoot) {
92
122
  function archiveDir() {
93
123
  return requireHost().paths.archiveDir;
94
124
  }
95
- /** Absolute path to the configured workspace's `collections-registries.json`. */
96
- function collectionsRegistriesConfigPath() {
97
- const host = requireHost();
98
- return host.paths.collectionsRegistriesConfig(host.workspaceRoot);
125
+ /** Absolute path to a workspace's `collections-registries.json`. Takes the
126
+ * root explicitly — reading the ambient one here would throw under an
127
+ * explicit-root binding and take the Discover tab down with it. */
128
+ function collectionsRegistriesConfigPath(workspaceRoot) {
129
+ return requireHost().paths.collectionsRegistriesConfig(workspaceRoot);
99
130
  }
100
131
  function isPresetSlug(slug) {
101
132
  return requireHost().isPresetSlug(slug);
@@ -174,11 +205,6 @@ function isContainedInRoot(absPath, rootPath) {
174
205
  if (ancestorReal === rootReal) return true;
175
206
  return ancestorReal.startsWith(rootReal + node_path.default.sep);
176
207
  }
177
- /** Workspace-bound convenience over `isContainedInRoot`. Production
178
- * callers use this; the tests exercise the pure helper. */
179
- function isContainedInWorkspace(absPath) {
180
- return isContainedInRoot(absPath, getWorkspaceRoot());
181
- }
182
208
  /** Resolve a schema-declared dataPath against `rootPath` (default:
183
209
  * the live workspace), refusing anything that escapes — absolute
184
210
  * paths, `..`-segments, empty string, or symlinks pointing outside
@@ -386,11 +412,11 @@ async function writeItem(dataDir, itemId, item, opts = {}) {
386
412
  await handle.close();
387
413
  }
388
414
  } else await require_atomic.writeFileAtomic(filePath, payload);
389
- if (opts.slug) publishCollectionChange({
415
+ if (opts.slug) publishCollectionChange(collectionChangePayload({
390
416
  slug: opts.slug,
391
417
  ids: [safeId],
392
418
  op: "upsert"
393
- });
419
+ }, opts.workspaceRoot));
394
420
  return {
395
421
  kind: "ok",
396
422
  itemId: safeId,
@@ -410,11 +436,11 @@ async function deleteItem(dataDir, itemId, opts = {}) {
410
436
  const filePath = itemFilePath(dataDir, safeId);
411
437
  try {
412
438
  await (0, node_fs_promises.unlink)(filePath);
413
- if (opts.slug) publishCollectionChange({
439
+ if (opts.slug) publishCollectionChange(collectionChangePayload({
414
440
  slug: opts.slug,
415
441
  ids: [safeId],
416
442
  op: "delete"
417
- });
443
+ }, opts.workspaceRoot));
418
444
  return {
419
445
  kind: "ok",
420
446
  itemId: safeId
@@ -1240,11 +1266,11 @@ async function sqliteWrite(absPath, itemId, item, opts) {
1240
1266
  item
1241
1267
  };
1242
1268
  });
1243
- if (outcome.kind === "ok" && opts.slug) publishCollectionChange({
1269
+ if (outcome.kind === "ok" && opts.slug) publishCollectionChange(collectionChangePayload({
1244
1270
  slug: opts.slug,
1245
1271
  ids: [safeId],
1246
1272
  op: "upsert"
1247
- });
1273
+ }, opts.publishRoot));
1248
1274
  return outcome;
1249
1275
  }
1250
1276
  async function sqliteDelete(absPath, itemId, opts) {
@@ -1269,11 +1295,11 @@ async function sqliteDelete(absPath, itemId, opts) {
1269
1295
  itemId: safeId
1270
1296
  };
1271
1297
  });
1272
- if (outcome.kind === "ok" && opts.slug) publishCollectionChange({
1298
+ if (outcome.kind === "ok" && opts.slug) publishCollectionChange(collectionChangePayload({
1273
1299
  slug: opts.slug,
1274
1300
  ids: [safeId],
1275
1301
  op: "delete"
1276
- });
1302
+ }, opts.publishRoot));
1277
1303
  return outcome;
1278
1304
  }
1279
1305
  /** Best-effort full WAL checkpoint so the MAIN db file alone is a
@@ -1304,6 +1330,7 @@ function sqliteStoreFor(collection, opts) {
1304
1330
  const key = collection.schema.primaryKey;
1305
1331
  const slug = opts.slug ?? collection.slug;
1306
1332
  const root = () => opts.workspaceRoot ?? getWorkspaceRoot();
1333
+ const publishRoot = opts.workspaceRoot;
1307
1334
  if (file === void 0) return {
1308
1335
  capabilities: {
1309
1336
  writable: false,
@@ -1329,11 +1356,13 @@ function sqliteStoreFor(collection, opts) {
1329
1356
  read: (itemId) => sqliteRead(file, itemId, root()),
1330
1357
  write: (itemId, item, writeOpts = {}) => sqliteWrite(file, itemId, item, {
1331
1358
  workspaceRoot: root(),
1359
+ publishRoot,
1332
1360
  slug,
1333
1361
  refuseOverwrite: writeOpts.refuseOverwrite
1334
1362
  }),
1335
1363
  delete: (itemId) => sqliteDelete(file, itemId, {
1336
1364
  workspaceRoot: root(),
1365
+ publishRoot,
1337
1366
  slug
1338
1367
  }),
1339
1368
  watch: async (onChange) => closerFor(await watchSingleFile(file, (base, name) => name.startsWith(base), () => onChange({ kind: "collection" })))
@@ -2730,6 +2759,12 @@ Object.defineProperty(exports, "BackendUnavailableError", {
2730
2759
  return BackendUnavailableError;
2731
2760
  }
2732
2761
  });
2762
+ Object.defineProperty(exports, "COLLECTION_ROOT_REQUIRED", {
2763
+ enumerable: true,
2764
+ get: function() {
2765
+ return COLLECTION_ROOT_REQUIRED;
2766
+ }
2767
+ });
2733
2768
  Object.defineProperty(exports, "CollectionQueryZ", {
2734
2769
  enumerable: true,
2735
2770
  get: function() {
@@ -2790,6 +2825,12 @@ Object.defineProperty(exports, "checkpointSqliteDatabase", {
2790
2825
  return checkpointSqliteDatabase;
2791
2826
  }
2792
2827
  });
2828
+ Object.defineProperty(exports, "collectionChangePayload", {
2829
+ enumerable: true,
2830
+ get: function() {
2831
+ return collectionChangePayload;
2832
+ }
2833
+ });
2793
2834
  Object.defineProperty(exports, "collectionWritable", {
2794
2835
  enumerable: true,
2795
2836
  get: function() {
@@ -2892,12 +2933,6 @@ Object.defineProperty(exports, "isContainedInRoot", {
2892
2933
  return isContainedInRoot;
2893
2934
  }
2894
2935
  });
2895
- Object.defineProperty(exports, "isContainedInWorkspace", {
2896
- enumerable: true,
2897
- get: function() {
2898
- return isContainedInWorkspace;
2899
- }
2900
- });
2901
2936
  Object.defineProperty(exports, "isPresetSlug", {
2902
2937
  enumerable: true,
2903
2938
  get: function() {
@@ -2946,6 +2981,12 @@ Object.defineProperty(exports, "pageFromFullRead", {
2946
2981
  return pageFromFullRead;
2947
2982
  }
2948
2983
  });
2984
+ Object.defineProperty(exports, "peekWorkspaceRoot", {
2985
+ enumerable: true,
2986
+ get: function() {
2987
+ return peekWorkspaceRoot;
2988
+ }
2989
+ });
2949
2990
  Object.defineProperty(exports, "projectItemFields", {
2950
2991
  enumerable: true,
2951
2992
  get: function() {
@@ -3055,4 +3096,4 @@ Object.defineProperty(exports, "writeItem", {
3055
3096
  }
3056
3097
  });
3057
3098
 
3058
- //# sourceMappingURL=discovery-B_sHig7n.cjs.map
3099
+ //# sourceMappingURL=discovery-CtiZMlsX.cjs.map