@mulmoclaude/core 1.13.0 → 1.14.1

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 (156) hide show
  1. package/assets/helps/error-recovery.md +12 -1
  2. package/dist/atomic-C_7YpMiM.cjs.map +1 -1
  3. package/dist/atomic-DPpdrJzO.js.map +1 -1
  4. package/dist/{calendarGrid-CrGxeCOG.js → calendarGrid-Csy2rpjp.js} +65 -36
  5. package/dist/{calendarGrid-CrGxeCOG.js.map → calendarGrid-Csy2rpjp.js.map} +1 -1
  6. package/dist/{calendarGrid-CaS9er8i.cjs → calendarGrid-p8K-7cuB.cjs} +65 -36
  7. package/dist/{calendarGrid-CaS9er8i.cjs.map → calendarGrid-p8K-7cuB.cjs.map} +1 -1
  8. package/dist/collection/core/actionVisible.d.ts +3 -3
  9. package/dist/collection/core/completion.d.ts +5 -5
  10. package/dist/collection/core/schemaZ.d.ts +4 -4
  11. package/dist/collection/index.cjs +7 -10
  12. package/dist/collection/index.cjs.map +1 -1
  13. package/dist/collection/index.js +7 -10
  14. package/dist/collection/index.js.map +1 -1
  15. package/dist/collection/registry/registryIndex.d.ts +1 -1
  16. package/dist/collection/registry/server/index.cjs +15 -13
  17. package/dist/collection/registry/server/index.cjs.map +1 -1
  18. package/dist/collection/registry/server/index.js +15 -13
  19. package/dist/collection/registry/server/index.js.map +1 -1
  20. package/dist/collection/server/csvQuery.d.ts +7 -2
  21. package/dist/collection/server/csvStore.d.ts +2 -1
  22. package/dist/collection/server/discovery.d.ts +2 -2
  23. package/dist/collection/server/index.cjs +3 -3
  24. package/dist/collection/server/index.js +3 -3
  25. package/dist/collection/server/io.d.ts +3 -3
  26. package/dist/collection/server/manageTool.d.ts +3 -3
  27. package/dist/collection/server/store.d.ts +3 -3
  28. package/dist/collection/server/validate.d.ts +1 -1
  29. package/dist/collection-watchers/index.cjs +10 -25
  30. package/dist/collection-watchers/index.cjs.map +1 -1
  31. package/dist/collection-watchers/index.js +10 -25
  32. package/dist/collection-watchers/index.js.map +1 -1
  33. package/dist/{discovery-D-ZJ6a6z.js → discovery-BSedPW8A.js} +64 -36
  34. package/dist/discovery-BSedPW8A.js.map +1 -0
  35. package/dist/{discovery-DAoMnBYM.cjs → discovery-DSLgRQhN.cjs} +64 -36
  36. package/dist/discovery-DSLgRQhN.cjs.map +1 -0
  37. package/dist/{dist-21pMsI1a.cjs → dist-CsgSfWwR.cjs} +22 -1
  38. package/dist/{dist-21pMsI1a.cjs.map → dist-CsgSfWwR.cjs.map} +1 -1
  39. package/dist/{dist-DP1FTGnO.js → dist-D8zokgGo.js} +11 -2
  40. package/dist/{dist-DP1FTGnO.js.map → dist-D8zokgGo.js.map} +1 -1
  41. package/dist/feeds/index.cjs +2 -2
  42. package/dist/feeds/index.js +2 -2
  43. package/dist/feeds/server/host.d.ts +2 -2
  44. package/dist/feeds/server/index.cjs +35 -29
  45. package/dist/feeds/server/index.cjs.map +1 -1
  46. package/dist/feeds/server/index.js +35 -29
  47. package/dist/feeds/server/index.js.map +1 -1
  48. package/dist/feeds/server/refreshResult.d.ts +2 -2
  49. package/dist/files/index.cjs +3 -2
  50. package/dist/files/index.cjs.map +1 -1
  51. package/dist/files/index.js +3 -2
  52. package/dist/files/index.js.map +1 -1
  53. package/dist/google/calendar.d.ts +47 -33
  54. package/dist/google/collectionPush.d.ts +13 -8
  55. package/dist/google/collectionSync.d.ts +2 -2
  56. package/dist/google/index.cjs +63 -38
  57. package/dist/google/index.cjs.map +1 -1
  58. package/dist/google/index.d.ts +2 -2
  59. package/dist/google/index.js +61 -38
  60. package/dist/google/index.js.map +1 -1
  61. package/dist/{graph-DjE1Az1C.cjs → graph-BZJxiv1E.cjs} +10 -12
  62. package/dist/graph-BZJxiv1E.cjs.map +1 -0
  63. package/dist/{graph-BcwqiSpR.js → graph-Ce7xsDTt.js} +10 -12
  64. package/dist/graph-Ce7xsDTt.js.map +1 -0
  65. package/dist/{ingestTypes-D1GQdG8e.cjs → ingestTypes-CPR-h-OZ.cjs} +2 -2
  66. package/dist/{ingestTypes-D1GQdG8e.cjs.map → ingestTypes-CPR-h-OZ.cjs.map} +1 -1
  67. package/dist/{ingestTypes-XReG-li7.js → ingestTypes-F2IJhOLJ.js} +2 -2
  68. package/dist/{ingestTypes-XReG-li7.js.map → ingestTypes-F2IJhOLJ.js.map} +1 -1
  69. package/dist/notifier/index.cjs +1 -1
  70. package/dist/notifier/index.js +1 -1
  71. package/dist/notifier/types.d.ts +4 -4
  72. package/dist/{notifier-C3IhYxqh.cjs → notifier-CKFVVwDP.cjs} +36 -25
  73. package/dist/notifier-CKFVVwDP.cjs.map +1 -0
  74. package/dist/{notifier-CMFlw74b.js → notifier-CQD8NljP.js} +36 -25
  75. package/dist/notifier-CQD8NljP.js.map +1 -0
  76. package/dist/plugin-vue/index.cjs +4 -2
  77. package/dist/plugin-vue/index.cjs.map +1 -1
  78. package/dist/plugin-vue/index.js +4 -2
  79. package/dist/plugin-vue/index.js.map +1 -1
  80. package/dist/{project-B9NSyr6L.js → project-B0j_Vf_Q.js} +7 -2
  81. package/dist/project-B0j_Vf_Q.js.map +1 -0
  82. package/dist/{project-CCtT_fQr.cjs → project-C1ep9pvo.cjs} +7 -2
  83. package/dist/project-C1ep9pvo.cjs.map +1 -0
  84. package/dist/{promptSafety-FD8cQn3e.cjs → promptSafety-DUZ5BiW5.cjs} +106 -88
  85. package/dist/promptSafety-DUZ5BiW5.cjs.map +1 -0
  86. package/dist/{promptSafety-C--op_6a.js → promptSafety-DgHMF4Pz.js} +106 -88
  87. package/dist/promptSafety-DgHMF4Pz.js.map +1 -0
  88. package/dist/remote-host/index.cjs +2 -1
  89. package/dist/remote-host/index.d.ts +10 -0
  90. package/dist/remote-host/index.js +2 -2
  91. package/dist/remote-host/server/hostRunner.d.ts +7 -2
  92. package/dist/remote-host/server/index.cjs +14 -11
  93. package/dist/remote-host/server/index.cjs.map +1 -1
  94. package/dist/remote-host/server/index.js +13 -10
  95. package/dist/remote-host/server/index.js.map +1 -1
  96. package/dist/{remote-host-DkDVxNim.cjs → remote-host-CtQjagPt.cjs} +53 -1
  97. package/dist/remote-host-CtQjagPt.cjs.map +1 -0
  98. package/dist/remote-host-Dba4lF3Z.js +82 -0
  99. package/dist/remote-host-Dba4lF3Z.js.map +1 -0
  100. package/dist/remote-view/index.cjs +6 -4
  101. package/dist/remote-view/index.cjs.map +1 -1
  102. package/dist/remote-view/index.d.ts +1 -1
  103. package/dist/remote-view/index.js +6 -4
  104. package/dist/remote-view/index.js.map +1 -1
  105. package/dist/scheduler/adapter.d.ts +4 -4
  106. package/dist/scheduler/index.cjs +35 -3
  107. package/dist/scheduler/index.cjs.map +1 -1
  108. package/dist/scheduler/index.js +35 -3
  109. package/dist/scheduler/index.js.map +1 -1
  110. package/dist/scheduler/task-manager.d.ts +2 -2
  111. package/dist/{server-B_b0bLSW.cjs → server-1c6gB372.cjs} +54 -31
  112. package/dist/server-1c6gB372.cjs.map +1 -0
  113. package/dist/{server-Ci_A3chZ.js → server-Dv_L7l0y.js} +54 -31
  114. package/dist/server-Dv_L7l0y.js.map +1 -0
  115. package/dist/skill-bridge/index.cjs +3 -4
  116. package/dist/skill-bridge/index.cjs.map +1 -1
  117. package/dist/skill-bridge/index.js +3 -4
  118. package/dist/skill-bridge/index.js.map +1 -1
  119. package/dist/types-BKVZrtyc.js.map +1 -1
  120. package/dist/types-CNqkLT4M.cjs.map +1 -1
  121. package/dist/utils/fetch.cjs.map +1 -1
  122. package/dist/utils/fetch.d.ts +1 -1
  123. package/dist/utils/fetch.js.map +1 -1
  124. package/dist/utils/index.cjs +1 -1
  125. package/dist/utils/index.js +1 -1
  126. package/dist/whisper/client.cjs.map +1 -1
  127. package/dist/whisper/client.d.ts +3 -3
  128. package/dist/whisper/client.js.map +1 -1
  129. package/dist/whisper/index.cjs +2 -6
  130. package/dist/whisper/index.cjs.map +1 -1
  131. package/dist/whisper/index.js +2 -6
  132. package/dist/whisper/index.js.map +1 -1
  133. package/dist/wiki/index.cjs +4 -4
  134. package/dist/wiki/index.cjs.map +1 -1
  135. package/dist/wiki/index.js +4 -4
  136. package/dist/wiki/index.js.map +1 -1
  137. package/dist/wiki/server/index.cjs +15 -12
  138. package/dist/wiki/server/index.cjs.map +1 -1
  139. package/dist/wiki/server/index.js +15 -12
  140. package/dist/wiki/server/index.js.map +1 -1
  141. package/package.json +6 -6
  142. package/dist/discovery-D-ZJ6a6z.js.map +0 -1
  143. package/dist/discovery-DAoMnBYM.cjs.map +0 -1
  144. package/dist/graph-BcwqiSpR.js.map +0 -1
  145. package/dist/graph-DjE1Az1C.cjs.map +0 -1
  146. package/dist/notifier-C3IhYxqh.cjs.map +0 -1
  147. package/dist/notifier-CMFlw74b.js.map +0 -1
  148. package/dist/project-B9NSyr6L.js.map +0 -1
  149. package/dist/project-CCtT_fQr.cjs.map +0 -1
  150. package/dist/promptSafety-C--op_6a.js.map +0 -1
  151. package/dist/promptSafety-FD8cQn3e.cjs.map +0 -1
  152. package/dist/remote-host-D_BRFHcI.js +0 -36
  153. package/dist/remote-host-D_BRFHcI.js.map +0 -1
  154. package/dist/remote-host-DkDVxNim.cjs.map +0 -1
  155. package/dist/server-B_b0bLSW.cjs.map +0 -1
  156. package/dist/server-Ci_A3chZ.js.map +0 -1
