@mulmoclaude/core 1.12.0 → 1.14.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 (117) hide show
  1. package/assets/helps/error-recovery.md +110 -1
  2. package/dist/{calendarGrid-CaS9er8i.cjs → calendarGrid-BQYqOCnF.cjs} +8 -9
  3. package/dist/{calendarGrid-CaS9er8i.cjs.map → calendarGrid-BQYqOCnF.cjs.map} +1 -1
  4. package/dist/{calendarGrid-CrGxeCOG.js → calendarGrid-DivcNKkX.js} +8 -9
  5. package/dist/{calendarGrid-CrGxeCOG.js.map → calendarGrid-DivcNKkX.js.map} +1 -1
  6. package/dist/collection/core/project.d.ts +11 -0
  7. package/dist/collection/core/schemaZ.d.ts +4 -4
  8. package/dist/collection/index.cjs +5 -4
  9. package/dist/collection/index.js +5 -5
  10. package/dist/collection/registry/server/index.cjs +3 -3
  11. package/dist/collection/registry/server/index.cjs.map +1 -1
  12. package/dist/collection/registry/server/index.js +3 -3
  13. package/dist/collection/registry/server/index.js.map +1 -1
  14. package/dist/collection/server/csvQuery.d.ts +7 -2
  15. package/dist/collection/server/csvStore.d.ts +2 -1
  16. package/dist/collection/server/index.cjs +3 -3
  17. package/dist/collection/server/index.js +3 -3
  18. package/dist/collection-watchers/index.cjs +10 -25
  19. package/dist/collection-watchers/index.cjs.map +1 -1
  20. package/dist/collection-watchers/index.js +10 -25
  21. package/dist/collection-watchers/index.js.map +1 -1
  22. package/dist/{discovery-NRy3tyUA.cjs → discovery-CRDx6TS4.cjs} +88 -47
  23. package/dist/discovery-CRDx6TS4.cjs.map +1 -0
  24. package/dist/{discovery-B4CZvrXR.js → discovery-D6p4ITNR.js} +88 -47
  25. package/dist/discovery-D6p4ITNR.js.map +1 -0
  26. package/dist/{dist-pWpC-b04.cjs → dist-CsgSfWwR.cjs} +66 -1
  27. package/dist/{dist-pWpC-b04.cjs.map → dist-CsgSfWwR.cjs.map} +1 -1
  28. package/dist/{dist-Cwk0e12G.js → dist-D8zokgGo.js} +25 -2
  29. package/dist/{dist-Cwk0e12G.js.map → dist-D8zokgGo.js.map} +1 -1
  30. package/dist/feeds/index.cjs +2 -2
  31. package/dist/feeds/index.js +2 -2
  32. package/dist/feeds/server/engine.d.ts +27 -0
  33. package/dist/feeds/server/index.cjs +97 -26
  34. package/dist/feeds/server/index.cjs.map +1 -1
  35. package/dist/feeds/server/index.d.ts +1 -1
  36. package/dist/feeds/server/index.js +96 -27
  37. package/dist/feeds/server/index.js.map +1 -1
  38. package/dist/google/calendar.d.ts +23 -9
  39. package/dist/google/calendarStateLock.d.ts +23 -0
  40. package/dist/google/collectionProjection.d.ts +0 -8
  41. package/dist/google/collectionPush.d.ts +13 -8
  42. package/dist/google/collectionSync.d.ts +80 -10
  43. package/dist/google/index.cjs +366 -98
  44. package/dist/google/index.cjs.map +1 -1
  45. package/dist/google/index.d.ts +6 -4
  46. package/dist/google/index.js +357 -99
  47. package/dist/google/index.js.map +1 -1
  48. package/dist/{ingestTypes-D1GQdG8e.cjs → ingestTypes-C7IJSqv4.cjs} +2 -2
  49. package/dist/{ingestTypes-D1GQdG8e.cjs.map → ingestTypes-C7IJSqv4.cjs.map} +1 -1
  50. package/dist/{ingestTypes-XReG-li7.js → ingestTypes-DmtDLRmt.js} +2 -2
  51. package/dist/{ingestTypes-XReG-li7.js.map → ingestTypes-DmtDLRmt.js.map} +1 -1
  52. package/dist/notifier/index.cjs +1 -1
  53. package/dist/notifier/index.js +1 -1
  54. package/dist/notifier/store.d.ts +4 -4
  55. package/dist/{notifier-BdA5qzhe.js → notifier-Dxh8mEFh.js} +39 -25
  56. package/dist/notifier-Dxh8mEFh.js.map +1 -0
  57. package/dist/{notifier-tMsAXyXp.cjs → notifier-Wc4M24Bi.cjs} +39 -25
  58. package/dist/notifier-Wc4M24Bi.cjs.map +1 -0
  59. package/dist/plugin-vue/index.cjs +4 -2
  60. package/dist/plugin-vue/index.cjs.map +1 -1
  61. package/dist/plugin-vue/index.js +4 -2
  62. package/dist/plugin-vue/index.js.map +1 -1
  63. package/dist/project-B0j_Vf_Q.js +33 -0
  64. package/dist/project-B0j_Vf_Q.js.map +1 -0
  65. package/dist/project-C1ep9pvo.cjs +44 -0
  66. package/dist/project-C1ep9pvo.cjs.map +1 -0
  67. package/dist/{promptSafety-FD8cQn3e.cjs → promptSafety-B52GvaJc.cjs} +99 -85
  68. package/dist/promptSafety-B52GvaJc.cjs.map +1 -0
  69. package/dist/{promptSafety-C--op_6a.js → promptSafety-DJgaDjM4.js} +99 -85
  70. package/dist/promptSafety-DJgaDjM4.js.map +1 -0
  71. package/dist/remote-host/index.cjs +2 -1
  72. package/dist/remote-host/index.d.ts +10 -0
  73. package/dist/remote-host/index.js +2 -2
  74. package/dist/remote-host/server/index.cjs +2 -2
  75. package/dist/remote-host/server/index.cjs.map +1 -1
  76. package/dist/remote-host/server/index.js +2 -2
  77. package/dist/remote-host/server/index.js.map +1 -1
  78. package/dist/{remote-host-DkDVxNim.cjs → remote-host-CtQjagPt.cjs} +53 -1
  79. package/dist/remote-host-CtQjagPt.cjs.map +1 -0
  80. package/dist/remote-host-Dba4lF3Z.js +82 -0
  81. package/dist/remote-host-Dba4lF3Z.js.map +1 -0
  82. package/dist/remote-view/index.cjs +6 -4
  83. package/dist/remote-view/index.cjs.map +1 -1
  84. package/dist/remote-view/index.js +6 -4
  85. package/dist/remote-view/index.js.map +1 -1
  86. package/dist/scheduler/index.cjs +1 -1
  87. package/dist/scheduler/index.js +1 -1
  88. package/dist/{server-DdyIvFhz.js → server-D6EUf3BF.js} +46 -27
  89. package/dist/server-D6EUf3BF.js.map +1 -0
  90. package/dist/{server-7U-3DE2e.cjs → server-D7_oRbTJ.cjs} +46 -27
  91. package/dist/server-D7_oRbTJ.cjs.map +1 -0
  92. package/dist/utils/index.cjs +1 -1
  93. package/dist/utils/index.js +1 -1
  94. package/dist/whisper/index.cjs +2 -6
  95. package/dist/whisper/index.cjs.map +1 -1
  96. package/dist/whisper/index.js +2 -6
  97. package/dist/whisper/index.js.map +1 -1
  98. package/dist/wiki/index.cjs +2 -2
  99. package/dist/wiki/index.cjs.map +1 -1
  100. package/dist/wiki/index.js +2 -2
  101. package/dist/wiki/index.js.map +1 -1
  102. package/package.json +2 -2
  103. package/dist/discovery-B4CZvrXR.js.map +0 -1
  104. package/dist/discovery-NRy3tyUA.cjs.map +0 -1
  105. package/dist/notifier-BdA5qzhe.js.map +0 -1
  106. package/dist/notifier-tMsAXyXp.cjs.map +0 -1
  107. package/dist/project-BWI5w_BT.cjs +0 -17
  108. package/dist/project-BWI5w_BT.cjs.map +0 -1
  109. package/dist/project-bU98ycsy.js +0 -12
  110. package/dist/project-bU98ycsy.js.map +0 -1
  111. package/dist/promptSafety-C--op_6a.js.map +0 -1
  112. package/dist/promptSafety-FD8cQn3e.cjs.map +0 -1
  113. package/dist/remote-host-D_BRFHcI.js +0 -36
  114. package/dist/remote-host-D_BRFHcI.js.map +0 -1
  115. package/dist/remote-host-DkDVxNim.cjs.map +0 -1
  116. package/dist/server-7U-3DE2e.cjs.map +0 -1
  117. package/dist/server-DdyIvFhz.js.map +0 -1
