@mulmoclaude/core 4.9.0 → 4.9.2
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/bug-report-faq.md +12 -0
- package/assets/helps/error-recovery.md +144 -29
- package/assets/helps/sandbox.md +2 -2
- package/dist/collection/index.cjs +3 -2
- package/dist/collection/index.cjs.map +1 -1
- package/dist/collection/index.js +3 -2
- package/dist/collection/index.js.map +1 -1
- package/dist/collection/registry/server/index.cjs +3 -3
- package/dist/collection/registry/server/index.js +3 -3
- package/dist/collection/server/index.cjs +2 -2
- package/dist/collection/server/index.js +2 -2
- package/dist/collection-watchers/index.cjs +4 -4
- package/dist/collection-watchers/index.js +4 -4
- package/dist/{discovery-BY-nMCuh.js → discovery-BkIKvdh0.js} +3 -3
- package/dist/discovery-BkIKvdh0.js.map +1 -0
- package/dist/{discovery-2TvulIz8.cjs → discovery-tvFo-bUJ.cjs} +3 -3
- package/dist/discovery-tvFo-bUJ.cjs.map +1 -0
- package/dist/{dist-D8zokgGo.js → dist-BzoA9pDR.js} +6 -1
- package/dist/dist-BzoA9pDR.js.map +1 -0
- package/dist/{dist-CsgSfWwR.cjs → dist-Gj7ygaW2.cjs} +6 -1
- package/dist/dist-Gj7ygaW2.cjs.map +1 -0
- package/dist/errorMessage-BQNpSYdT.js +1 -0
- package/dist/errorMessage-CT-va_Pv.cjs +1 -0
- package/dist/errors-C7TI_t_4.js +10 -0
- package/dist/errors-C7TI_t_4.js.map +1 -0
- package/dist/errors-CdXsfFCF.cjs +15 -0
- package/dist/errors-CdXsfFCF.cjs.map +1 -0
- package/dist/feeds/server/index.cjs +4 -4
- package/dist/feeds/server/index.js +4 -4
- package/dist/google/index.cjs +3 -2
- package/dist/google/index.cjs.map +1 -1
- package/dist/google/index.js +3 -2
- package/dist/google/index.js.map +1 -1
- package/dist/{listen-UZA68Upt.cjs → listen-BXthb-9C.cjs} +2 -2
- package/dist/{listen-UZA68Upt.cjs.map → listen-BXthb-9C.cjs.map} +1 -1
- package/dist/{listen-D5av7GzB.js → listen-Dca-NoBi.js} +2 -2
- package/dist/{listen-D5av7GzB.js.map → listen-Dca-NoBi.js.map} +1 -1
- package/dist/notifier/index.cjs +1 -1
- package/dist/notifier/index.js +1 -1
- package/dist/notifier/types.d.ts +20 -11
- package/dist/{notifier-DZJj0sOh.cjs → notifier-B65Mvngb.cjs} +12 -7
- package/dist/notifier-B65Mvngb.cjs.map +1 -0
- package/dist/{notifier-DhnwR82U.js → notifier-vAp5t6wL.js} +12 -7
- package/dist/notifier-vAp5t6wL.js.map +1 -0
- package/dist/{promptSafety-Bte62OvU.js → promptSafety-BpBTh5xO.js} +2 -2
- package/dist/{promptSafety-Bte62OvU.js.map → promptSafety-BpBTh5xO.js.map} +1 -1
- package/dist/{promptSafety-Cv-SoTd4.cjs → promptSafety-caJWd1ZQ.cjs} +2 -2
- package/dist/{promptSafety-Cv-SoTd4.cjs.map → promptSafety-caJWd1ZQ.cjs.map} +1 -1
- package/dist/remote-host/index.cjs +1 -1
- package/dist/remote-host/index.js +1 -1
- package/dist/remote-host/server/index.cjs +4 -3
- package/dist/remote-host/server/index.cjs.map +1 -1
- package/dist/remote-host/server/index.js +4 -3
- package/dist/remote-host/server/index.js.map +1 -1
- package/dist/{remote-host-CFnl1I-L.js → remote-host-Cjox2F2J.js} +2 -2
- package/dist/{remote-host-CFnl1I-L.js.map → remote-host-Cjox2F2J.js.map} +1 -1
- package/dist/{remote-host-EQPlccB9.cjs → remote-host-DhAHBYzN.cjs} +2 -2
- package/dist/{remote-host-EQPlccB9.cjs.map → remote-host-DhAHBYzN.cjs.map} +1 -1
- package/dist/remote-view/index.cjs +1 -1
- package/dist/remote-view/index.js +1 -1
- package/dist/scheduler/index.cjs +2 -1
- package/dist/scheduler/index.cjs.map +1 -1
- package/dist/scheduler/index.js +2 -1
- package/dist/scheduler/index.js.map +1 -1
- package/dist/{server-DXUt34Rt.cjs → server-Div1i_k5.cjs} +5 -4
- package/dist/{server-DXUt34Rt.cjs.map → server-Div1i_k5.cjs.map} +1 -1
- package/dist/{server-DyYwfNB6.js → server-Dk9x1VLG.js} +5 -4
- package/dist/{server-DyYwfNB6.js.map → server-Dk9x1VLG.js.map} +1 -1
- package/dist/utils/index.cjs +3 -10
- package/dist/utils/index.js +2 -9
- package/dist/whisper/index.cjs +2 -1
- package/dist/whisper/index.cjs.map +1 -1
- package/dist/whisper/index.js +2 -1
- package/dist/whisper/index.js.map +1 -1
- package/dist/wiki/index.cjs +1 -1
- package/dist/wiki/index.js +1 -1
- package/dist/workspace-setup/index.js +5 -0
- package/dist/workspace-setup/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/discovery-2TvulIz8.cjs.map +0 -1
- package/dist/discovery-BY-nMCuh.js.map +0 -1
- package/dist/dist-CsgSfWwR.cjs.map +0 -1
- package/dist/dist-D8zokgGo.js.map +0 -1
- package/dist/notifier-DZJj0sOh.cjs.map +0 -1
- package/dist/notifier-DhnwR82U.js.map +0 -1
- package/dist/utils/index.cjs.map +0 -1
- package/dist/utils/index.js.map +0 -1
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
Object.freeze({
|
|
2
|
+
min: 0,
|
|
3
|
+
max: 65535
|
|
4
|
+
});
|
|
5
|
+
//#endregion
|
|
1
6
|
//#region ../common/dist/index.js
|
|
2
7
|
/** Narrow `unknown` to a plain object (not null, not array). */
|
|
3
8
|
function isRecord(value) {
|
|
@@ -70,4 +75,4 @@ function escapeHtml(value) {
|
|
|
70
75
|
//#endregion
|
|
71
76
|
export { isErrorWithCode as a, isStringArray as c, hasStringProp as i, isUnknownArray as l, escapeHtml as n, isObj as o, hasNumberProp as r, isRecord as s, errorMessage as t };
|
|
72
77
|
|
|
73
|
-
//# sourceMappingURL=dist-
|
|
78
|
+
//# sourceMappingURL=dist-BzoA9pDR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dist-BzoA9pDR.js","names":[],"sources":["../../common/dist/envCoerce.js","../../common/dist/index.js"],"sourcesContent":["// Env-var type coercion for ports and other integer settings.\n//\n// It started inside `server/system/env.ts` (#504-era), moved to\n// `server/utils/envCoerce.ts` when #2650 needed the SAME rule for `yarn dev`'s\n// Vite proxy — the proxy has to resolve `PORT` exactly as the backend does, or\n// the two point at different servers — and moved here when #3084 needed it for\n// the messaging bridges too. A second opinion about \"is this a port\" is that\n// bug one level down, so there is exactly one copy and every tier imports it.\n/**\n * `Number()`-based integer coercion with an optional range, falling back when the\n * value is absent, empty, non-integer, or out of range.\n *\n * `Number()` — not `parseInt` — on purpose: it is what the server has always used,\n * so `0x1f`, `1e3`, `+3100` and `3100.0` coerce exactly as they did, and a\n * whitespace-only value coerces to 0. Anything stricter here would silently\n * disagree with the backend.\n */\nexport function asInt(value, fallback, opts = {}) {\n if (value === undefined || value === \"\")\n return fallback;\n const parsed = Number(value);\n if (!Number.isInteger(parsed))\n return fallback;\n if (opts.min !== undefined && parsed < opts.min)\n return fallback;\n if (opts.max !== undefined && parsed > opts.max)\n return fallback;\n return parsed;\n}\n/** The port range the backend accepts, so both sides bound the value identically.\n * `min: 0` is deliberate — 0 asks the OS for an ephemeral port.\n *\n * `Required<IntRange>`, not `IntRange`: both bounds are always present here, and\n * saying so lets a caller compare against them (`port <= PORT_RANGE.max`) without\n * a non-null assertion. Still assignable wherever an `IntRange` is expected. */\nexport const PORT_RANGE = Object.freeze({ min: 0, max: 65_535 });\n","// General-purpose runtime type guards, shared across the MulmoClaude host,\n// bridges, and plugins. This is a leaf package — pure and dependency-free — so\n// any tier can import it without creating an uphill edge.\n//\n// These originated as `server/utils/types.ts` (#504), which centralised 40+\n// hand-written inline `typeof x === \"object\"` checks. They are promoted here so\n// the same guards stop being re-hand-written in every bridge and plugin too.\n/** Narrow `unknown` to a plain object (not null, not array). */\nexport function isRecord(value) {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n/** Narrow `unknown` to any object (not null, arrays allowed).\n * Use `isRecord` when you need to access string keys. */\nexport function isObj(value) {\n return typeof value === \"object\" && value !== null;\n}\n/** Non-empty string after trimming whitespace. */\nexport function isNonEmptyString(value) {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n/** Record whose values are all strings. */\nexport function isStringRecord(value) {\n if (!isRecord(value))\n return false;\n return Object.values(value).every((val) => typeof val === \"string\");\n}\n/** String array (every element is a string). */\nexport function isStringArray(value) {\n return Array.isArray(value) && value.every((val) => typeof val === \"string\");\n}\n/** An array of unknowns. Prefer this over a bare `Array.isArray` in typed code:\n * `Array.isArray(x: unknown)` narrows to `any[]`, silently reintroducing\n * `any`, whereas this keeps the element type `unknown`. */\nexport function isUnknownArray(value) {\n return Array.isArray(value);\n}\n/** Error-like object with a `code` property (e.g. Node.js fs errors). */\nexport function isErrorWithCode(value) {\n return isRecord(value) && typeof value.code === \"string\";\n}\n/** Check that a record has a specific key with a string value. */\nexport function hasStringProp(value, key) {\n return isRecord(value) && typeof value[key] === \"string\";\n}\n/** Check that a record has a specific key with a number value. */\nexport function hasNumberProp(value, key) {\n return isRecord(value) && typeof value[key] === \"number\";\n}\n/** Split a comma-separated env value into trimmed, non-empty entries.\n * `lowercase` folds case for identifiers compared case-insensitively\n * (JIDs, email addresses, hex pubkeys). Absent/empty input → empty list. */\nexport function parseCsvList(raw, opts) {\n return (raw ?? \"\")\n .split(\",\")\n .map((entry) => (opts?.lowercase ? entry.trim().toLowerCase() : entry.trim()))\n .filter(Boolean);\n}\n/** A comma-separated env value as a Set — the canonical allowlist shape,\n * where an empty set is the \"allow all\" sentinel (`set.size === 0`). */\nexport function parseCsvSet(raw, opts) {\n return new Set(parseCsvList(raw, opts));\n}\n/** Normalise an unknown thrown value into a human-readable string. Isomorphic\n * (host, bridges, plugins, Vue) — this is the single home for the helper that\n * #2217 could only consolidate for server code, since `@mulmoclaude/core/utils`\n * is server-only.\n *\n * A non-Error object with a non-empty string `details` (gRPC convention) or\n * `message` field surfaces that field — `details` wins — instead of the\n * `[object Object]` a bare `String(err)` would print; an empty-string field\n * falls through. `fallback` covers the error-boundary idiom where a thrown\n * non-Error should read as a descriptive message rather than `String(err)`\n * noise; omit it in logging contexts where `String(err)` is fine. */\nexport function errorMessage(err, fallback) {\n if (err instanceof Error)\n return err.message;\n if (hasStringProp(err, \"details\") && err.details)\n return err.details;\n if (hasStringProp(err, \"message\") && err.message)\n return err.message;\n if (fallback !== undefined)\n return fallback;\n return String(err);\n}\n/** `Date` → `YYYY-MM-DD` in UTC — for dates that must not shift with the\n * host's local timezone (tool-trace search dirs, API date keys). Isomorphic\n * single source (#2480): the host re-exports it from `server/utils/date.ts`,\n * x-plugin imports it directly. The `@receptron/task-scheduler` copy stays\n * local on purpose — that leaf package is published independently and kept\n * dependency-free. Wall-clock questions use the host's `toLocalIsoDate`. */\nexport function toUtcIsoDate(timestamp) {\n const year = timestamp.getUTCFullYear();\n const month = String(timestamp.getUTCMonth() + 1).padStart(2, \"0\");\n const day = String(timestamp.getUTCDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n}\n// A Map, not an object literal: `{}[char]` reads through the prototype chain,\n// so a future caller widening the regex would silently get `[object Object]`\n// for keys like `constructor`.\nconst HTML_ESCAPES = new Map([\n [\"&\", \"&\"],\n [\"<\", \"<\"],\n [\">\", \">\"],\n ['\"', \""\"],\n [\"'\", \"'\"],\n]);\n/** HTML-escape text destined for markup or an attribute value — the fixed\n * five-character map, nothing more. Lives here rather than in\n * `@mulmoclaude/core/wiki` (#2483) because `@mulmoclaude/markdown-utils` is a\n * leaf that core depends on and so cannot import back up; core/wiki\n * re-exports this, keeping its consumers' import path unchanged.\n *\n * Escaping `&` first is what makes a single pass safe — the entities this\n * introduces contain none of the other four characters, so nothing is\n * double-escaped. Not a sanitiser: it neither strips tags nor validates URLs. */\nexport function escapeHtml(value) {\n return value.replace(/[&<>\"']/g, (char) => HTML_ESCAPES.get(char) ?? char);\n}\n/** Split a JWS compact serialization into its three segments, or `null` when the\n * token isn't well-formed. Pure string work, so the Node bridges and the\n * Cloudflare Workers relay — which decode the segments differently (`Buffer` vs\n * `atob`) — can still share this one guard.\n *\n * A JWS compact serialization is EXACTLY three segments. Both a short token and\n * a longer one (a five-segment JWE, or an attacker appending `.junk`) are\n * rejected outright — never parsed from their first three segments, which would\n * let the signed input disagree with the token. */\nexport function splitJwtSegments(token) {\n const [headerSegment, payloadSegment, signatureSegment, ...extraSegments] = token.split(\".\");\n if (headerSegment === undefined || payloadSegment === undefined || signatureSegment === undefined)\n return null;\n if (extraSegments.length > 0)\n return null;\n return { headerSegment, payloadSegment, signatureSegment };\n}\nexport { scanEnvOptions, snakeToLowerCamel } from \"./envScan.js\";\nexport { asInt, PORT_RANGE } from \"./envCoerce.js\";\n"],"mappings":"AAmC0B,OAAO,OAAO;CAAE,KAAK;CAAG,KAAK;AAAO,CAAC;;;;AC3B/D,SAAgB,SAAS,OAAO;CAC5B,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC9E;;;AAGA,SAAgB,MAAM,OAAO;CACzB,OAAO,OAAO,UAAU,YAAY,UAAU;AAClD;;AAYA,SAAgB,cAAc,OAAO;CACjC,OAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,OAAO,QAAQ,OAAO,QAAQ,QAAQ;AAC/E;;;;AAIA,SAAgB,eAAe,OAAO;CAClC,OAAO,MAAM,QAAQ,KAAK;AAC9B;;AAEA,SAAgB,gBAAgB,OAAO;CACnC,OAAO,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS;AACpD;;AAEA,SAAgB,cAAc,OAAO,KAAK;CACtC,OAAO,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS;AACpD;;AAEA,SAAgB,cAAc,OAAO,KAAK;CACtC,OAAO,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS;AACpD;;;;;;;;;;;;AA0BA,SAAgB,aAAa,KAAK,UAAU;CACxC,IAAI,eAAe,OACf,OAAO,IAAI;CACf,IAAI,cAAc,KAAK,SAAS,KAAK,IAAI,SACrC,OAAO,IAAI;CACf,IAAI,cAAc,KAAK,SAAS,KAAK,IAAI,SACrC,OAAO,IAAI;CACf,IAAI,aAAa,KAAA,GACb,OAAO;CACX,OAAO,OAAO,GAAG;AACrB;AAgBA,IAAM,+BAAe,IAAI,IAAI;CACzB,CAAC,KAAK,OAAO;CACb,CAAC,KAAK,MAAM;CACZ,CAAC,KAAK,MAAM;CACZ,CAAC,MAAK,QAAQ;CACd,CAAC,KAAK,OAAO;AACjB,CAAC;;;;;;;;;;AAUD,SAAgB,WAAW,OAAO;CAC9B,OAAO,MAAM,QAAQ,aAAa,SAAS,aAAa,IAAI,IAAI,KAAK,IAAI;AAC7E"}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
Object.freeze({
|
|
2
|
+
min: 0,
|
|
3
|
+
max: 65535
|
|
4
|
+
});
|
|
5
|
+
//#endregion
|
|
1
6
|
//#region ../common/dist/index.js
|
|
2
7
|
/** Narrow `unknown` to a plain object (not null, not array). */
|
|
3
8
|
function isRecord(value) {
|
|
@@ -123,4 +128,4 @@ Object.defineProperty(exports, "isUnknownArray", {
|
|
|
123
128
|
}
|
|
124
129
|
});
|
|
125
130
|
|
|
126
|
-
//# sourceMappingURL=dist-
|
|
131
|
+
//# sourceMappingURL=dist-Gj7ygaW2.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dist-Gj7ygaW2.cjs","names":[],"sources":["../../common/dist/envCoerce.js","../../common/dist/index.js"],"sourcesContent":["// Env-var type coercion for ports and other integer settings.\n//\n// It started inside `server/system/env.ts` (#504-era), moved to\n// `server/utils/envCoerce.ts` when #2650 needed the SAME rule for `yarn dev`'s\n// Vite proxy — the proxy has to resolve `PORT` exactly as the backend does, or\n// the two point at different servers — and moved here when #3084 needed it for\n// the messaging bridges too. A second opinion about \"is this a port\" is that\n// bug one level down, so there is exactly one copy and every tier imports it.\n/**\n * `Number()`-based integer coercion with an optional range, falling back when the\n * value is absent, empty, non-integer, or out of range.\n *\n * `Number()` — not `parseInt` — on purpose: it is what the server has always used,\n * so `0x1f`, `1e3`, `+3100` and `3100.0` coerce exactly as they did, and a\n * whitespace-only value coerces to 0. Anything stricter here would silently\n * disagree with the backend.\n */\nexport function asInt(value, fallback, opts = {}) {\n if (value === undefined || value === \"\")\n return fallback;\n const parsed = Number(value);\n if (!Number.isInteger(parsed))\n return fallback;\n if (opts.min !== undefined && parsed < opts.min)\n return fallback;\n if (opts.max !== undefined && parsed > opts.max)\n return fallback;\n return parsed;\n}\n/** The port range the backend accepts, so both sides bound the value identically.\n * `min: 0` is deliberate — 0 asks the OS for an ephemeral port.\n *\n * `Required<IntRange>`, not `IntRange`: both bounds are always present here, and\n * saying so lets a caller compare against them (`port <= PORT_RANGE.max`) without\n * a non-null assertion. Still assignable wherever an `IntRange` is expected. */\nexport const PORT_RANGE = Object.freeze({ min: 0, max: 65_535 });\n","// General-purpose runtime type guards, shared across the MulmoClaude host,\n// bridges, and plugins. This is a leaf package — pure and dependency-free — so\n// any tier can import it without creating an uphill edge.\n//\n// These originated as `server/utils/types.ts` (#504), which centralised 40+\n// hand-written inline `typeof x === \"object\"` checks. They are promoted here so\n// the same guards stop being re-hand-written in every bridge and plugin too.\n/** Narrow `unknown` to a plain object (not null, not array). */\nexport function isRecord(value) {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n/** Narrow `unknown` to any object (not null, arrays allowed).\n * Use `isRecord` when you need to access string keys. */\nexport function isObj(value) {\n return typeof value === \"object\" && value !== null;\n}\n/** Non-empty string after trimming whitespace. */\nexport function isNonEmptyString(value) {\n return typeof value === \"string\" && value.trim().length > 0;\n}\n/** Record whose values are all strings. */\nexport function isStringRecord(value) {\n if (!isRecord(value))\n return false;\n return Object.values(value).every((val) => typeof val === \"string\");\n}\n/** String array (every element is a string). */\nexport function isStringArray(value) {\n return Array.isArray(value) && value.every((val) => typeof val === \"string\");\n}\n/** An array of unknowns. Prefer this over a bare `Array.isArray` in typed code:\n * `Array.isArray(x: unknown)` narrows to `any[]`, silently reintroducing\n * `any`, whereas this keeps the element type `unknown`. */\nexport function isUnknownArray(value) {\n return Array.isArray(value);\n}\n/** Error-like object with a `code` property (e.g. Node.js fs errors). */\nexport function isErrorWithCode(value) {\n return isRecord(value) && typeof value.code === \"string\";\n}\n/** Check that a record has a specific key with a string value. */\nexport function hasStringProp(value, key) {\n return isRecord(value) && typeof value[key] === \"string\";\n}\n/** Check that a record has a specific key with a number value. */\nexport function hasNumberProp(value, key) {\n return isRecord(value) && typeof value[key] === \"number\";\n}\n/** Split a comma-separated env value into trimmed, non-empty entries.\n * `lowercase` folds case for identifiers compared case-insensitively\n * (JIDs, email addresses, hex pubkeys). Absent/empty input → empty list. */\nexport function parseCsvList(raw, opts) {\n return (raw ?? \"\")\n .split(\",\")\n .map((entry) => (opts?.lowercase ? entry.trim().toLowerCase() : entry.trim()))\n .filter(Boolean);\n}\n/** A comma-separated env value as a Set — the canonical allowlist shape,\n * where an empty set is the \"allow all\" sentinel (`set.size === 0`). */\nexport function parseCsvSet(raw, opts) {\n return new Set(parseCsvList(raw, opts));\n}\n/** Normalise an unknown thrown value into a human-readable string. Isomorphic\n * (host, bridges, plugins, Vue) — this is the single home for the helper that\n * #2217 could only consolidate for server code, since `@mulmoclaude/core/utils`\n * is server-only.\n *\n * A non-Error object with a non-empty string `details` (gRPC convention) or\n * `message` field surfaces that field — `details` wins — instead of the\n * `[object Object]` a bare `String(err)` would print; an empty-string field\n * falls through. `fallback` covers the error-boundary idiom where a thrown\n * non-Error should read as a descriptive message rather than `String(err)`\n * noise; omit it in logging contexts where `String(err)` is fine. */\nexport function errorMessage(err, fallback) {\n if (err instanceof Error)\n return err.message;\n if (hasStringProp(err, \"details\") && err.details)\n return err.details;\n if (hasStringProp(err, \"message\") && err.message)\n return err.message;\n if (fallback !== undefined)\n return fallback;\n return String(err);\n}\n/** `Date` → `YYYY-MM-DD` in UTC — for dates that must not shift with the\n * host's local timezone (tool-trace search dirs, API date keys). Isomorphic\n * single source (#2480): the host re-exports it from `server/utils/date.ts`,\n * x-plugin imports it directly. The `@receptron/task-scheduler` copy stays\n * local on purpose — that leaf package is published independently and kept\n * dependency-free. Wall-clock questions use the host's `toLocalIsoDate`. */\nexport function toUtcIsoDate(timestamp) {\n const year = timestamp.getUTCFullYear();\n const month = String(timestamp.getUTCMonth() + 1).padStart(2, \"0\");\n const day = String(timestamp.getUTCDate()).padStart(2, \"0\");\n return `${year}-${month}-${day}`;\n}\n// A Map, not an object literal: `{}[char]` reads through the prototype chain,\n// so a future caller widening the regex would silently get `[object Object]`\n// for keys like `constructor`.\nconst HTML_ESCAPES = new Map([\n [\"&\", \"&\"],\n [\"<\", \"<\"],\n [\">\", \">\"],\n ['\"', \""\"],\n [\"'\", \"'\"],\n]);\n/** HTML-escape text destined for markup or an attribute value — the fixed\n * five-character map, nothing more. Lives here rather than in\n * `@mulmoclaude/core/wiki` (#2483) because `@mulmoclaude/markdown-utils` is a\n * leaf that core depends on and so cannot import back up; core/wiki\n * re-exports this, keeping its consumers' import path unchanged.\n *\n * Escaping `&` first is what makes a single pass safe — the entities this\n * introduces contain none of the other four characters, so nothing is\n * double-escaped. Not a sanitiser: it neither strips tags nor validates URLs. */\nexport function escapeHtml(value) {\n return value.replace(/[&<>\"']/g, (char) => HTML_ESCAPES.get(char) ?? char);\n}\n/** Split a JWS compact serialization into its three segments, or `null` when the\n * token isn't well-formed. Pure string work, so the Node bridges and the\n * Cloudflare Workers relay — which decode the segments differently (`Buffer` vs\n * `atob`) — can still share this one guard.\n *\n * A JWS compact serialization is EXACTLY three segments. Both a short token and\n * a longer one (a five-segment JWE, or an attacker appending `.junk`) are\n * rejected outright — never parsed from their first three segments, which would\n * let the signed input disagree with the token. */\nexport function splitJwtSegments(token) {\n const [headerSegment, payloadSegment, signatureSegment, ...extraSegments] = token.split(\".\");\n if (headerSegment === undefined || payloadSegment === undefined || signatureSegment === undefined)\n return null;\n if (extraSegments.length > 0)\n return null;\n return { headerSegment, payloadSegment, signatureSegment };\n}\nexport { scanEnvOptions, snakeToLowerCamel } from \"./envScan.js\";\nexport { asInt, PORT_RANGE } from \"./envCoerce.js\";\n"],"mappings":"AAmC0B,OAAO,OAAO;CAAE,KAAK;CAAG,KAAK;AAAO,CAAC;;;;AC3B/D,SAAgB,SAAS,OAAO;CAC5B,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC9E;;;AAGA,SAAgB,MAAM,OAAO;CACzB,OAAO,OAAO,UAAU,YAAY,UAAU;AAClD;;AAYA,SAAgB,cAAc,OAAO;CACjC,OAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,OAAO,QAAQ,OAAO,QAAQ,QAAQ;AAC/E;;;;AAIA,SAAgB,eAAe,OAAO;CAClC,OAAO,MAAM,QAAQ,KAAK;AAC9B;;AAEA,SAAgB,gBAAgB,OAAO;CACnC,OAAO,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS;AACpD;;AAEA,SAAgB,cAAc,OAAO,KAAK;CACtC,OAAO,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS;AACpD;;AAEA,SAAgB,cAAc,OAAO,KAAK;CACtC,OAAO,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS;AACpD;;;;;;;;;;;;AA0BA,SAAgB,aAAa,KAAK,UAAU;CACxC,IAAI,eAAe,OACf,OAAO,IAAI;CACf,IAAI,cAAc,KAAK,SAAS,KAAK,IAAI,SACrC,OAAO,IAAI;CACf,IAAI,cAAc,KAAK,SAAS,KAAK,IAAI,SACrC,OAAO,IAAI;CACf,IAAI,aAAa,KAAA,GACb,OAAO;CACX,OAAO,OAAO,GAAG;AACrB;AAgBA,IAAM,+BAAe,IAAI,IAAI;CACzB,CAAC,KAAK,OAAO;CACb,CAAC,KAAK,MAAM;CACZ,CAAC,KAAK,MAAM;CACZ,CAAC,MAAK,QAAQ;CACd,CAAC,KAAK,OAAO;AACjB,CAAC;;;;;;;;;;AAUD,SAAgB,WAAW,OAAO;CAC9B,OAAO,MAAM,QAAQ,aAAa,SAAS,aAAa,IAAI,IAAI,KAAK,IAAI;AAC7E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "./errors-C7TI_t_4.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require("./errors-CdXsfFCF.cjs");
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { t as errorMessage } from "./dist-BzoA9pDR.js";
|
|
2
|
+
//#region src/utils/errors.ts
|
|
3
|
+
function toError(err, fallback) {
|
|
4
|
+
if (err instanceof Error) return err;
|
|
5
|
+
return new Error(fallback ?? errorMessage(err));
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { toError as t };
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=errors-C7TI_t_4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-C7TI_t_4.js","names":[],"sources":["../src/utils/errors.ts"],"sourcesContent":["// Canonical error helpers for the whole monorepo. Host (`server/`, `src/`)\n// re-exports these rather than keeping its own copy — before #2217 the same\n// function existed 14 times across 4 behaviours, and the two that mattered\n// disagreed on gRPC-shaped errors: `{ code, details, metadata }` surfaced as\n// \"quota exceeded\" through the host copy and as \"[object Object]\" through the\n// core ones.\n//\n// `errorMessage` itself now lives in `@mulmoclaude/common` (browser-safe leaf,\n// zero deps) so the Vue plugin surfaces can share the one implementation\n// instead of hand-copying it — `@mulmoclaude/core/utils` is server-only and\n// unreachable from browser code. This module keeps the same import surface so\n// no core/host consumer of `errorMessage` breaks.\nimport { errorMessage } from \"@mulmoclaude/common\";\n\nexport { errorMessage };\n\n// Coerce an unknown caught value into an Error, preserving the original if it\n// already was one. Use in error boundaries / Promise rejections / event-handler\n// onerror callbacks where the downstream API wants an Error object.\n//\n// `fallback` is the message used when coercing a non-Error value — pass a\n// descriptive string for cases where `String(err)` would just produce noise\n// (e.g. `<img>.onerror` hands you an Event, not the underlying load failure).\nexport function toError(err: unknown, fallback?: string): Error {\n if (err instanceof Error) return err;\n return new Error(fallback ?? errorMessage(err));\n}\n"],"mappings":";;AAuBA,SAAgB,QAAQ,KAAc,UAA0B;CAC9D,IAAI,eAAe,OAAO,OAAO;CACjC,OAAO,IAAI,MAAM,YAAY,aAAa,GAAG,CAAC;AAChD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const require_dist = require("./dist-Gj7ygaW2.cjs");
|
|
2
|
+
//#region src/utils/errors.ts
|
|
3
|
+
function toError(err, fallback) {
|
|
4
|
+
if (err instanceof Error) return err;
|
|
5
|
+
return new Error(fallback ?? require_dist.errorMessage(err));
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
Object.defineProperty(exports, "toError", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function() {
|
|
11
|
+
return toError;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=errors-CdXsfFCF.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-CdXsfFCF.cjs","names":[],"sources":["../src/utils/errors.ts"],"sourcesContent":["// Canonical error helpers for the whole monorepo. Host (`server/`, `src/`)\n// re-exports these rather than keeping its own copy — before #2217 the same\n// function existed 14 times across 4 behaviours, and the two that mattered\n// disagreed on gRPC-shaped errors: `{ code, details, metadata }` surfaced as\n// \"quota exceeded\" through the host copy and as \"[object Object]\" through the\n// core ones.\n//\n// `errorMessage` itself now lives in `@mulmoclaude/common` (browser-safe leaf,\n// zero deps) so the Vue plugin surfaces can share the one implementation\n// instead of hand-copying it — `@mulmoclaude/core/utils` is server-only and\n// unreachable from browser code. This module keeps the same import surface so\n// no core/host consumer of `errorMessage` breaks.\nimport { errorMessage } from \"@mulmoclaude/common\";\n\nexport { errorMessage };\n\n// Coerce an unknown caught value into an Error, preserving the original if it\n// already was one. Use in error boundaries / Promise rejections / event-handler\n// onerror callbacks where the downstream API wants an Error object.\n//\n// `fallback` is the message used when coercing a non-Error value — pass a\n// descriptive string for cases where `String(err)` would just produce noise\n// (e.g. `<img>.onerror` hands you an Event, not the underlying load failure).\nexport function toError(err: unknown, fallback?: string): Error {\n if (err instanceof Error) return err;\n return new Error(fallback ?? errorMessage(err));\n}\n"],"mappings":";;AAuBA,SAAgB,QAAQ,KAAc,UAA0B;CAC9D,IAAI,eAAe,OAAO,OAAO;CACjC,OAAO,IAAI,MAAM,YAAY,aAAA,aAAa,GAAG,CAAC;AAChD"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_rolldown_runtime = require("../../rolldown-runtime-VH7oDXx4.cjs");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-Gj7ygaW2.cjs");
|
|
4
4
|
const require_root = require("../../root-BvwBUcol.cjs");
|
|
5
5
|
const require_itemId = require("../../itemId-CGT2J7YK.cjs");
|
|
6
6
|
const require_project = require("../../project-C1ep9pvo.cjs");
|
|
7
|
-
const require_discovery = require("../../discovery-
|
|
8
|
-
const require_server = require("../../server-
|
|
7
|
+
const require_discovery = require("../../discovery-tvFo-bUJ.cjs");
|
|
8
|
+
const require_server = require("../../server-Div1i_k5.cjs");
|
|
9
9
|
const require_feeds_paths = require("../paths.cjs");
|
|
10
10
|
const require_ingestTypes = require("../../ingestTypes-DsVH9BYy.cjs");
|
|
11
|
-
const require_notifier = require("../../notifier-
|
|
11
|
+
const require_notifier = require("../../notifier-B65Mvngb.cjs");
|
|
12
12
|
let node_path = require("node:path");
|
|
13
13
|
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
14
14
|
let node_crypto = require("node:crypto");
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { a as isErrorWithCode, l as isUnknownArray, s as isRecord$1 } from "../../dist-
|
|
1
|
+
import { a as isErrorWithCode, l as isUnknownArray, s as isRecord$1 } from "../../dist-BzoA9pDR.js";
|
|
2
2
|
import { t as canonicalRoot } from "../../root-BcS4-Kge.js";
|
|
3
3
|
import { G as INGEST_KINDS, W as FEED_SCHEDULES } from "../../itemId-4P9S_ehz.js";
|
|
4
4
|
import { t as mergeIntoExisting } from "../../project-B0j_Vf_Q.js";
|
|
5
|
-
import { W as resolveDataDir, _t as createForwardingLogger, d as storeFor, k as listItems, n as discoverCollections, q as safeSlugName, vt as createHostSlot } from "../../discovery-
|
|
6
|
-
import { F as buildCollectionActionSeedPrompt, I as promptPathsFor, z as readSkillTemplate } from "../../server-
|
|
5
|
+
import { W as resolveDataDir, _t as createForwardingLogger, d as storeFor, k as listItems, n as discoverCollections, q as safeSlugName, vt as createHostSlot } from "../../discovery-BkIKvdh0.js";
|
|
6
|
+
import { F as buildCollectionActionSeedPrompt, I as promptPathsFor, z as readSkillTemplate } from "../../server-Dk9x1VLG.js";
|
|
7
7
|
import { FEEDS_DIR, feedDir, feedStatePath, feedsRoot, ingestStateDir, ingestStatePath } from "../paths.js";
|
|
8
8
|
import { n as DEFAULT_FEED_MAX_ITEMS, r as isFeedSchedule, t as AGENT_INGEST_KIND } from "../../ingestTypes-GkG7bJdB.js";
|
|
9
|
-
import { d as publish, n as clear } from "../../notifier-
|
|
9
|
+
import { d as publish, n as clear } from "../../notifier-vAp5t6wL.js";
|
|
10
10
|
import path from "node:path";
|
|
11
11
|
import { createHash } from "node:crypto";
|
|
12
12
|
import { mkdir, readFile, rm } from "node:fs/promises";
|
package/dist/google/index.cjs
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_rolldown_runtime = require("../rolldown-runtime-VH7oDXx4.cjs");
|
|
3
|
-
const require_dist = require("../dist-
|
|
3
|
+
const require_dist = require("../dist-Gj7ygaW2.cjs");
|
|
4
|
+
require("../errors-CdXsfFCF.cjs");
|
|
4
5
|
const require_text = require("../text-CaAh9ZSO.cjs");
|
|
5
6
|
const require_root = require("../root-BvwBUcol.cjs");
|
|
6
7
|
const require_utils_fetch = require("../utils/fetch.cjs");
|
|
7
8
|
const require_itemId = require("../itemId-CGT2J7YK.cjs");
|
|
8
9
|
const require_project = require("../project-C1ep9pvo.cjs");
|
|
9
|
-
const require_discovery = require("../discovery-
|
|
10
|
+
const require_discovery = require("../discovery-tvFo-bUJ.cjs");
|
|
10
11
|
const require_paths = require("../paths-C8-jxR0s.cjs");
|
|
11
12
|
let node_fs = require("node:fs");
|
|
12
13
|
let node_path = require("node:path");
|