@mulmoclaude/core 0.2.15 → 0.4.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 (67) hide show
  1. package/dist/collection/registry/guards.d.ts +2 -0
  2. package/dist/collection/registry/index.cjs +4 -0
  3. package/dist/collection/registry/index.d.ts +2 -0
  4. package/dist/collection/registry/index.js +2 -0
  5. package/dist/collection/registry/registryIndex.d.ts +48 -0
  6. package/dist/collection/registry/server/client.d.ts +60 -0
  7. package/dist/collection/registry/server/collectionFiles.d.ts +51 -0
  8. package/dist/collection/registry/server/exportCollection.d.ts +29 -0
  9. package/dist/collection/registry/server/fetch.d.ts +8 -0
  10. package/dist/collection/registry/server/importCollection.d.ts +35 -0
  11. package/dist/collection/registry/server/importWriter.d.ts +30 -0
  12. package/dist/collection/registry/server/index.cjs +1110 -0
  13. package/dist/collection/registry/server/index.cjs.map +1 -0
  14. package/dist/collection/registry/server/index.d.ts +28 -0
  15. package/dist/collection/registry/server/index.js +1076 -0
  16. package/dist/collection/registry/server/index.js.map +1 -0
  17. package/dist/collection/registry/server/performExport.d.ts +6 -0
  18. package/dist/collection/registry/server/registriesConfig.d.ts +11 -0
  19. package/dist/collection/registry/server/skillDescription.d.ts +4 -0
  20. package/dist/collection/registry/types.d.ts +37 -0
  21. package/dist/collection/server/host.d.ts +7 -0
  22. package/dist/collection/server/index.cjs +1 -1
  23. package/dist/collection/server/index.js +1 -1
  24. package/dist/collection/server/util.d.ts +1 -0
  25. package/dist/collection-watchers/index.cjs +1 -1
  26. package/dist/collection-watchers/index.js +1 -1
  27. package/dist/feeds/server/index.cjs +1 -1
  28. package/dist/feeds/server/index.cjs.map +1 -1
  29. package/dist/feeds/server/index.js +1 -1
  30. package/dist/feeds/server/index.js.map +1 -1
  31. package/dist/notifier-ChpY0XrY.js.map +1 -1
  32. package/dist/notifier-bS8IEeLA.cjs.map +1 -1
  33. package/dist/{server-CRlmOBVQ.js → server-DRoqc8dL.js} +8 -2
  34. package/dist/server-DRoqc8dL.js.map +1 -0
  35. package/dist/{server-BjXvqGrE.cjs → server-DoDXibCq.cjs} +31 -1
  36. package/dist/server-DoDXibCq.cjs.map +1 -0
  37. package/dist/slug-CdN-pQX1.js +37 -0
  38. package/dist/slug-CdN-pQX1.js.map +1 -0
  39. package/dist/slug-DbwORN9z.cjs +48 -0
  40. package/dist/slug-DbwORN9z.cjs.map +1 -0
  41. package/dist/types-BKVZrtyc.js +123 -0
  42. package/dist/types-BKVZrtyc.js.map +1 -0
  43. package/dist/types-CNqkLT4M.cjs +140 -0
  44. package/dist/types-CNqkLT4M.cjs.map +1 -0
  45. package/dist/whisper/client.cjs.map +1 -1
  46. package/dist/whisper/client.js.map +1 -1
  47. package/dist/wiki/graph.d.ts +33 -0
  48. package/dist/wiki/index-parse.d.ts +39 -0
  49. package/dist/wiki/index.cjs +493 -0
  50. package/dist/wiki/index.cjs.map +1 -0
  51. package/dist/wiki/index.d.ts +7 -0
  52. package/dist/wiki/index.js +465 -0
  53. package/dist/wiki/index.js.map +1 -0
  54. package/dist/wiki/link.d.ts +41 -0
  55. package/dist/wiki/lint.d.ts +26 -0
  56. package/dist/wiki/render.d.ts +19 -0
  57. package/dist/wiki/route.d.ts +32 -0
  58. package/dist/wiki/server/index.cjs +30 -0
  59. package/dist/wiki/server/index.cjs.map +1 -0
  60. package/dist/wiki/server/index.d.ts +1 -0
  61. package/dist/wiki/server/index.js +27 -0
  62. package/dist/wiki/server/index.js.map +1 -0
  63. package/dist/wiki/server/paths.d.ts +11 -0
  64. package/dist/wiki/slug.d.ts +24 -0
  65. package/package.json +25 -1
  66. package/dist/server-BjXvqGrE.cjs.map +0 -1
  67. package/dist/server-CRlmOBVQ.js.map +0 -1