@@ -1,9 +1,9 @@
1
- import { t as errorMessage } from "./dist-Cwk0e12G.js";
1
+ import { a as isErrorWithCode, c as isStringArray, l as isUnknownArray, s as isRecord, t as errorMessage } from "./dist-D8zokgGo.js";
2
2
  import { t as writeFileAtomic } from "./atomic-DPpdrJzO.js";
3
3
  import { n as toPosixRelPath } from "./relPath-DW8MC8VO.js";
4
- import { A as fieldTextOrNull, E as isFieldDrivenEvery, O as storageKindFor, S as COMPUTED_TYPES, T as embedTargetId, k as fieldText, l as parseIsoDate, u as parseIsoDateTime } from "./calendarGrid-CrGxeCOG.js";
5
- import { C as actionVisible, _ as uniqueRefTargets, b as projectBacklinkRow, c as selectDynamicRecord, f as itemIsDone, g as uniqueEmbedTargets, h as uniqueBacklinkSources, i as ownProp, n as deriveAll, o as firstDateField, s as resolveIcon, t as defangForPrompt, v as backlinkRows, x as rollupValue, y as coerceNumeric } from "./promptSafety-C--op_6a.js";
6
- import { $ as skillsStagingDir, F as resolveCreateItemId, G as archiveDir, H as resolveTemplatePath, J as getWorkspaceRoot, L as SCHEMA_FILE$1, M as isRegularFile, R as isContainedInRoot, S as queryCsv, T as CollectionQueryZ, V as resolveDataDir, W as safeSlugName, X as log, Y as isPresetSlug$1, c as resolveMutateSet, d as storeFor, f as checkpointSqliteDatabase, g as cacheDir, i as resolvePrimaryField, k as isBackendUnavailable, n as discoverCollections, r as loadCollection, s as CollectionSchemaZ, u as readOnlyRefusal, w as compileJsonlQuery, x as normalizeCsvValue } from "./discovery-B4CZvrXR.js";
4
+ import { A as fieldTextOrNull, E as isFieldDrivenEvery, O as storageKindFor, S as COMPUTED_TYPES, T as embedTargetId, k as fieldText, l as parseIsoDate, u as parseIsoDateTime } from "./calendarGrid-DivcNKkX.js";
5
+ import { C as actionVisible, _ as uniqueRefTargets, b as projectBacklinkRow, c as selectDynamicRecord, f as itemIsDone, g as uniqueEmbedTargets, h as uniqueBacklinkSources, i as ownProp, n as deriveAll, o as firstDateField, s as resolveIcon, t as defangForPrompt, v as backlinkRows, x as rollupValue, y as coerceNumeric } from "./promptSafety-DJgaDjM4.js";
6
+ import { $ as skillsStagingDir, F as resolveCreateItemId, G as archiveDir, H as resolveTemplatePath, J as getWorkspaceRoot, L as SCHEMA_FILE$1, M as isRegularFile, R as isContainedInRoot, S as queryCsv, T as CollectionQueryZ, V as resolveDataDir, W as safeSlugName, X as log, Y as isPresetSlug$1, c as resolveMutateSet, d as storeFor, f as checkpointSqliteDatabase, g as cacheDir, i as resolvePrimaryField, k as isBackendUnavailable, n as discoverCollections, r as loadCollection, s as CollectionSchemaZ, u as readOnlyRefusal, w as compileJsonlQuery, x as normalizeCsvValue } from "./discovery-D6p4ITNR.js";
7
7
  import { ingestStatePath } from "./feeds/paths.js";
