@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.
- package/assets/helps/google-calendar-collection.md +79 -0
- package/assets/helps/index.md +1 -0
- package/dist/collection/core/schemaZ.d.ts +29 -0
- package/dist/collection/index.cjs +15 -14
- package/dist/collection/index.cjs.map +1 -1
- package/dist/collection/index.js +2 -1
- package/dist/collection/index.js.map +1 -1
- package/dist/collection/paths.cjs +5 -55
- package/dist/collection/paths.js +1 -51
- package/dist/collection/registry/server/index.cjs +20 -19
- package/dist/collection/registry/server/index.cjs.map +1 -1
- package/dist/collection/registry/server/index.js +3 -2
- package/dist/collection/registry/server/index.js.map +1 -1
- package/dist/collection/server/index.cjs +41 -40
- package/dist/collection/server/index.js +4 -3
- package/dist/collection-watchers/index.cjs +12 -11
- package/dist/collection-watchers/index.cjs.map +1 -1
- package/dist/collection-watchers/index.js +3 -2
- package/dist/collection-watchers/index.js.map +1 -1
- package/dist/discovery-3K_Wtkvn.js +1636 -0
- package/dist/discovery-3K_Wtkvn.js.map +1 -0
- package/dist/discovery-BZ2ms1tE.cjs +1865 -0
- package/dist/discovery-BZ2ms1tE.cjs.map +1 -0
- package/dist/feeds/index.cjs +4 -4
- package/dist/feeds/index.js +2 -2
- package/dist/feeds/server/index.cjs +16 -15
- package/dist/feeds/server/index.cjs.map +1 -1
- package/dist/feeds/server/index.js +4 -3
- package/dist/feeds/server/index.js.map +1 -1
- package/dist/google/apiClient.d.ts +8 -1
- package/dist/google/calendar.d.ts +35 -0
- package/dist/google/calendarSyncStore.d.ts +7 -0
- package/dist/google/collectionSync.d.ts +70 -0
- package/dist/google/index.cjs +296 -4
- package/dist/google/index.cjs.map +1 -1
- package/dist/google/index.d.ts +4 -2
- package/dist/google/index.js +281 -5
- package/dist/google/index.js.map +1 -1
- package/dist/ids-BR4U1dJD.cjs +150 -0
- package/dist/ids-BR4U1dJD.cjs.map +1 -0
- package/dist/ids-D4e10971.js +85 -0
- package/dist/ids-D4e10971.js.map +1 -0
- package/dist/{ingestTypes-CFEgTItj.js → ingestTypes-BsGOjR2l.js} +2 -2
- package/dist/{ingestTypes-CFEgTItj.js.map → ingestTypes-BsGOjR2l.js.map} +1 -1
- package/dist/{ingestTypes-Stc7iQyA.cjs → ingestTypes-CygUXsjf.cjs} +3 -3
- package/dist/{ingestTypes-Stc7iQyA.cjs.map → ingestTypes-CygUXsjf.cjs.map} +1 -1
- package/dist/{promptSafety-BLUcImzd.js → promptSafety-Boz5qOs-.js} +2 -84
- package/dist/promptSafety-Boz5qOs-.js.map +1 -0
- package/dist/{promptSafety-DI_1Rvhk.cjs → promptSafety-Co4cYQ_Z.cjs} +1 -149
- package/dist/promptSafety-Co4cYQ_Z.cjs.map +1 -0
- package/dist/remote-host/server/index.cjs +6 -4
- package/dist/remote-host/server/index.cjs.map +1 -1
- package/dist/remote-host/server/index.js +6 -4
- package/dist/remote-host/server/index.js.map +1 -1
- package/dist/scheduler/index.cjs +3 -1
- package/dist/scheduler/index.cjs.map +1 -1
- package/dist/scheduler/index.js +3 -1
- package/dist/scheduler/index.js.map +1 -1
- package/dist/{server-CkysfLh4.cjs → server-DLRz-U7F.cjs} +76 -1884
- package/dist/server-DLRz-U7F.cjs.map +1 -0
- package/dist/{server-BpEo0FOd.js → server-DZH7OjOD.js} +5 -1609
- package/dist/server-DZH7OjOD.js.map +1 -0
- package/dist/skill-bridge/index.cjs +2 -2
- package/dist/skill-bridge/index.cjs.map +1 -1
- package/dist/skill-bridge/index.js +1 -1
- package/dist/templatePath-27vUZowm.cjs +75 -0
- package/dist/templatePath-27vUZowm.cjs.map +1 -0
- package/dist/templatePath-k_WNbL_Q.js +52 -0
- package/dist/templatePath-k_WNbL_Q.js.map +1 -0
- package/package.json +1 -1
- package/dist/collection/paths.cjs.map +0 -1
- package/dist/collection/paths.js.map +0 -1
- package/dist/promptSafety-BLUcImzd.js.map +0 -1
- package/dist/promptSafety-DI_1Rvhk.cjs.map +0 -1
- package/dist/server-BpEo0FOd.js.map +0 -1
- package/dist/server-CkysfLh4.cjs.map +0 -1
|
@@ -1,56 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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;
|
package/dist/collection/paths.js
CHANGED
|
@@ -1,52 +1,2 @@
|
|
|
1
|
-
|
|
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
|
|
4
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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("/") ||
|
|
624
|
-
|
|
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 (!
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
1029
|
+
const collection = await require_discovery.loadCollection(slug);
|
|
1029
1030
|
if (!collection) return {
|
|
1030
1031
|
ok: false,
|
|
1031
1032
|
status: STATUS_NOT_FOUND,
|