@@ -0,0 +1,32 @@
1
+ export declare const WIKI_ROUTE_SECTION: {
2
+ readonly pages: "pages";
3
+ readonly log: "log";
4
+ readonly lintReport: "lint-report";
5
+ readonly graph: "graph";
6
+ };
7
+ export type WikiRouteSection = (typeof WIKI_ROUTE_SECTION)[keyof typeof WIKI_ROUTE_SECTION];
8
+ export declare const WIKI_ACTION: {
9
+ readonly index: "index";
10
+ readonly page: "page";
11
+ readonly log: "log";
12
+ readonly lintReport: "lint_report";
13
+ readonly graph: "graph";
14
+ readonly save: "save";
15
+ };
16
+ export type WikiAction = (typeof WIKI_ACTION)[keyof typeof WIKI_ACTION];
17
+ export type WikiTarget = {
18
+ kind: "index";
19
+ } | {
20
+ kind: "page";
21
+ slug: string;
22
+ } | {
23
+ kind: "log";
24
+ } | {
25
+ kind: "lint_report";
26
+ } | {
27
+ kind: "graph";
28
+ };
29
+ export declare function isSafeWikiSlug(value: unknown): value is string;
30
+ export declare function readWikiRouteTarget(params: unknown): WikiTarget | null;
31
+ export declare function buildWikiRouteParams(target: WikiTarget): Record<string, string>;
32
+ export declare function wikiActionFor(target: WikiTarget): WikiAction;
@@ -0,0 +1,30 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_rolldown_runtime = require("../../rolldown-runtime-D6vf50IK.cjs");
3
+ const require_slug = require("../../slug-DbwORN9z.cjs");
4
+ let node_path = require("node:path");
5
+ node_path = require_rolldown_runtime.__toESM(node_path, 1);
6
+ //#region src/wiki/server/paths.ts
7
+ /** Given an absolute path and the absolute `pagesDir`, return the
8
+ * slug if `absPath` is a direct `.md` child of `pagesDir`, else
9
+ * null. Pure path-string math — no fs IO, no symlink resolution.
10
+ *
11
+ * Caller responsibility: pass already-realpath'd values for both
12
+ * arguments. Mixing a realpath'd `absPath` with a symlinked
13
+ * `pagesDir` (or vice versa) silently mismatches because
14
+ * `path.relative` is plain string arithmetic. The trap caused
15
+ * #883 review-iter-1 — a symlinked workspace silently routed
16
+ * wiki writes through the generic writer. */
17
+ function wikiSlugFromAbsPath(absPath, pagesDir) {
18
+ const rel = node_path.default.relative(pagesDir, absPath);
19
+ if (rel.length === 0) return null;
20
+ if (node_path.default.isAbsolute(rel)) return null;
21
+ if (rel.includes(node_path.default.sep)) return null;
22
+ if (!rel.endsWith(".md")) return null;
23
+ const slug = rel.slice(0, -3);
24
+ if (!require_slug.isSafeSlug(slug)) return null;
25
+ return slug;
26
+ }
27
+ //#endregion
28
+ exports.wikiSlugFromAbsPath = wikiSlugFromAbsPath;
29
+
30
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../../src/wiki/server/paths.ts"],"sourcesContent":["// Node-only wiki-page helpers — anything that needs `node:path`\n// lives here so the rest of `@mulmoclaude/core/wiki` stays pure\n// (string-only, importable from both browser and Node bundles).\n// Frontend code MUST NOT import this file directly; use the pure\n// `@mulmoclaude/core/wiki` modules instead.\n\nimport path from \"node:path\";\nimport { isSafeSlug } from \"../slug.js\";\n\n/** Given an absolute path and the absolute `pagesDir`, return the\n * slug if `absPath` is a direct `.md` child of `pagesDir`, else\n * null. Pure path-string math — no fs IO, no symlink resolution.\n *\n * Caller responsibility: pass already-realpath'd values for both\n * arguments. Mixing a realpath'd `absPath` with a symlinked\n * `pagesDir` (or vice versa) silently mismatches because\n * `path.relative` is plain string arithmetic. The trap caused\n * #883 review-iter-1 — a symlinked workspace silently routed\n * wiki writes through the generic writer. */\nexport function wikiSlugFromAbsPath(absPath: string, pagesDir: string): string | null {\n const rel = path.relative(pagesDir, absPath);\n if (rel.length === 0) return null;\n if (path.isAbsolute(rel)) return null;\n // Direct child only — no nested layout today. Any separator\n // means the path either escapes (`../secret.md`) or descends\n // (`subdir/foo.md`). A literal page name like `..foo.md` is a\n // single segment without a separator and is allowed (codex\n // iter-3 #883 — the prior `startsWith(\"..\")` rule wrongly\n // rejected it).\n if (rel.includes(path.sep)) return null;\n if (!rel.endsWith(\".md\")) return null;\n const slug = rel.slice(0, -\".md\".length);\n if (!isSafeSlug(slug)) return null;\n return slug;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,SAAgB,oBAAoB,SAAiB,UAAiC;CACpF,MAAM,MAAM,UAAA,QAAK,SAAS,UAAU,OAAO;CAC3C,IAAI,IAAI,WAAW,GAAG,OAAO;CAC7B,IAAI,UAAA,QAAK,WAAW,GAAG,GAAG,OAAO;CAOjC,IAAI,IAAI,SAAS,UAAA,QAAK,GAAG,GAAG,OAAO;CACnC,IAAI,CAAC,IAAI,SAAS,KAAK,GAAG,OAAO;CACjC,MAAM,OAAO,IAAI,MAAM,GAAG,EAAa;CACvC,IAAI,CAAC,aAAA,WAAW,IAAI,GAAG,OAAO;CAC9B,OAAO;AACT"}
@@ -0,0 +1 @@
1
+ export { wikiSlugFromAbsPath } from './paths.js';
@@ -0,0 +1,27 @@
1
+ import { t as isSafeSlug } from "../../slug-CdN-pQX1.js";
2
+ import path from "node:path";
3
+ //#region src/wiki/server/paths.ts
4
+ /** Given an absolute path and the absolute `pagesDir`, return the
5
+ * slug if `absPath` is a direct `.md` child of `pagesDir`, else
6
+ * null. Pure path-string math — no fs IO, no symlink resolution.
7
+ *
8
+ * Caller responsibility: pass already-realpath'd values for both
9
+ * arguments. Mixing a realpath'd `absPath` with a symlinked
10
+ * `pagesDir` (or vice versa) silently mismatches because
11
+ * `path.relative` is plain string arithmetic. The trap caused
12
+ * #883 review-iter-1 — a symlinked workspace silently routed
13
+ * wiki writes through the generic writer. */
14
+ function wikiSlugFromAbsPath(absPath, pagesDir) {
15
+ const rel = path.relative(pagesDir, absPath);
16
+ if (rel.length === 0) return null;
17
+ if (path.isAbsolute(rel)) return null;
18
+ if (rel.includes(path.sep)) return null;
19
+ if (!rel.endsWith(".md")) return null;
20
+ const slug = rel.slice(0, -3);
21
+ if (!isSafeSlug(slug)) return null;
22
+ return slug;
23
+ }
24
+ //#endregion
25
+ export { wikiSlugFromAbsPath };
26
+
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/wiki/server/paths.ts"],"sourcesContent":["// Node-only wiki-page helpers — anything that needs `node:path`\n// lives here so the rest of `@mulmoclaude/core/wiki` stays pure\n// (string-only, importable from both browser and Node bundles).\n// Frontend code MUST NOT import this file directly; use the pure\n// `@mulmoclaude/core/wiki` modules instead.\n\nimport path from \"node:path\";\nimport { isSafeSlug } from \"../slug.js\";\n\n/** Given an absolute path and the absolute `pagesDir`, return the\n * slug if `absPath` is a direct `.md` child of `pagesDir`, else\n * null. Pure path-string math — no fs IO, no symlink resolution.\n *\n * Caller responsibility: pass already-realpath'd values for both\n * arguments. Mixing a realpath'd `absPath` with a symlinked\n * `pagesDir` (or vice versa) silently mismatches because\n * `path.relative` is plain string arithmetic. The trap caused\n * #883 review-iter-1 — a symlinked workspace silently routed\n * wiki writes through the generic writer. */\nexport function wikiSlugFromAbsPath(absPath: string, pagesDir: string): string | null {\n const rel = path.relative(pagesDir, absPath);\n if (rel.length === 0) return null;\n if (path.isAbsolute(rel)) return null;\n // Direct child only — no nested layout today. Any separator\n // means the path either escapes (`../secret.md`) or descends\n // (`subdir/foo.md`). A literal page name like `..foo.md` is a\n // single segment without a separator and is allowed (codex\n // iter-3 #883 — the prior `startsWith(\"..\")` rule wrongly\n // rejected it).\n if (rel.includes(path.sep)) return null;\n if (!rel.endsWith(\".md\")) return null;\n const slug = rel.slice(0, -\".md\".length);\n if (!isSafeSlug(slug)) return null;\n return slug;\n}\n"],"mappings":";;;;;;;;;;;;;AAmBA,SAAgB,oBAAoB,SAAiB,UAAiC;CACpF,MAAM,MAAM,KAAK,SAAS,UAAU,OAAO;CAC3C,IAAI,IAAI,WAAW,GAAG,OAAO;CAC7B,IAAI,KAAK,WAAW,GAAG,GAAG,OAAO;CAOjC,IAAI,IAAI,SAAS,KAAK,GAAG,GAAG,OAAO;CACnC,IAAI,CAAC,IAAI,SAAS,KAAK,GAAG,OAAO;CACjC,MAAM,OAAO,IAAI,MAAM,GAAG,EAAa;CACvC,IAAI,CAAC,WAAW,IAAI,GAAG,OAAO;CAC9B,OAAO;AACT"}
@@ -0,0 +1,11 @@
1
+ /** Given an absolute path and the absolute `pagesDir`, return the
2
+ * slug if `absPath` is a direct `.md` child of `pagesDir`, else
3
+ * null. Pure path-string math — no fs IO, no symlink resolution.
4
+ *
5
+ * Caller responsibility: pass already-realpath'd values for both
6
+ * arguments. Mixing a realpath'd `absPath` with a symlinked
7
+ * `pagesDir` (or vice versa) silently mismatches because
8
+ * `path.relative` is plain string arithmetic. The trap caused
9
+ * #883 review-iter-1 — a symlinked workspace silently routed
10
+ * wiki writes through the generic writer. */
11
+ export declare function wikiSlugFromAbsPath(absPath: string, pagesDir: string): string | null;
@@ -0,0 +1,24 @@
1
+ /** Reject slugs that would escape `data/wiki/pages/` once
2
+ * joined back into a path, or that are otherwise invalid as
3
+ * page filenames. The chokepoint must defend itself even when
4
+ * callers derive the slug from a trusted source — a typo or
5
+ * future caller mistake should fail loud, not silently write
6
+ * outside the wiki tree.
7
+ *
8
+ * The rule is intentionally narrow — separators / `..` / NUL /
9
+ * empty — so it only rejects unambiguous violations. Aesthetic
10
+ * concerns (e.g. dot-prefixed filenames) are out of scope: a
11
+ * pre-existing `data/wiki/pages/.foo.md` should remain writable
12
+ * through the chokepoint (codex review iter-2 #883). */
13
+ export declare function isSafeSlug(slug: string): boolean;
14
+ /** Slug rules for `[[wiki link]]` text → slug derivation:
15
+ * lowercase, spaces collapsed to hyphens, every non-ASCII /
16
+ * non-alphanumeric / non-hyphen character stripped.
17
+ *
18
+ * Pure: no normalisation, no transliteration — this is the
19
+ * same shape the index parser, page resolver, and frontend
20
+ * renderer all need to agree on. Non-ASCII titles (e.g.
21
+ * Japanese) collapse to an empty string here; callers fall back
22
+ * to other strategies (title-match in the index, or the agent
23
+ * pre-resolving to a slug-form target via `[[slug|display]]`). */
24
+ export declare function wikiSlugify(text: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mulmoclaude/core",
3
- "version": "0.2.15",
3
+ "version": "0.4.0",
4
4
  "description": "Shared server-side core for MulmoClaude and MulmoTerminal — the always-shipped-together subsystems consolidated behind subpath exports so the two hosts can't drift. Server-only except the browser-safe ./whisper/client, ./workspace-setup/slug and ./translation/client entries. All host specifics are injected.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -22,6 +22,30 @@
22
22
  "require": "./dist/collection/paths.cjs",
23
23
  "default": "./dist/collection/paths.js"
24
24
  },