@@ -1,9 +1,9 @@
1
- import { t as errorMessage } from "./dist-DP1FTGnO.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-D-ZJ6a6z.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-Csy2rpjp.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-DgHMF4Pz.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-BSedPW8A.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
@@ -1338,6 +1341,7 @@ var CORE_SECTION_PATTERNS = [
1338
1341
  * heading "External data (CSV) collections — `dataSource`". */
1339
1342
  var normalize = (text) => text.toLowerCase().replace(/`/g, "");
1340
1343
  var sliceLines = (lines, from, until) => lines.slice(from, until).join("\n").trim();
1344
+ var HEADING_PATTERN = /^(#{1,3}) (.+)$/;
1341
1345
  /** All `#`–`###` headings, skipping fenced code blocks (a `# comment`
1342
1346
  * inside an example must not become a section boundary). */
1343
1347
  function headingLines(lines) {
@@ -1345,11 +1349,14 @@ function headingLines(lines) {
1345
1349
  let fenced = false;
1346
1350
  lines.forEach((line, index) => {
1347
1351
  if (line.trimStart().startsWith("```")) fenced = !fenced;
1348
- const match = fenced ? null : /^(#{1,3}) (.+)$/.exec(line);
1349
- if (match) found.push({
1352
+ if (fenced) return;
1353
+ const match = HEADING_PATTERN.exec(line);
1354
+ if (!match) return;
1355
+ const [, hashes = "", heading = ""] = match;
1356
+ found.push({
1350
1357
  index,
1351
- level: match[1].length,
1352
- heading: match[2].trim()
1358
+ level: hashes.length,
1359
+ heading: heading.trim()
1353
1360
  });
1354
1361
  });
1355
1362
  return found;
@@ -1475,7 +1482,7 @@ function unknownCollection(slug) {
1475
1482
  }
1476
1483
  function optionalStringArray(value, name) {
1477
1484
  if (value === void 0) return { ok: true };
1478
- if (!Array.isArray(value) || !value.every((entry) => typeof entry === "string" && entry.length > 0)) return {
1485
+ if (!isStringArray(value) || !value.every((entry) => entry.length > 0)) return {
1479
1486
  ok: false,
1480
1487
  error: `manageCollection: \`${name}\` must be an array of non-empty strings when present.`
1481
1488
  };
@@ -1526,11 +1533,12 @@ async function loadRequestedItems(collection, ids, deps) {
1526
1533
  };
1527
1534
  }
1528
1535
  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.`;
1536
+ const { ids, fields } = args;
1537
+ const { items, missing } = await loadRequestedItems(collection, ids, deps);
1538
+ 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
1539
  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;
1540
+ const projected = fields ? enriched.map((item) => projectFields(item, fields, collection.schema.primaryKey)) : enriched;
1541
+ const warning = !ids || missing.length > 0 ? await recordIssuesWarning(collection, deps) : void 0;
1534
1542
  return JSON.stringify({
1535
1543
  collection: collection.slug,
1536
1544
  count: projected.length,
@@ -1685,17 +1693,32 @@ async function deleteOneItem(removeItem, itemId) {
1685
1693
  }
1686
1694
  function parseDeleteIds(args) {
1687
1695
  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.";
1696
+ 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
1697
  return ids;
1690
1698
  }
1699
+ var PUT_MODES = [
1700
+ "upsert",
1701
+ "create",
1702
+ "merge"
1703
+ ];
1704
+ /** The requested write mode, defaulting when absent, or null when the caller
1705
+ * named a mode that doesn't exist. */
1706
+ function parsePutMode(mode) {
1707
+ if (mode === void 0) return "upsert";
1708
+ return PUT_MODES.find((candidate) => candidate === mode) ?? null;
1709
+ }
1710
+ function isRecordArray(value) {
1711
+ return isUnknownArray(value) && value.every(isRecord);
1712
+ }
1691
1713
  function parsePutItems(args, slug) {
1692
1714
  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\".";
1715
+ if (!isRecordArray(items) || items.length === 0) return "manageCollection: `items` is required for putItems — a non-empty array of record objects.";
1716
+ const putMode = parsePutMode(mode);
1717
+ if (putMode === null) return "manageCollection: `mode` must be \"upsert\" (default), \"create\", or \"merge\".";
1695
1718
  return {
1696
1719
  slug,
1697
1720
  items,
1698
- mode: mode ?? "upsert"
1721
+ mode: putMode
1699
1722
  };
1700
1723
  }
1701
1724
  /** The machine-readable workspace ontology: every collection with its
@@ -1928,4 +1951,4 @@ function makeManageCollectionTool(deps = {}) {
1928
1951
  //#endregion
1929
1952
  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
1953
 
1931
- //# sourceMappingURL=server-Ci_A3chZ.js.map
1954
+ //# sourceMappingURL=server-Dv_L7l0y.js.map