@mulmoclaude/core 0.24.0 → 0.25.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 (76) hide show
  1. package/assets/helps/google-calendar-collection.md +79 -0
  2. package/assets/helps/index.md +1 -0
  3. package/dist/collection/core/schemaZ.d.ts +29 -0
  4. package/dist/collection/index.cjs +15 -14
  5. package/dist/collection/index.cjs.map +1 -1
  6. package/dist/collection/index.js +2 -1
  7. package/dist/collection/index.js.map +1 -1
  8. package/dist/collection/paths.cjs +5 -55
  9. package/dist/collection/paths.js +1 -51
  10. package/dist/collection/registry/server/index.cjs +20 -19
  11. package/dist/collection/registry/server/index.cjs.map +1 -1
  12. package/dist/collection/registry/server/index.js +3 -2
  13. package/dist/collection/registry/server/index.js.map +1 -1
  14. package/dist/collection/server/index.cjs +41 -40
  15. package/dist/collection/server/index.js +4 -3
  16. package/dist/collection-watchers/index.cjs +12 -11
  17. package/dist/collection-watchers/index.cjs.map +1 -1
  18. package/dist/collection-watchers/index.js +3 -2
  19. package/dist/collection-watchers/index.js.map +1 -1
  20. package/dist/discovery-3K_Wtkvn.js +1636 -0
  21. package/dist/discovery-3K_Wtkvn.js.map +1 -0
  22. package/dist/discovery-BZ2ms1tE.cjs +1865 -0
  23. package/dist/discovery-BZ2ms1tE.cjs.map +1 -0
  24. package/dist/feeds/index.cjs +4 -4
  25. package/dist/feeds/index.js +2 -2
  26. package/dist/feeds/server/index.cjs +16 -15
  27. package/dist/feeds/server/index.cjs.map +1 -1
  28. package/dist/feeds/server/index.js +4 -3
  29. package/dist/feeds/server/index.js.map +1 -1
  30. package/dist/google/apiClient.d.ts +8 -1
  31. package/dist/google/calendar.d.ts +35 -0
  32. package/dist/google/calendarSyncStore.d.ts +7 -0
  33. package/dist/google/collectionSync.d.ts +70 -0
  34. package/dist/google/index.cjs +296 -4
  35. package/dist/google/index.cjs.map +1 -1
  36. package/dist/google/index.d.ts +4 -2
  37. package/dist/google/index.js +281 -5
  38. package/dist/google/index.js.map +1 -1
  39. package/dist/ids-BR4U1dJD.cjs +150 -0
  40. package/dist/ids-BR4U1dJD.cjs.map +1 -0
  41. package/dist/ids-D4e10971.js +85 -0
  42. package/dist/ids-D4e10971.js.map +1 -0
  43. package/dist/{ingestTypes-CFEgTItj.js → ingestTypes-BsGOjR2l.js} +2 -2
  44. package/dist/{ingestTypes-CFEgTItj.js.map → ingestTypes-BsGOjR2l.js.map} +1 -1
  45. package/dist/{ingestTypes-Stc7iQyA.cjs → ingestTypes-CygUXsjf.cjs} +3 -3
  46. package/dist/{ingestTypes-Stc7iQyA.cjs.map → ingestTypes-CygUXsjf.cjs.map} +1 -1
  47. package/dist/{promptSafety-BLUcImzd.js → promptSafety-Boz5qOs-.js} +2 -84
  48. package/dist/promptSafety-Boz5qOs-.js.map +1 -0
  49. package/dist/{promptSafety-DI_1Rvhk.cjs → promptSafety-Co4cYQ_Z.cjs} +1 -149
  50. package/dist/promptSafety-Co4cYQ_Z.cjs.map +1 -0
  51. package/dist/remote-host/server/index.cjs +6 -4
  52. package/dist/remote-host/server/index.cjs.map +1 -1
  53. package/dist/remote-host/server/index.js +6 -4
  54. package/dist/remote-host/server/index.js.map +1 -1
  55. package/dist/scheduler/index.cjs +3 -1
  56. package/dist/scheduler/index.cjs.map +1 -1
  57. package/dist/scheduler/index.js +3 -1
  58. package/dist/scheduler/index.js.map +1 -1
  59. package/dist/{server-CkysfLh4.cjs → server-DLRz-U7F.cjs} +76 -1884
  60. package/dist/server-DLRz-U7F.cjs.map +1 -0
  61. package/dist/{server-BpEo0FOd.js → server-DZH7OjOD.js} +5 -1609
  62. package/dist/server-DZH7OjOD.js.map +1 -0
  63. package/dist/skill-bridge/index.cjs +2 -2
  64. package/dist/skill-bridge/index.cjs.map +1 -1
  65. package/dist/skill-bridge/index.js +1 -1
  66. package/dist/templatePath-27vUZowm.cjs +75 -0
  67. package/dist/templatePath-27vUZowm.cjs.map +1 -0
  68. package/dist/templatePath-k_WNbL_Q.js +52 -0
  69. package/dist/templatePath-k_WNbL_Q.js.map +1 -0
  70. package/package.json +1 -1
  71. package/dist/collection/paths.cjs.map +0 -1
  72. package/dist/collection/paths.js.map +0 -1
  73. package/dist/promptSafety-BLUcImzd.js.map +0 -1
  74. package/dist/promptSafety-DI_1Rvhk.cjs.map +0 -1
  75. package/dist/server-BpEo0FOd.js.map +0 -1
  76. package/dist/server-CkysfLh4.cjs.map +0 -1