8
8
  import { dataSkillDir, mirrorSkillWrite } from "./skill-bridge/index.js";
9
9
  import path from "node:path";
@@ -44,8 +44,8 @@ async function readSourceAwareFile(collection, relPath, opts) {
44
44
  try {
45
45
  return await readFile(resolved, "utf-8");
46
46
  } catch (err) {
47
- const { code } = err;
48
- if (code !== "ENOENT" && code !== "ENOTDIR") throw err;
47
+ if (!isErrorWithCode(err)) throw err;
48
+ if (err.code !== "ENOENT" && err.code !== "ENOTDIR") throw err;
49
49
  }
50
50
  }
51
51
  return null;
@@ -57,7 +57,7 @@ var EMPTY_I18N = {
57
57
  };
58
58
  function pickLocaleBlock(parsed, locale) {
59
59
  const block = parsed[locale];
60
- if (!block || typeof block !== "object" || Array.isArray(block)) return null;
60
+ if (!isRecord(block)) return null;
61
61
  const entries = Object.entries(block).filter((entry) => typeof entry[1] === "string");
62
62
  return Object.fromEntries(entries);
63
63
  }
@@ -77,7 +77,7 @@ async function readCustomViewI18n(collection, i18nFile, locale, opts = {}) {
77
77
  } catch {
78
78
  return EMPTY_I18N;
79
79
  }
