@mulmoclaude/core 4.5.0 → 4.7.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/dist/collection/core/schemaZ.d.ts +1 -1
- package/dist/collection/registry/server/index.cjs +1 -1
- package/dist/collection/registry/server/index.js +1 -1
- package/dist/collection/server/index.cjs +2 -1
- package/dist/collection/server/index.js +2 -2
- package/dist/collection/server/skillAssets.d.ts +20 -0
- package/dist/collection-watchers/index.cjs +1 -1
- package/dist/collection-watchers/index.js +1 -1
- package/dist/feeds/server/index.cjs +1 -1
- package/dist/feeds/server/index.js +1 -1
- package/dist/global-config/index.cjs +1 -1
- package/dist/google/index.cjs +1 -1
- package/dist/{paths-ClV946_f.cjs → paths-C8-jxR0s.cjs} +1 -2
- package/dist/{paths-ClV946_f.cjs.map → paths-C8-jxR0s.cjs.map} +1 -1
- package/dist/plugin-vue/index.cjs +214 -75
- package/dist/plugin-vue/index.cjs.map +1 -1
- package/dist/plugin-vue/index.js +214 -75
- package/dist/plugin-vue/index.js.map +1 -1
- package/dist/{server-Wz4_ALLl.cjs → server-DXUt34Rt.cjs} +79 -29
- package/dist/server-DXUt34Rt.cjs.map +1 -0
- package/dist/{server-BENtFplH.js → server-DyYwfNB6.js} +74 -30
- package/dist/server-DyYwfNB6.js.map +1 -0
- package/package.json +4 -4
- package/dist/server-BENtFplH.js.map +0 -1
- package/dist/server-Wz4_ALLl.cjs.map +0 -1
|
@@ -33,27 +33,78 @@ let zod = require("zod");
|
|
|
33
33
|
async function readCustomViewHtml(collection, viewFile, opts = {}) {
|
|
34
34
|
return readSourceAwareFile(collection, viewFile, opts);
|
|
35
35
|
}
|
|
36
|
-
/**
|
|
37
|
-
*
|
|
38
|
-
* `
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
/** `<staging>/<slug>` when THAT slug is actually staged there, else null.
|
|
37
|
+
*
|
|
38
|
+
* `stagingSkillDir` only says whether the ROOT has a staging tree, and then
|
|
39
|
+
* joins the slug — so on its own it claims every collection in a staged
|
|
40
|
+
* workspace is staged. That is wrong for the two layouts that coexist there:
|
|
41
|
+
* a collection IMPORTED via the discover panel, and one committed directly
|
|
42
|
+
* under `.claude/skills/`, neither of which has a staging copy. A stale
|
|
43
|
+
* `data/skills/<slug>/views/x.html` left beside them then SHADOWED the real
|
|
44
|
+
* view on every read (#3031).
|
|
45
|
+
*
|
|
46
|
+
* The evidence is the slug's own `schema.json`, because that is what the
|
|
47
|
+
* authoring layout actually produces — `putSchema` writes it, and the delete
|
|
48
|
+
* path below has always keyed on it. It must be a REGULAR FILE — `lstat`, not
|
|
49
|
+
* `stat` — so a symlink standing in for the schema is not evidence.
|
|
50
|
+
*
|
|
51
|
+
* Exported so the DELETE path uses this exact function rather than a second
|
|
52
|
+
* copy of the expression: "reads and deletes agree" is a claim `views.ts` has
|
|
53
|
+
* made in its comments since #1836, and sharing the predicate is what makes
|
|
54
|
+
* it structurally true instead of a convention two files have to remember. */
|
|
55
|
+
async function stagedSkillDir(workspaceRoot, safeSlug) {
|
|
56
|
+
const staging = require_discovery.stagingSkillDir(workspaceRoot, safeSlug);
|
|
57
|
+
if (staging === null) return null;
|
|
58
|
+
return await isStagedSchema(node_path.default.join(staging, "schema.json")) ? staging : null;
|
|
59
|
+
}
|
|
60
|
+
/** Is the staged `schema.json` there, as a regular file?
|
|
61
|
+
*
|
|
62
|
+
* NOT `isRegularFile` from `io.ts`, which answers `false` for every `lstat`
|
|
63
|
+
* failure. Here "no schema" and "the schema could not be inspected" must not
|
|
64
|
+
* collapse into one answer: the second would quietly downgrade a staged slug
|
|
65
|
+
* to unstaged and serve the OTHER base's copy — the same masking the read loop
|
|
66
|
+
* below refuses, and for the same reason (Sourcery review on #3032). Only the
|
|
67
|
+
* missing-here codes mean "not staged"; anything else propagates. */
|
|
68
|
+
async function isStagedSchema(target) {
|
|
69
|
+
try {
|
|
70
|
+
return (await (0, node_fs_promises.lstat)(target)).isFile();
|
|
71
|
+
} catch (err) {
|
|
72
|
+
if (!isMissingHere(err)) throw err;
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** The two codes that mean "not at this path" rather than "this path failed".
|
|
77
|
+
* A permission denial / disk error must propagate — silently treating it as
|
|
78
|
+
* absent masks a real failure as a stale-from-another-base success or a
|
|
79
|
+
* misleading 404 (CodeRabbit review on #1836). */
|
|
80
|
+
function isMissingHere(err) {
|
|
81
|
+
return require_dist.isErrorWithCode(err) && (err.code === "ENOENT" || err.code === "ENOTDIR");
|
|
82
|
+
}
|
|
83
|
+
/** Read `relPath` from the first base that holds it, or null when none does.
|
|
84
|
+
* Bases are tried in order and each is containment-checked on its own, so the
|
|
85
|
+
* fallback never widens what a single base would have allowed. */
|
|
86
|
+
async function readFromBases(bases, relPath) {
|
|
45
87
|
for (const base of bases) {
|
|
46
88
|
const resolved = require_discovery.resolveTemplatePath(base, relPath);
|
|
47
89
|
if (resolved === null) continue;
|
|
48
90
|
try {
|
|
49
91
|
return await (0, node_fs_promises.readFile)(resolved, "utf-8");
|
|
50
92
|
} catch (err) {
|
|
51
|
-
if (!
|
|
52
|
-
if (err.code !== "ENOENT" && err.code !== "ENOTDIR") throw err;
|
|
93
|
+
if (!isMissingHere(err)) throw err;
|
|
53
94
|
}
|
|
54
95
|
}
|
|
55
96
|
return null;
|
|
56
97
|
}
|
|
98
|
+
/** Internal helper: read a file using the same source-aware base fallback as
|
|
99
|
+
* `readCustomViewHtml`. Used by both `readCustomViewHtml` and
|
|
100
|
+
* `readCustomViewI18n` so the two stay in lockstep. */
|
|
101
|
+
async function readSourceAwareFile(collection, relPath, opts) {
|
|
102
|
+
const safeSlug = require_discovery.safeSlugName(collection.slug);
|
|
103
|
+
if (safeSlug === null) return null;
|
|
104
|
+
const workspaceRoot = opts.workspaceRoot ?? require_discovery.getWorkspaceRoot();
|
|
105
|
+
const staging = collection.source === "project" ? await stagedSkillDir(workspaceRoot, safeSlug) : null;
|
|
106
|
+
return readFromBases(staging === null ? [collection.skillDir] : [staging, collection.skillDir], relPath);
|
|
107
|
+
}
|
|
57
108
|
var I18N_FALLBACK_LOCALE = "en";
|
|
58
109
|
var EMPTY_I18N = {
|
|
59
110
|
locale: "",
|
|
@@ -1267,27 +1318,20 @@ async function deleteCollection(collection, opts = {}) {
|
|
|
1267
1318
|
}
|
|
1268
1319
|
//#endregion
|
|
1269
1320
|
//#region src/collection/server/views.ts
|
|
1270
|
-
async function fileExists(target) {
|
|
1271
|
-
try {
|
|
1272
|
-
await (0, node_fs_promises.stat)(target);
|
|
1273
|
-
return true;
|
|
1274
|
-
} catch (err) {
|
|
1275
|
-
if (!require_dist.isErrorWithCode(err)) throw err;
|
|
1276
|
-
if (err.code === "ENOENT" || err.code === "ENOTDIR") return false;
|
|
1277
|
-
throw err;
|
|
1278
|
-
}
|
|
1279
|
-
}
|
|
1280
1321
|
/** The authoritative base dir for a collection's schema.json + view HTML.
|
|
1281
1322
|
* For a project collection, prefer the staging tree when its schema.json is
|
|
1282
1323
|
* present (authoring layout); otherwise fall back to the active skill dir
|
|
1283
1324
|
* (imported layout — staging never materialised). For feed / user, it's
|
|
1284
|
-
* always the discovered skillDir.
|
|
1285
|
-
*
|
|
1325
|
+
* always the discovered skillDir.
|
|
1326
|
+
*
|
|
1327
|
+
* Matches `readCustomViewHtml` so reads and deletes agree on both layouts —
|
|
1328
|
+
* through the SAME function now (`stagedSkillDir`), not through two copies of
|
|
1329
|
+
* one expression. The read side had drifted off it and was preferring staging
|
|
1330
|
+
* per root rather than per slug (#3031), which is precisely the drift a shared
|
|
1331
|
+
* predicate makes unrepresentable. */
|
|
1286
1332
|
async function canonicalBase(collection, workspaceRoot, safeSlug) {
|
|
1287
1333
|
if (collection.source !== "project") return collection.skillDir;
|
|
1288
|
-
|
|
1289
|
-
if (staging !== null && await fileExists(node_path.default.join(staging, "schema.json"))) return staging;
|
|
1290
|
-
return collection.skillDir;
|
|
1334
|
+
return await stagedSkillDir(workspaceRoot, safeSlug) ?? collection.skillDir;
|
|
1291
1335
|
}
|
|
1292
1336
|
/** Every on-disk schema.json that must reflect the removal. The active
|
|
1293
1337
|
* `<skillDir>/schema.json` is the discovery anchor and is always present.
|
|
@@ -1297,9 +1341,9 @@ async function canonicalBase(collection, workspaceRoot, safeSlug) {
|
|
|
1297
1341
|
async function schemaWriteTargets(collection, workspaceRoot, safeSlug) {
|
|
1298
1342
|
const active = node_path.default.join(collection.skillDir, require_discovery.SCHEMA_FILE);
|
|
1299
1343
|
if (collection.source !== "project") return [active];
|
|
1300
|
-
const staging =
|
|
1344
|
+
const staging = await stagedSkillDir(workspaceRoot, safeSlug);
|
|
1301
1345
|
const targets = [];
|
|
1302
|
-
if (staging !== null
|
|
1346
|
+
if (staging !== null) targets.push(node_path.default.join(staging, require_discovery.SCHEMA_FILE));
|
|
1303
1347
|
targets.push(active);
|
|
1304
1348
|
return targets;
|
|
1305
1349
|
}
|
|
@@ -2603,6 +2647,12 @@ Object.defineProperty(exports, "schemaRelations", {
|
|
|
2603
2647
|
return schemaRelations;
|
|
2604
2648
|
}
|
|
2605
2649
|
});
|
|
2650
|
+
Object.defineProperty(exports, "stagedSkillDir", {
|
|
2651
|
+
enumerable: true,
|
|
2652
|
+
get: function() {
|
|
2653
|
+
return stagedSkillDir;
|
|
2654
|
+
}
|
|
2655
|
+
});
|
|
2606
2656
|
Object.defineProperty(exports, "successorId", {
|
|
2607
2657
|
enumerable: true,
|
|
2608
2658
|
get: function() {
|
|
@@ -2622,4 +2672,4 @@ Object.defineProperty(exports, "validateRecordObject", {
|
|
|
2622
2672
|
}
|
|
2623
2673
|
});
|
|
2624
2674
|
|
|
2625
|
-
//# sourceMappingURL=server-
|
|
2675
|
+
//# sourceMappingURL=server-DXUt34Rt.cjs.map
|