@@ -1,56 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- //#region src/collection/core/templatePath.ts
3
- /** `templates/` — the subdir an action template must live under. */
4
- var TEMPLATES_PREFIX = "templates/";
5
- /**
6
- * A safe skill-relative path: non-empty, no backslash, not absolute,
7
- * and every `/`-separated segment is a plain `[A-Za-z0-9._-]+` token
8
- * that isn't `.` / `..` (no traversal). Multi-segment (nested) paths
9
- * are allowed. The reader's realpath containment is the hard
10
- * guarantee; this fails a bad path fast.
11
- */
12
- function isSafeTemplatePath(value) {
13
- if (value.length === 0 || value.includes("\\") || value.startsWith("/")) return false;
14
- return value.split("/").every((seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg));
15
- }
16
- /**
17
- * An action `template` value: a safe path that lives under the skill's
18
- * `templates/` subdir. This is the canonical contract — the schema
19
- * validator rejects anything else up front, and the bridge mirrors
20
- * exactly these. Nested paths (`templates/mail/welcome.md`) and any
21
- * extension are allowed as long as the path is otherwise safe.
22
- */
23
- function isSafeActionTemplatePath(value) {
24
- return value.startsWith(TEMPLATES_PREFIX) && isSafeTemplatePath(value);
25
- }
26
- /** `views/` — the subdir a custom-view HTML file must live under. */
27
- var VIEWS_PREFIX = "views/";
28
- /**
29
- * A custom-view `file` value: a safe path under the skill's `views/`
30
- * subdir that ends in `.html`. Custom views are LLM-authored HTML the
31
- * host renders in a sandboxed iframe; constraining them to `views/*.html`
32
- * keeps the data folder and the schema/template files off-limits to the
33
- * view-file reader. Same per-segment safety as templates; the reader's
34
- * realpath containment is the hard guarantee.
35
- */
36
- function isSafeCustomViewPath(value) {
37
- return value.startsWith(VIEWS_PREFIX) && /\.html$/.test(value) && isSafeTemplatePath(value);
38
- }
39
- /**
40
- * A custom-view `i18n` value: the JSON dictionary file authors ship next to
41
- * their `views/<id>.html`. Constrained to `views/<name>.i18n.json` so the
42
- * field can only point at a translation file co-located with the view it
43
- * translates — the same `views/` containment the HTML reader uses. The
44
- * `.i18n.json` suffix (vs plain `.json`) makes the file's purpose grep-able
45
- * for both authors and tooling.
46
- */
47
- function isSafeCustomViewI18nPath(value) {
48
- return value.startsWith(VIEWS_PREFIX) && /\.i18n\.json$/.test(value) && isSafeTemplatePath(value);
49
- }
50
- //#endregion
51
- exports.isSafeActionTemplatePath = isSafeActionTemplatePath;
52
- exports.isSafeCustomViewI18nPath = isSafeCustomViewI18nPath;
53
- exports.isSafeCustomViewPath = isSafeCustomViewPath;
54
- exports.isSafeTemplatePath = isSafeTemplatePath;
55
-
56
- //# sourceMappingURL=paths.cjs.map
2
+ const require_templatePath = require("../templatePath-27vUZowm.cjs");
3
+ exports.isSafeActionTemplatePath = require_templatePath.isSafeActionTemplatePath;
4
+ exports.isSafeCustomViewI18nPath = require_templatePath.isSafeCustomViewI18nPath;
5
+ exports.isSafeCustomViewPath = require_templatePath.isSafeCustomViewPath;
6
+ exports.isSafeTemplatePath = require_templatePath.isSafeTemplatePath;
@@ -1,52 +1,2 @@
1
- //#region src/collection/core/templatePath.ts
2
- /** `templates/` — the subdir an action template must live under. */
3
- var TEMPLATES_PREFIX = "templates/";
4
- /**
5
- * A safe skill-relative path: non-empty, no backslash, not absolute,
6
- * and every `/`-separated segment is a plain `[A-Za-z0-9._-]+` token
7
- * that isn't `.` / `..` (no traversal). Multi-segment (nested) paths
8
- * are allowed. The reader's realpath containment is the hard
9
- * guarantee; this fails a bad path fast.
10
- */
11
- function isSafeTemplatePath(value) {
12
- if (value.length === 0 || value.includes("\\") || value.startsWith("/")) return false;
13
- return value.split("/").every((seg) => seg.length > 0 && seg !== "." && seg !== ".." && /^[A-Za-z0-9._-]+$/.test(seg));
14
- }
15
- /**
16
- * An action `template` value: a safe path that lives under the skill's
17
- * `templates/` subdir. This is the canonical contract — the schema
18
- * validator rejects anything else up front, and the bridge mirrors
19
- * exactly these. Nested paths (`templates/mail/welcome.md`) and any
20
- * extension are allowed as long as the path is otherwise safe.
21
- */
22
- function isSafeActionTemplatePath(value) {
23
- return value.startsWith(TEMPLATES_PREFIX) && isSafeTemplatePath(value);
24
- }
25
- /** `views/` — the subdir a custom-view HTML file must live under. */
26
- var VIEWS_PREFIX = "views/";
27
- /**
28
- * A custom-view `file` value: a safe path under the skill's `views/`
29
- * subdir that ends in `.html`. Custom views are LLM-authored HTML the
30
- * host renders in a sandboxed iframe; constraining them to `views/*.html`
31
- * keeps the data folder and the schema/template files off-limits to the
32
- * view-file reader. Same per-segment safety as templates; the reader's
33
- * realpath containment is the hard guarantee.
34
- */
35
- function isSafeCustomViewPath(value) {
36
- return value.startsWith(VIEWS_PREFIX) && /\.html$/.test(value) && isSafeTemplatePath(value);
37
- }
38
- /**
39
- * A custom-view `i18n` value: the JSON dictionary file authors ship next to
40
- * their `views/<id>.html`. Constrained to `views/<name>.i18n.json` so the
41
- * field can only point at a translation file co-located with the view it
42
- * translates — the same `views/` containment the HTML reader uses. The
43
- * `.i18n.json` suffix (vs plain `.json`) makes the file's purpose grep-able
44
- * for both authors and tooling.
45
- */
46
- function isSafeCustomViewI18nPath(value) {
47
- return value.startsWith(VIEWS_PREFIX) && /\.i18n\.json$/.test(value) && isSafeTemplatePath(value);
48
- }
49
- //#endregion
1
+ import { i as isSafeTemplatePath, n as isSafeCustomViewI18nPath, r as isSafeCustomViewPath, t as isSafeActionTemplatePath } from "../templatePath-k_WNbL_Q.js";
50
2
  export { isSafeActionTemplatePath, isSafeCustomViewI18nPath, isSafeCustomViewPath, isSafeTemplatePath };