80
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return EMPTY_I18N;
80
+ if (!isRecord(parsed)) return EMPTY_I18N;
81
81
  const obj = parsed;
82
82
  const primary = pickLocaleBlock(obj, locale);
83
83
  if (primary !== null && Object.keys(primary).length > 0) return {
@@ -264,7 +264,7 @@ async function runQueryOverRows(rows, query) {
264
264
  return (await queryCsv(sql, [jsonlPath, ...params])).map((row) => Object.fromEntries(Object.entries(row).map(([key, value]) => [key, normalizeCsvValue(value)])));
265
265
  } finally {
266
266
  await unlink(jsonlPath).catch((err) => {
267
- if (err.code !== "ENOENT") log.warn("collections", "temp JSONL cleanup failed", {
267
+ if (!isErrorWithCode(err) || err.code !== "ENOENT") log.warn("collections", "temp JSONL cleanup failed", {
268
268
  path: jsonlPath,
269
269
  error: String(err)
270
270
  });
@@ -407,7 +407,7 @@ function strictTableProblem(key, spec, value) {
407
407
  if (!Array.isArray(value)) return `'${key}' = '${String(value)}' is not an array of rows (a 'table' field stores an array of row objects)`;
408
408
  for (let index = 0; index < value.length; index++) {
409
409
  const row = value[index];
410
- if (!row || typeof row !== "object" || Array.isArray(row)) return `'${key}' row ${index + 1} is not an object`;
410
+ if (!isRecord(row)) return `'${key}' row ${index + 1} is not an object`;
411
411
  for (const [subKey, subSpec] of Object.entries(spec.of)) {
412
412
  const subValue = row[subKey];
413
413
  const problem = enforcedProblem(subKey, subSpec, subValue) ?? (isEmptyValue(subValue) ? null : strictTypeProblem(subKey, subSpec, subValue));
@@ -481,7 +481,7 @@ async function listRecordFilenames(dataDir, workspaceRoot) {
481
481
  try {
482
482
  return await readdir(dataDir);
483
483
  } catch (err) {
484
- if (err.code === "ENOENT") return [];
484
+ if (isErrorWithCode(err) && err.code === "ENOENT") return [];
485
485
  throw err;
486
486
  }
487
487
  }
@@ -555,7 +555,7 @@ async function inspectRecord(fullPath, name, schema) {
555
555
  problem: `invalid JSON (${err instanceof Error ? err.message : String(err)}) — SKIPPED, won't appear. Usual cause: an unescaped " inside a string value; use 「」/『』 or write \\" instead.`
556
556
  };
557
557
  }
558
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return {
558
+ if (!isRecord(parsed)) return {
559
559
  file: name,
560
560
  problem: "not a JSON object — skipped, won't appear"
561
561
  };
@@ -1215,8 +1215,8 @@ async function fileExists(target) {
1215
1215
  await stat(target);
1216
1216
  return true;
1217
1217
  } catch (err) {
1218
- const { code } = err;
1219
- if (code === "ENOENT" || code === "ENOTDIR") return false;
1218
+ if (!isErrorWithCode(err)) throw err;
1219
+ if (err.code === "ENOENT" || err.code === "ENOTDIR") return false;
1220
1220
  throw err;
1221
1221
  }
1222
1222
  }
@@ -1252,7 +1252,7 @@ async function unlinkIfPresent(target) {
1252
1252
  try {
1253
1253
  await unlink(target);
1254
1254
  } catch (err) {
1255
- if (err.code !== "ENOENT") throw err;
1255
+ if (!isErrorWithCode(err) || err.code !== "ENOENT") throw err;
1256
1256
  }
1257
1257
  }
1258
1258
  /** Re-read the canonical schema.json, drop the `views[]` entry, and write the
@@ -1263,8 +1263,11 @@ async function removeViewFromSchemas(collection, viewId, workspaceRoot, safeSlug
1263
1263
  const base = await canonicalBase(collection, workspaceRoot, safeSlug);
1264
1264
  const canonical = path.join(base, SCHEMA_FILE$1);
1265
1265
  const parsed = JSON.parse(await readFile(canonical, "utf-8"));
1266
- if (Array.isArray(parsed.views)) parsed.views = parsed.views.filter((entry) => entry?.id !== viewId);
1267
- const serialized = `${JSON.stringify(parsed, null, 2)}\n`;
1266
+ const next = isRecord(parsed) && isUnknownArray(parsed.views) ? {
1267
+ ...parsed,
1268
+ views: parsed.views.filter((entry) => !isRecord(entry) || entry.id !== viewId)
1269
+ } : parsed;
1270
+ const serialized = `${JSON.stringify(next, null, 2)}\n`;
1268
1271
  for (const target of await schemaWriteTargets(collection, workspaceRoot, safeSlug)) await writeFileAtomic(target, serialized);
1269
1272
  }
1270
1273
  /** Delete one custom view from `collection`: unlink its HTML file and drop it
@@ -1475,7 +1478,7 @@ function unknownCollection(slug) {
1475
1478
  }
1476
1479
  function optionalStringArray(value, name) {
1477
1480
  if (value === void 0) return { ok: true };
1478
- if (!Array.isArray(value) || !value.every((entry) => typeof entry === "string" && entry.length > 0)) return {
1481
+ if (!isStringArray(value) || !value.every((entry) => entry.length > 0)) return {
1479
1482
  ok: false,
1480
1483
  error: `manageCollection: \`${name}\` must be an array of non-empty strings when present.`
1481
1484
  };
@@ -1526,11 +1529,12 @@ async function loadRequestedItems(collection, ids, deps) {
1526
1529
  };
1527
1530
  }
1528
1531
  async function handleGetItems(collection, args, deps) {
1529
- const { items, missing } = await loadRequestedItems(collection, args.ids, deps);
1530
- if (!args.ids && !args.fields && items.length > 200) return `manageCollection: refused — '${collection.slug}' has ${items.length} records, over the unselective limit of 200. Pass \`ids\` for specific records or \`fields\` to project only the columns you need.`;
1532
+ const { ids, fields } = args;
1533
+ const { items, missing } = await loadRequestedItems(collection, ids, deps);
1534
+ if (!ids && !fields && items.length > 200) return `manageCollection: refused — '${collection.slug}' has ${items.length} records, over the unselective limit of 200. Pass \`ids\` for specific records or \`fields\` to project only the columns you need.`;
1531
1535
  const enriched = await enrichItems(collection, items, deps);
1532
- const projected = args.fields ? enriched.map((item) => projectFields(item, args.fields, collection.schema.primaryKey)) : enriched;
1533
- const warning = !args.ids || missing.length > 0 ? await recordIssuesWarning(collection, deps) : void 0;
1536
+ const projected = fields ? enriched.map((item) => projectFields(item, fields, collection.schema.primaryKey)) : enriched;
1537
+ const warning = !ids || missing.length > 0 ? await recordIssuesWarning(collection, deps) : void 0;
1534
1538
  return JSON.stringify({
1535
1539
  collection: collection.slug,
1536
1540
  count: projected.length,
@@ -1685,17 +1689,32 @@ async function deleteOneItem(removeItem, itemId) {
1685
1689
  }
1686
1690
  function parseDeleteIds(args) {
1687
1691
  const { ids } = args;
1688
- if (!(Array.isArray(ids) && ids.length > 0 && ids.every((entry) => typeof entry === "string" && entry.trim().length > 0))) return "manageCollection: `ids` is required for deleteItems — a non-empty array of record ids.";
1692
+ if (!(isStringArray(ids) && ids.length > 0 && ids.every((entry) => entry.trim().length > 0))) return "manageCollection: `ids` is required for deleteItems — a non-empty array of record ids.";
1689
1693
  return ids;
1690
1694
  }
1695
+ var PUT_MODES = [
1696
+ "upsert",
1697
+ "create",
1698
+ "merge"
1699
+ ];
1700
+ /** The requested write mode, defaulting when absent, or null when the caller
1701
+ * named a mode that doesn't exist. */
1702
+ function parsePutMode(mode) {
1703
+ if (mode === void 0) return "upsert";
1704
+ return PUT_MODES.find((candidate) => candidate === mode) ?? null;
1705
+ }
1706
+ function isRecordArray(value) {
1707
+ return isUnknownArray(value) && value.every(isRecord);
1708
+ }
1691
1709
  function parsePutItems(args, slug) {
1692
1710
  const { items, mode } = args;
1693
- if (!(Array.isArray(items) && items.length > 0 && items.every((entry) => Boolean(entry) && typeof entry === "object" && !Array.isArray(entry)))) return "manageCollection: `items` is required for putItems — a non-empty array of record objects.";
1694
- if (mode !== void 0 && mode !== "upsert" && mode !== "create" && mode !== "merge") return "manageCollection: `mode` must be \"upsert\" (default), \"create\", or \"merge\".";
1711
+ if (!isRecordArray(items) || items.length === 0) return "manageCollection: `items` is required for putItems — a non-empty array of record objects.";
1712
+ const putMode = parsePutMode(mode);
1713
+ if (putMode === null) return "manageCollection: `mode` must be \"upsert\" (default), \"create\", or \"merge\".";
1695
1714
  return {
1696
1715
  slug,
1697
1716
  items,
1698
- mode: mode ?? "upsert"
1717
+ mode: putMode
1699
1718
  };
1700
1719
  }
1701
1720
  /** The machine-readable workspace ontology: every collection with its
@@ -1928,4 +1947,4 @@ function makeManageCollectionTool(deps = {}) {
1928
1947
  //#endregion
1929
1948
  export { buildCollectionActionSeedPrompt as A, validateRecordObject as C, enrichItems as D, runCollectionQuery as E, readCustomViewHtml as M, readCustomViewI18n as N, runQueryOverRows as O, readSkillTemplate as P, validateCollectionRecords as S, recordFieldProblem as T, computeCollectionIcon as _, deleteCollection as a, applyMutateAction as b, computeSuccessor as c, isTriggerDue as d, maybeSpawnSuccessor as f, ONE_SECOND_MS as g, successorId as h, deleteCustomView as i, promptPathsFor as j, buildActionSeedPrompt as k, daysInMonth as l, resolveEvery as m, MAX_UNSELECTIVE_ITEMS as n, deleteCollectionRefusalMessage as o, parseCivil as p, makeManageCollectionTool as r, advanceTriggerDate as s, MAX_SCHEMA_ISSUES as t, formatCivil as u, buildWorkspaceOntology as v, compileRecordZ as w, firstMutateParamProblem as x, schemaRelations as y };
1930
1949
 
1931
- //# sourceMappingURL=server-DdyIvFhz.js.map
1950
+ //# sourceMappingURL=server-D6EUf3BF.js.map