25
+ "./collection/registry": {
26
+ "types": "./dist/collection/registry/index.d.ts",
27
+ "import": "./dist/collection/registry/index.js",
28
+ "require": "./dist/collection/registry/index.cjs",
29
+ "default": "./dist/collection/registry/index.js"
30
+ },
31
+ "./collection/registry/server": {
32
+ "types": "./dist/collection/registry/server/index.d.ts",
33
+ "import": "./dist/collection/registry/server/index.js",
34
+ "require": "./dist/collection/registry/server/index.cjs",
35
+ "default": "./dist/collection/registry/server/index.js"
36
+ },
37
+ "./wiki": {
38
+ "types": "./dist/wiki/index.d.ts",
39
+ "import": "./dist/wiki/index.js",
40
+ "require": "./dist/wiki/index.cjs",
41
+ "default": "./dist/wiki/index.js"
42
+ },
43
+ "./wiki/server": {
44
+ "types": "./dist/wiki/server/index.d.ts",
45
+ "import": "./dist/wiki/server/index.js",
46
+ "require": "./dist/wiki/server/index.cjs",
47
+ "default": "./dist/wiki/server/index.js"
48
+ },
25
49
  "./feeds": {
26
50
  "types": "./dist/feeds/index.d.ts",
27
51
  "import": "./dist/feeds/index.js",