51
-
52
- //# sourceMappingURL=paths.js.map
@@ -1,7 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("../../../rolldown-runtime-D6vf50IK.cjs");
3
- const require_server = require("../../../server-CkysfLh4.cjs");
4
- const require_collection_paths = require("../../paths.cjs");
3
+ const require_discovery = require("../../../discovery-BZ2ms1tE.cjs");
4
+ const require_templatePath = require("../../../templatePath-27vUZowm.cjs");
5
+ const require_server = require("../../../server-DLRz-U7F.cjs");
5
6
  const require_skill_bridge_index = require("../../../skill-bridge/index.cjs");
6
7
  const require_types = require("../../../types-CNqkLT4M.cjs");
7
8
  let node_path = require("node:path");
@@ -74,7 +75,7 @@ function parseEntry(value, index) {
74
75
  * workspace file and delegates here. */
75
76
  function parseRegistriesConfig(raw) {
76
77
  if (!Array.isArray(raw)) {
77
- require_server.log.warn("collections-registry", "registries config is not an array — ignoring");
78
+ require_discovery.log.warn("collections-registry", "registries config is not an array — ignoring");
78
79
  return [];
79
80
  }
80
81
  const seen = /* @__PURE__ */ new Set();
@@ -82,11 +83,11 @@ function parseRegistriesConfig(raw) {
82
83
  for (let i = 0; i < raw.length; i++) {
83
84
  const parsed = parseEntry(raw[i], i);
84
85
  if (typeof parsed === "string") {
85
- require_server.log.warn("collections-registry", "registry config entry rejected", { reason: parsed });
86
+ require_discovery.log.warn("collections-registry", "registry config entry rejected", { reason: parsed });
86
87
  continue;
87
88
  }
88
89
  if (seen.has(parsed.name)) {
89
- require_server.log.warn("collections-registry", "registry config duplicate name dropped", { name: parsed.name });
90
+ require_discovery.log.warn("collections-registry", "registry config duplicate name dropped", { name: parsed.name });
90
91
  continue;
91
92
  }
92
93
  seen.add(parsed.name);
@@ -106,13 +107,13 @@ function readConfigTextOrNull(filePath) {
106
107
  * Missing file ⇒ empty list. Malformed JSON or rejected entries log but never
107
108
  * throw. */
108
109
  function loadRegistriesConfig() {
109
- const text = readConfigTextOrNull(require_server.collectionsRegistriesConfigPath());
110
+ const text = readConfigTextOrNull(require_discovery.collectionsRegistriesConfigPath());
110
111
  if (text === null) return [];
111
112
  let parsed;
112
113
  try {
113
114
  parsed = JSON.parse(text);
114
115
  } catch (err) {
115
- require_server.log.warn("collections-registry", "registries config is not valid JSON — ignoring", { error: err instanceof Error ? err.message : String(err) });
116
+ require_discovery.log.warn("collections-registry", "registries config is not valid JSON — ignoring", { error: err instanceof Error ? err.message : String(err) });
116
117
  return [];
117
118
  }
118
119
  return parseRegistriesConfig(parsed);
@@ -154,7 +155,7 @@ async function loadFromNetwork(descriptor) {
154
155
  headers: { accept: "application/json" }
155
156
  });
156
157
  } catch (err) {
157
- require_server.log.warn("collections-registry", "index fetch failed", {
158
+ require_discovery.log.warn("collections-registry", "index fetch failed", {
158
159
  registry: descriptor.name,
159
160
  url: descriptor.indexUrl,
160
161
  error: require_server.errorMessage(err)
@@ -172,7 +173,7 @@ async function loadFromNetwork(descriptor) {
172
173
  };
173
174
  const parsed = require_types.parseRegistryIndex(await res.json().catch(() => null), descriptor.name);
174
175
  if (!parsed.ok) {
175
- require_server.log.warn("collections-registry", "index invalid", {
176
+ require_discovery.log.warn("collections-registry", "index invalid", {
176
177
  registry: descriptor.name,
177
178
  url: descriptor.indexUrl,
178
179
  error: parsed.error
@@ -582,14 +583,14 @@ function validateAndNormalize(bundle, localSlug, workspaceRoot) {
582
583
  } catch {
583
584
  return { error: "schema.json is not valid JSON" };
584
585
  }
585
- const parsed = require_server.CollectionSchemaZ.safeParse(parsedJson);
586
+ const parsed = require_discovery.CollectionSchemaZ.safeParse(parsedJson);
586
587
  if (!parsed.success) return { error: `schema.json failed validation: ${parsed.error.issues[0]?.message ?? "invalid"}` };
587
588
  if (parsed.data.dataSource !== void 0) return { error: "schema.json declares `dataSource` — external-data collections are machine-local and cannot be imported from a registry" };
588
589
  const schema = {
589
590
  ...parsed.data,
590
591
  dataPath: normalizedDataPath(localSlug)
591
592
  };
592
- const acceptance = require_server.acceptParsedSchema(schema, {
593
+ const acceptance = require_discovery.acceptParsedSchema(schema, {
593
594
  source: "project",
594
595
  workspaceRoot,
595
596
  slug: localSlug
@@ -620,8 +621,8 @@ async function materializeSeed(dataDir, bundle) {
620
621
  let written = 0;
621
622
  for (const [rel, content] of seedEntries) {
622
623
  const fileName = rel.slice(11);
623
- if (fileName.includes("/") || require_server.safeRecordId(fileName.replace(/\.json$/, "")) === null) {
624
- require_server.log.warn("collections-registry", "skipped unsafe seed record", { rel });
624
+ if (fileName.includes("/") || require_discovery.safeRecordId(fileName.replace(/\.json$/, "")) === null) {
625
+ require_discovery.log.warn("collections-registry", "skipped unsafe seed record", { rel });
625
626
  continue;
626
627
  }
627
628
  await (0, node_fs_promises.writeFile)(node_path.default.join(dataDir, fileName), content, "utf-8");
@@ -641,7 +642,7 @@ function bridgeAllowlistFiles(bundle) {
641
642
  for (const rel of bundle.keys()) {
642
643
  if (rel === SKILL_FILE || rel === SCHEMA_FILE) continue;
643
644
  if (rel.startsWith(SEED_PREFIX)) continue;
644
- if (!require_collection_paths.isSafeActionTemplatePath(rel)) continue;
645
+ if (!require_templatePath.isSafeActionTemplatePath(rel)) continue;
645
646
  wanted.add(rel);
646
647
  }
647
648
  return wanted;
@@ -716,7 +717,7 @@ async function writeImportedCollection(params) {
716
717
  contentSha: entry.contentSha,
717
718
  importedAt: nowIso
718
719
  };
719
- await require_server.writeFileAtomic(node_path.default.join(staging, ORIGIN_FILE), `${JSON.stringify(origin, null, 2)}\n`);
720
+ await require_discovery.writeFileAtomic(node_path.default.join(staging, ORIGIN_FILE), `${JSON.stringify(origin, null, 2)}\n`);
720
721
  if (target.updated) await (0, node_fs_promises.rename)(target.targetDir, backup);
721
722
  try {
722
723
  await (0, node_fs_promises.rename)(staging, target.targetDir);
@@ -731,7 +732,7 @@ async function writeImportedCollection(params) {
731
732
  try {
732
733
  await mirrorToClaudeSkills(workspaceRoot, localSlug, bundle);
733
734
  } catch (err) {
734
- require_server.log.warn("collections-registry", "mirror to .claude/skills/ failed (data/skills write succeeded; prior mirror left intact)", {
735
+ require_discovery.log.warn("collections-registry", "mirror to .claude/skills/ failed (data/skills write succeeded; prior mirror left intact)", {
735
736
  localSlug,
736
737
  error: require_server.errorMessage(err)
737
738
  });
@@ -779,7 +780,7 @@ async function performImport(author, slug, workspaceRoot, registry = null) {
779
780
  nowIso: (/* @__PURE__ */ new Date()).toISOString()
780
781
  });
781
782
  } catch (err) {
782
- require_server.log.warn("collections-registry", "import write failed", {
783
+ require_discovery.log.warn("collections-registry", "import write failed", {
783
784
  author,
784
785
  slug,
785
786
  registry: entry.registryName,
@@ -924,7 +925,7 @@ async function writeCollectionExport(params) {
924
925
  ...seed.count > 0 ? { dataConsent: true } : {}
925
926
  };
926
927
  await (0, node_fs_promises.writeFile)(node_path.default.join(outDir, "meta.json"), `${JSON.stringify(metaOut, null, 2)}\n`, "utf-8");
927
- require_server.log.info("collections-registry", "exported collection", {
928
+ require_discovery.log.info("collections-registry", "exported collection", {
928
929
  slug: meta.slug,
929
930
  author: meta.author,
930
931
  seedCount: seed.count
@@ -1025,7 +1026,7 @@ async function readJsonObject(file) {
1025
1026
  }
1026
1027
  }
1027
1028
  async function performExport(slug, opts, workspaceRoot) {
1028
- const collection = await require_server.loadCollection(slug);
1029
+ const collection = await require_discovery.loadCollection(slug);
1029
1030
  if (!collection) return {
1030
1031
  ok: false,
1031
1032
  status: STATUS_NOT_FOUND,