@kanadego/dsh-heartbeat 1.9.3 → 2.0.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/LICENSE +21 -21
- package/README.md +103 -110
- package/client.js +12 -0
- package/config/policy.json +74 -74
- package/config/profile-schema.json +306 -306
- package/dist/{bindings-225SI7KC.js → bindings-U2M3CO2D.js} +3 -3
- package/dist/{chunk-TY6UP74X.js → chunk-3DNGY4DS.js} +2 -2
- package/dist/{chunk-CUOSICYJ.js → chunk-544QOJN5.js} +397 -23
- package/dist/chunk-544QOJN5.js.map +1 -0
- package/dist/{chunk-TRO4E6WG.js → chunk-6MVKWICX.js} +587 -139
- package/dist/chunk-6MVKWICX.js.map +1 -0
- package/dist/{chunk-WLZSABBH.js → chunk-6XM6KY7M.js} +27 -10
- package/dist/chunk-6XM6KY7M.js.map +1 -0
- package/dist/chunk-AKIJ4LS2.js +680 -0
- package/dist/chunk-AKIJ4LS2.js.map +1 -0
- package/dist/{chunk-KB5SMG3F.js → chunk-DC5HMCJC.js} +3 -3
- package/dist/{chunk-3MDBU6WY.js → chunk-DZ7YCFGX.js} +37 -7
- package/dist/chunk-DZ7YCFGX.js.map +1 -0
- package/dist/{chunk-WRUTATW4.js → chunk-IBBAISSW.js} +13 -2
- package/dist/chunk-IBBAISSW.js.map +1 -0
- package/dist/{chunk-XYYEJK3W.js → chunk-IFRMKVIC.js} +82 -21
- package/dist/chunk-IFRMKVIC.js.map +1 -0
- package/dist/{chunk-XFNCTOW7.js → chunk-NCPKOWS7.js} +52 -4
- package/dist/chunk-NCPKOWS7.js.map +1 -0
- package/dist/{chunk-JDH2LDFS.js → chunk-TVX4HV4Y.js} +4 -6
- package/dist/{chunk-JDH2LDFS.js.map → chunk-TVX4HV4Y.js.map} +1 -1
- package/dist/cli/index.js +149 -26
- package/dist/cli/index.js.map +1 -1
- package/dist/{inbox-P26DDMWC.js → inbox-OWBK6PE2.js} +8 -7
- package/dist/index.d.ts +48 -315
- package/dist/index.js +259 -918
- package/dist/index.js.map +1 -1
- package/dist/migrate-TQ5PB2DI.js +27 -0
- package/dist/{orchestrator-ZPRGVDCB.js → orchestrator-P7AEWVYR.js} +23 -12
- package/dist/{pool-UTXQJJ5C.js → pool-2T6TVS2L.js} +4 -5
- package/dist/{snapshot-K5VHETTK.js → snapshot-F5B2DD56.js} +5 -5
- package/package.json +84 -83
- package/dist/chunk-3MDBU6WY.js.map +0 -1
- package/dist/chunk-CUOSICYJ.js.map +0 -1
- package/dist/chunk-IV2ZWQA3.js +0 -56
- package/dist/chunk-IV2ZWQA3.js.map +0 -1
- package/dist/chunk-K5Y6JP2B.js +0 -399
- package/dist/chunk-K5Y6JP2B.js.map +0 -1
- package/dist/chunk-TRO4E6WG.js.map +0 -1
- package/dist/chunk-WLZSABBH.js.map +0 -1
- package/dist/chunk-WRUTATW4.js.map +0 -1
- package/dist/chunk-XFNCTOW7.js.map +0 -1
- package/dist/chunk-XYYEJK3W.js.map +0 -1
- package/dist/migrate-D4VKAKYT.js +0 -21
- /package/dist/{bindings-225SI7KC.js.map → bindings-U2M3CO2D.js.map} +0 -0
- /package/dist/{chunk-TY6UP74X.js.map → chunk-3DNGY4DS.js.map} +0 -0
- /package/dist/{chunk-KB5SMG3F.js.map → chunk-DC5HMCJC.js.map} +0 -0
- /package/dist/{inbox-P26DDMWC.js.map → inbox-OWBK6PE2.js.map} +0 -0
- /package/dist/{migrate-D4VKAKYT.js.map → migrate-TQ5PB2DI.js.map} +0 -0
- /package/dist/{orchestrator-ZPRGVDCB.js.map → orchestrator-P7AEWVYR.js.map} +0 -0
- /package/dist/{pool-UTXQJJ5C.js.map → pool-2T6TVS2L.js.map} +0 -0
- /package/dist/{snapshot-K5VHETTK.js.map → snapshot-F5B2DD56.js.map} +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.5/node_modules/@deepseek-ai/cosmokit/lib/index.js","../node_modules/.pnpm/@deepseek-ai+schemastery@3.18.4/node_modules/@deepseek-ai/schemastery/lib/index.mjs","../src/config/ui-config.ts","../src/rpc.ts","../src/browse/interests-edit.ts","../src/statusbar/time-inject.ts","../src/statusbar/track.ts","../src/core/preset-definition.ts","../src/ledger/tool.ts","../src/index.ts"],"sourcesContent":["//#region lib/types/misc.js\n/** No-op callback returning `undefined` at runtime and `any` at type level. */\nfunction noop() {}\n/** Return true when a value is `null` or `undefined`. */\nfunction isNullable(value) {\n\treturn value === null || value === void 0;\n}\n/** Return true when a value is neither `null` nor `undefined`. */\nfunction isNonNullable(value) {\n\treturn !isNullable(value);\n}\n/** Return true for non-array object values. */\nfunction isPlainObject(data) {\n\treturn data && typeof data === \"object\" && !Array.isArray(data);\n}\n/** Filter object entries and return a new object. */\nfunction filterKeys(object, filter) {\n\treturn Object.fromEntries(Object.entries(object).filter(([key, value]) => filter(key, value)));\n}\n/** Map object values while preserving the original key set. */\nfunction mapValues(object, transform) {\n\treturn Object.fromEntries(Object.entries(object).map(([key, value]) => [key, transform(value, key)]));\n}\n/** Pick selected keys from an object, optionally including `undefined` values. */\nfunction pick(source, keys, forced) {\n\tif (!keys) return { ...source };\n\tconst result = {};\n\tfor (const key of keys) if (forced || source[key] !== void 0) result[key] = source[key];\n\treturn result;\n}\n/** Omit selected keys from a shallow object copy. */\nfunction omit(source, keys) {\n\tif (!keys) return { ...source };\n\tconst result = { ...source };\n\tfor (const key of keys) Reflect.deleteProperty(result, key);\n\treturn result;\n}\n/** Define a non-enumerable writable property and return the object. */\nfunction defineProperty(object, key, value) {\n\treturn Object.defineProperty(object, key, {\n\t\twritable: true,\n\t\tvalue,\n\t\tenumerable: false\n\t});\n}\n//#endregion\n//#region lib/types/array.js\n/** Return true when every item in `array2` is present in `array1`. */\nfunction contain(array1, array2) {\n\treturn array2.every((item) => array1.includes(item));\n}\n/** Return items that appear in both arrays. */\nfunction intersection(array1, array2) {\n\treturn array1.filter((item) => array2.includes(item));\n}\n/** Return items from `array1` that do not appear in `array2`. */\nfunction difference(array1, array2) {\n\treturn array1.filter((item) => !array2.includes(item));\n}\n/** Return the set-union of two arrays while preserving first occurrence order. */\nfunction union(array1, array2) {\n\treturn Array.from(new Set([...array1, ...array2]));\n}\n/** Remove duplicate values while preserving first occurrence order. */\nfunction deduplicate(array) {\n\treturn [...new Set(array)];\n}\n/** Remove one item from an array and report whether it was found. */\nfunction remove(list, item) {\n\tconst index = list?.indexOf(item);\n\tif (index >= 0) {\n\t\tlist.splice(index, 1);\n\t\treturn true;\n\t} else return false;\n}\n/** Normalize nullish, scalar, or array input to an array. */\nfunction makeArray(source) {\n\treturn Array.isArray(source) ? source : isNullable(source) ? [] : [source];\n}\n//#endregion\n//#region lib/types/volatile.js\n/** Shared config references used by schema validators and plugin runtimes. */\nconst write = Symbol.for(\"cosmokit.volatile.write\");\nfunction snapshot(value, ancestors = /* @__PURE__ */ new Set()) {\n\tif (typeof value === \"function\") throw new TypeError(\"volatile config cannot contain functions\");\n\tif (value === null || typeof value !== \"object\") return value;\n\tif (ancestors.has(value)) throw new TypeError(\"volatile config cannot contain cycles\");\n\tancestors.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return Object.freeze(value.map((item) => snapshot(item, ancestors)));\n\t\tif (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) throw new TypeError(\"volatile config objects must be plain objects or arrays\");\n\t\treturn Object.freeze(Object.fromEntries(Object.entries(value).map(([key, item]) => [key, snapshot(item, ancestors)])));\n\t} finally {\n\t\tancestors.delete(value);\n\t}\n}\n/**\n* Create a detached reference containing an immutable copy of the supplied data.\n* @param value - validated config data; class instances and functions are unsupported.\n* @returns a reference whose value is updated only by its owning runtime.\n*/\nfunction createVolatile(value) {\n\tlet current = snapshot(value);\n\treturn Object.freeze({\n\t\tget: () => current,\n\t\t[write]: (value) => {\n\t\t\tcurrent = value;\n\t\t}\n\t});\n}\n/**\n* Identify references across ESM/CJS copies of the shared library.\n* @param value - a parsed config value.\n* @returns whether the value implements the shared reference protocol.\n*/\nfunction isVolatile(value) {\n\treturn typeof value === \"object\" && value !== null && write in value;\n}\n/**\n* Collect config references without descending into their snapshots or opaque objects.\n* @internal\n* @param value - parsed config; cyclic ordinary fields are visited once per path.\n* @returns references and their object-key paths, including an empty path for a root reference.\n*/\nfunction volatileEntries(value) {\n\tconst ancestors = /* @__PURE__ */ new Set();\n\tfunction visit(value, path) {\n\t\tif (isVolatile(value)) return [{\n\t\t\tpath,\n\t\t\tref: value\n\t\t}];\n\t\tif (!value || typeof value !== \"object\" || ancestors.has(value)) return [];\n\t\tif (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) return [];\n\t\tancestors.add(value);\n\t\ttry {\n\t\t\treturn Object.entries(value).flatMap(([key, child]) => visit(child, [...path, key]));\n\t\t} finally {\n\t\t\tancestors.delete(value);\n\t\t}\n\t}\n\treturn visit(value, []);\n}\n/**\n* Commit an already validated immutable snapshot from another reference.\n* @internal\n* @param target - the owning plugin's stable reference.\n* @param source - a newly parsed candidate reference.\n*/\nfunction updateVolatile(target, source) {\n\ttarget[write](source.get());\n}\n//#endregion\n//#region lib/types/types.js\n/** Test values using `instanceof` with a `toStringTag` fallback. */\nfunction is(type, value) {\n\tif (arguments.length === 1) return (value) => is(type, value);\n\treturn type in globalThis && value instanceof globalThis[type] || Object.prototype.toString.call(value).slice(8, -1) === type;\n}\nfunction isArrayBufferLike(value) {\n\treturn is(\"ArrayBuffer\", value) || is(\"SharedArrayBuffer\", value);\n}\nfunction isArrayBufferSource(value) {\n\treturn isArrayBufferLike(value) || ArrayBuffer.isView(value);\n}\n/** Binary source detection and base64/hex conversion helpers. */\nvar Binary;\n(function(Binary) {\n\tBinary.is = isArrayBufferLike;\n\tBinary.isSource = isArrayBufferSource;\n\tfunction fromSource(source) {\n\t\tif (ArrayBuffer.isView(source)) return source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);\n\t\telse return source;\n\t}\n\tBinary.fromSource = fromSource;\n\tfunction toBase64(source) {\n\t\tsource = fromSource(source);\n\t\tif (typeof Buffer !== \"undefined\") return Buffer.from(source).toString(\"base64\");\n\t\tlet binary = \"\";\n\t\tconst bytes = new Uint8Array(source);\n\t\tfor (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i]);\n\t\treturn btoa(binary);\n\t}\n\tBinary.toBase64 = toBase64;\n\tfunction fromBase64(source) {\n\t\tif (typeof Buffer !== \"undefined\") return fromSource(Buffer.from(source, \"base64\"));\n\t\treturn Uint8Array.from(atob(source), (c) => c.charCodeAt(0));\n\t}\n\tBinary.fromBase64 = fromBase64;\n\tfunction toHex(source) {\n\t\tsource = fromSource(source);\n\t\tif (typeof Buffer !== \"undefined\") return Buffer.from(source).toString(\"hex\");\n\t\treturn Array.from(new Uint8Array(source), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n\t}\n\tBinary.toHex = toHex;\n\tfunction fromHex(source) {\n\t\tif (typeof Buffer !== \"undefined\") return fromSource(Buffer.from(source, \"hex\"));\n\t\tconst hex = source.length % 2 === 0 ? source : source.slice(0, source.length - 1);\n\t\tconst buffer = [];\n\t\tfor (let i = 0; i < hex.length; i += 2) buffer.push(parseInt(`${hex[i]}${hex[i + 1]}`, 16));\n\t\treturn Uint8Array.from(buffer).buffer;\n\t}\n\tBinary.fromHex = fromHex;\n})(Binary || (Binary = {}));\n/** Decode a base64 string into binary data. */\nconst base64ToArrayBuffer = Binary.fromBase64;\n/** Encode binary data as base64. */\nconst arrayBufferToBase64 = Binary.toBase64;\n/** Decode a hex string into binary data. */\nconst hexToArrayBuffer = Binary.fromHex;\n/** Encode binary data as hex. */\nconst arrayBufferToHex = Binary.toHex;\n/** Deep-clone common JavaScript values while preserving prototypes and cycles. */\nfunction clone(source, refs = /* @__PURE__ */ new Map()) {\n\tif (!source || typeof source !== \"object\") return source;\n\tif (is(\"Date\", source)) return new Date(source.valueOf());\n\tif (is(\"RegExp\", source)) return new RegExp(source.source, source.flags);\n\tif (isArrayBufferLike(source)) return source.slice(0);\n\tif (ArrayBuffer.isView(source)) return source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);\n\tconst cached = refs.get(source);\n\tif (cached) return cached;\n\tif (Array.isArray(source)) {\n\t\tconst result = [];\n\t\trefs.set(source, result);\n\t\tsource.forEach((value, index) => {\n\t\t\tresult[index] = Reflect.apply(clone, null, [value, refs]);\n\t\t});\n\t\treturn result;\n\t}\n\tconst result = Object.create(Object.getPrototypeOf(source));\n\trefs.set(source, result);\n\tfor (const key of Reflect.ownKeys(source)) {\n\t\tconst descriptor = { ...Reflect.getOwnPropertyDescriptor(source, key) };\n\t\tif (\"value\" in descriptor) descriptor.value = Reflect.apply(clone, null, [descriptor.value, refs]);\n\t\tReflect.defineProperty(result, key, descriptor);\n\t}\n\treturn result;\n}\n/**\n* Compare values recursively, treating two volatile references as equal regardless of value.\n* Strict comparison distinguishes null/undefined, treats opaque objects by identity,\n* compares URLs by normalized href, treats array holes as undefined, and considers distinct cyclic structures unequal.\n* @param a - first value.\n* @param b - second value.\n* @param strict - whether to require strict data equality outside volatile references.\n* @returns whether the values compare equal.\n*/\nfunction deepEqual(a, b, strict) {\n\tconst ancestors = /* @__PURE__ */ new Set();\n\tfunction compare(a, b) {\n\t\tif (a === b) return true;\n\t\tif (isVolatile(a) || isVolatile(b)) return isVolatile(a) && isVolatile(b);\n\t\tif (!strict && isNullable(a) && isNullable(b)) return true;\n\t\tif (typeof a !== typeof b || typeof a !== \"object\" || !a || !b) return false;\n\t\tif (ancestors.has(a)) return false;\n\t\tfunction check(test, then) {\n\t\t\treturn test(a) ? test(b) ? then(a, b) : false : test(b) ? false : void 0;\n\t\t}\n\t\tancestors.add(a);\n\t\ttry {\n\t\t\treturn check(Array.isArray, (a, b) => {\n\t\t\t\tif (a.length !== b.length) return false;\n\t\t\t\tfor (let index = 0; index < a.length; index++) if (!compare(a[index], b[index])) return false;\n\t\t\t\treturn true;\n\t\t\t}) ?? check(is(\"Date\"), (a, b) => a.valueOf() === b.valueOf()) ?? check(is(\"URL\"), (a, b) => a.href === b.href) ?? check(is(\"RegExp\"), (a, b) => a.source === b.source && a.flags === b.flags) ?? check(isArrayBufferLike, (a, b) => {\n\t\t\t\tif (a.byteLength !== b.byteLength) return false;\n\t\t\t\tconst viewA = new Uint8Array(a);\n\t\t\t\tconst viewB = new Uint8Array(b);\n\t\t\t\tfor (let i = 0; i < viewA.length; i++) if (viewA[i] !== viewB[i]) return false;\n\t\t\t\treturn true;\n\t\t\t}) ?? ((!strict || [a, b].every((value) => Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null)) && Object.keys({\n\t\t\t\t...a,\n\t\t\t\t...b\n\t\t\t}).every((key) => compare(a[key], b[key])));\n\t\t} finally {\n\t\t\tancestors.delete(a);\n\t\t}\n\t}\n\treturn compare(a, b);\n}\n//#endregion\n//#region lib/types/string.js\n/** Uppercase the first character of a string. */\nfunction capitalize(source) {\n\treturn source.charAt(0).toUpperCase() + source.slice(1);\n}\n/** Lowercase the first character of a string. */\nfunction uncapitalize(source) {\n\treturn source.charAt(0).toLowerCase() + source.slice(1);\n}\n/** Convert dash or underscore delimited text to camelCase. */\nfunction camelCase(source) {\n\treturn source.replace(/[_-][a-z]/g, (str) => str.slice(1).toUpperCase());\n}\nfunction tokenize(source, delimiters, delimiter) {\n\tconst output = [];\n\tlet state = 0;\n\tfor (let i = 0; i < source.length; i++) {\n\t\tconst code = source.charCodeAt(i);\n\t\tif (code >= 65 && code <= 90) {\n\t\t\tif (state === 1) {\n\t\t\t\tconst next = source.charCodeAt(i + 1);\n\t\t\t\tif (next >= 97 && next <= 122) output.push(delimiter);\n\t\t\t\toutput.push(code + 32);\n\t\t\t} else {\n\t\t\t\tif (state !== 0) output.push(delimiter);\n\t\t\t\toutput.push(code + 32);\n\t\t\t}\n\t\t\tstate = 1;\n\t\t} else if (code >= 97 && code <= 122) {\n\t\t\toutput.push(code);\n\t\t\tstate = 2;\n\t\t} else if (delimiters.includes(code)) {\n\t\t\tif (state !== 0) output.push(delimiter);\n\t\t\tstate = 0;\n\t\t} else output.push(code);\n\t}\n\treturn String.fromCharCode(...output);\n}\n/** Convert text to dash-delimited parameter case. */\nfunction paramCase(source) {\n\treturn tokenize(source, [45, 95], 45);\n}\n/** Convert text to underscore-delimited snake case. */\nfunction snakeCase(source) {\n\treturn tokenize(source, [45, 95], 95);\n}\n/** Runtime alias for `camelCase`. */\nconst camelize = camelCase;\n/** Runtime alias for `paramCase`. */\nconst hyphenate = paramCase;\n/** Format a property key as a JavaScript member access suffix. */\nfunction formatProperty(key) {\n\tif (typeof key !== \"string\") return `[${key.toString()}]`;\n\treturn /^[a-z_$][\\w$]*$/i.test(key) ? `.${key}` : `[${JSON.stringify(key)}]`;\n}\n/** Remove one trailing slash from a path string. */\nfunction trimSlash(source) {\n\treturn source.replace(/\\/$/, \"\");\n}\n/** Ensure a path starts with `/` and has no trailing slash. */\nfunction sanitize(source) {\n\tif (!source.startsWith(\"/\")) source = \"/\" + source;\n\treturn trimSlash(source);\n}\n//#endregion\n//#region lib/types/time.js\n/** Time constants plus parsing and formatting helpers. */\nvar Time;\n(function(Time) {\n\tTime.millisecond = 1;\n\tTime.second = 1e3;\n\tTime.minute = Time.second * 60;\n\tTime.hour = Time.minute * 60;\n\tTime.day = Time.hour * 24;\n\tTime.week = Time.day * 7;\n\tlet timezoneOffset = (/* @__PURE__ */ new Date()).getTimezoneOffset();\n\tfunction setTimezoneOffset(offset) {\n\t\ttimezoneOffset = offset;\n\t}\n\tTime.setTimezoneOffset = setTimezoneOffset;\n\tfunction getTimezoneOffset() {\n\t\treturn timezoneOffset;\n\t}\n\tTime.getTimezoneOffset = getTimezoneOffset;\n\tfunction getDateNumber(date = /* @__PURE__ */ new Date(), offset) {\n\t\tif (typeof date === \"number\") date = new Date(date);\n\t\tif (offset === void 0) offset = timezoneOffset;\n\t\treturn Math.floor((date.valueOf() / Time.minute - offset) / 1440);\n\t}\n\tTime.getDateNumber = getDateNumber;\n\tfunction fromDateNumber(value, offset) {\n\t\tconst date = new Date(value * Time.day);\n\t\tif (offset === void 0) offset = timezoneOffset;\n\t\treturn new Date(+date + offset * Time.minute);\n\t}\n\tTime.fromDateNumber = fromDateNumber;\n\tconst numeric = /\\d+(?:\\.\\d+)?/.source;\n\tconst timeRegExp = new RegExp(`^${[\n\t\t\"w(?:eek(?:s)?)?\",\n\t\t\"d(?:ay(?:s)?)?\",\n\t\t\"h(?:our(?:s)?)?\",\n\t\t\"m(?:in(?:ute)?(?:s)?)?\",\n\t\t\"s(?:ec(?:ond)?(?:s)?)?\"\n\t].map((unit) => `(${numeric}${unit})?`).join(\"\")}$`);\n\tfunction parseTime(source) {\n\t\tconst capture = timeRegExp.exec(source);\n\t\tif (!capture) return 0;\n\t\treturn (parseFloat(capture[1]) * Time.week || 0) + (parseFloat(capture[2]) * Time.day || 0) + (parseFloat(capture[3]) * Time.hour || 0) + (parseFloat(capture[4]) * Time.minute || 0) + (parseFloat(capture[5]) * Time.second || 0);\n\t}\n\tTime.parseTime = parseTime;\n\tfunction parseDate(date) {\n\t\tconst parsed = parseTime(date);\n\t\tif (parsed) date = Date.now() + parsed;\n\t\telse if (/^\\d{1,2}(:\\d{1,2}){1,2}$/.test(date)) date = `${(/* @__PURE__ */ new Date()).toLocaleDateString()}-${date}`;\n\t\telse if (/^\\d{1,2}-\\d{1,2}-\\d{1,2}(:\\d{1,2}){1,2}$/.test(date)) date = `${(/* @__PURE__ */ new Date()).getFullYear()}-${date}`;\n\t\treturn date ? new Date(date) : /* @__PURE__ */ new Date();\n\t}\n\tTime.parseDate = parseDate;\n\tfunction format(ms) {\n\t\tconst abs = Math.abs(ms);\n\t\tif (abs >= Time.day - Time.hour / 2) return Math.round(ms / Time.day) + \"d\";\n\t\telse if (abs >= Time.hour - Time.minute / 2) return Math.round(ms / Time.hour) + \"h\";\n\t\telse if (abs >= Time.minute - Time.second / 2) return Math.round(ms / Time.minute) + \"m\";\n\t\telse if (abs >= Time.second) return Math.round(ms / Time.second) + \"s\";\n\t\treturn ms + \"ms\";\n\t}\n\tTime.format = format;\n\tfunction toDigits(source, length = 2) {\n\t\treturn source.toString().padStart(length, \"0\");\n\t}\n\tTime.toDigits = toDigits;\n\tfunction template(template, time = /* @__PURE__ */ new Date()) {\n\t\treturn template.replace(\"yyyy\", time.getFullYear().toString()).replace(\"yy\", time.getFullYear().toString().slice(2)).replace(\"MM\", toDigits(time.getMonth() + 1)).replace(\"dd\", toDigits(time.getDate())).replace(\"hh\", toDigits(time.getHours())).replace(\"mm\", toDigits(time.getMinutes())).replace(\"ss\", toDigits(time.getSeconds())).replace(\"SSS\", toDigits(time.getMilliseconds(), 3));\n\t}\n\tTime.template = template;\n})(Time || (Time = {}));\n//#endregion\nexport { Binary, Time, arrayBufferToBase64, arrayBufferToHex, base64ToArrayBuffer, camelCase, camelize, capitalize, clone, contain, createVolatile, deduplicate, deepEqual, defineProperty, difference, filterKeys, formatProperty, hexToArrayBuffer, hyphenate, intersection, is, isNonNullable, isNullable, isPlainObject, isVolatile, makeArray, mapValues, mapValues as valueMap, noop, omit, paramCase, pick, remove, sanitize, snakeCase, trimSlash, uncapitalize, union, updateVolatile, volatileEntries };\n","import { Binary, clone, createVolatile, deepEqual, filterKeys, isNullable, isPlainObject, isVolatile, pick, valueMap } from \"@deepseek-ai/cosmokit\";\n//#region lib/types/index.js\nconst kSchema = Symbol.for(\"schemastery\");\nconst kValidationError = Symbol.for(\"ValidationError\");\nglobalThis.__schemastery_index__ ??= 0;\nglobalThis.__schemastery_refs__ = void 0;\nvar ValidationError = class extends TypeError {\n\toptions;\n\tname = \"ValidationError\";\n\tconstructor(message, options) {\n\t\tlet prefix = \"$\";\n\t\tfor (const segment of options.path || []) if (typeof segment === \"string\") prefix += \".\" + segment;\n\t\telse if (typeof segment === \"number\") prefix += \"[\" + segment + \"]\";\n\t\telse if (typeof segment === \"symbol\") prefix += `[Symbol(${segment.toString()})]`;\n\t\tif (prefix.startsWith(\".\")) prefix = prefix.slice(1);\n\t\tsuper((prefix === \"$\" ? \"\" : `${prefix} `) + message);\n\t\tthis.options = options;\n\t}\n\tstatic is(error) {\n\t\treturn !!error?.[kValidationError];\n\t}\n};\nObject.defineProperty(ValidationError.prototype, kValidationError, { value: true });\nconst Schema = function(options) {\n\tconst schema = function(data, options = {}) {\n\t\treturn Schema.resolve(data, schema, options)[0];\n\t};\n\tif (options.refs) {\n\t\tconst refs = valueMap(options.refs, (options) => new Schema(options));\n\t\tconst getRef = (uid) => refs[uid];\n\t\tfor (const key in refs) {\n\t\t\tconst options = refs[key];\n\t\t\toptions.sKey = getRef(options.sKey);\n\t\t\toptions.inner = getRef(options.inner);\n\t\t\toptions.list = options.list && options.list.map(getRef);\n\t\t\toptions.dict = options.dict && valueMap(options.dict, getRef);\n\t\t}\n\t\treturn refs[options.uid];\n\t}\n\tObject.assign(schema, options);\n\tif (typeof schema.callback === \"string\") try {\n\t\tschema.callback = new Function(\"return \" + schema.callback)();\n\t} catch {}\n\tObject.defineProperty(schema, \"uid\", { value: globalThis.__schemastery_index__++ });\n\tObject.setPrototypeOf(schema, Schema.prototype);\n\tschema.meta ||= {};\n\tschema.toString = schema.toString.bind(schema);\n\treturn schema;\n};\nSchema.prototype = Object.create(Function.prototype);\nSchema.prototype[kSchema] = true;\nObject.defineProperty(Schema.prototype, \"~standard\", { get() {\n\treturn {\n\t\tversion: 1,\n\t\tvendor: \"schemastery\",\n\t\tvalidate: (value) => {\n\t\t\ttry {\n\t\t\t\treturn { value: Schema.resolve(value, this, {})[0] };\n\t\t\t} catch (error) {\n\t\t\t\tif (ValidationError.is(error)) return { issues: [{\n\t\t\t\t\tmessage: error.message,\n\t\t\t\t\tpath: error.options.path\n\t\t\t\t}] };\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t};\n} });\nSchema.ValidationError = ValidationError;\nSchema.prototype.toJSON = function toJSON() {\n\tif (globalThis.__schemastery_refs__) {\n\t\tglobalThis.__schemastery_refs__[this.uid] ??= JSON.parse(JSON.stringify({ ...this }));\n\t\treturn this.uid;\n\t}\n\tglobalThis.__schemastery_refs__ = { [this.uid]: { ...this } };\n\tglobalThis.__schemastery_refs__[this.uid] = JSON.parse(JSON.stringify({ ...this }));\n\tconst result = {\n\t\tuid: this.uid,\n\t\trefs: globalThis.__schemastery_refs__\n\t};\n\tglobalThis.__schemastery_refs__ = void 0;\n\treturn result;\n};\nSchema.prototype.set = function set(key, value) {\n\tthis.dict[key] = value;\n\treturn this;\n};\nSchema.prototype.push = function push(value) {\n\tthis.list.push(value);\n\treturn this;\n};\nfunction mergeDesc(original, messages) {\n\tconst result = typeof original === \"string\" ? { \"\": original } : { ...original };\n\tfor (const locale in messages) {\n\t\tconst value = messages[locale];\n\t\tif (value?.$description || value?.$desc) result[locale] = value.$description || value.$desc;\n\t\telse if (typeof value === \"string\") result[locale] = value;\n\t}\n\treturn result;\n}\nfunction getInner(value) {\n\treturn value?.$value ?? value?.$inner;\n}\nfunction extractKeys(data) {\n\treturn filterKeys(data ?? {}, (key) => !key.startsWith(\"$\"));\n}\nSchema.prototype.i18n = function i18n(messages) {\n\tconst schema = Schema(this);\n\tconst desc = mergeDesc(schema.meta.description, messages);\n\tif (Object.keys(desc).length) schema.meta.description = desc;\n\tif (schema.dict) schema.dict = valueMap(schema.dict, (inner, key) => {\n\t\treturn inner.i18n(valueMap(messages, (data) => getInner(data)?.[key] ?? data?.[key]));\n\t});\n\tif (schema.list) schema.list = schema.list.map((inner, index) => {\n\t\treturn inner.i18n(valueMap(messages, (data = {}) => {\n\t\t\tif (Array.isArray(getInner(data))) return getInner(data)[index];\n\t\t\tif (Array.isArray(data)) return data[index];\n\t\t\treturn extractKeys(data);\n\t\t}));\n\t});\n\tif (schema.inner) schema.inner = schema.inner.i18n(valueMap(messages, (data) => {\n\t\tif (getInner(data)) return getInner(data);\n\t\treturn extractKeys(data);\n\t}));\n\tif (schema.sKey) schema.sKey = schema.sKey.i18n(valueMap(messages, (data) => data?.$key));\n\treturn schema;\n};\nSchema.prototype.extra = function extra(key, value) {\n\tconst schema = Schema(this);\n\tschema.meta = {\n\t\t...schema.meta,\n\t\t[key]: value\n\t};\n\treturn schema;\n};\nfor (const key of [\n\t\"required\",\n\t\"disabled\",\n\t\"collapse\",\n\t\"hidden\",\n\t\"loose\"\n]) Object.assign(Schema.prototype, { [key](value = true) {\n\tconst schema = Schema(this);\n\tschema.meta = {\n\t\t...schema.meta,\n\t\t[key]: value\n\t};\n\treturn schema;\n} });\nSchema.prototype.deprecated = function deprecated() {\n\tconst schema = Schema(this);\n\tschema.meta.badges ||= [];\n\tschema.meta.badges.push({\n\t\ttext: \"deprecated\",\n\t\ttype: \"danger\"\n\t});\n\treturn schema;\n};\nSchema.prototype.experimental = function experimental() {\n\tconst schema = Schema(this);\n\tschema.meta.badges ||= [];\n\tschema.meta.badges.push({\n\t\ttext: \"experimental\",\n\t\ttype: \"warning\"\n\t});\n\treturn schema;\n};\nSchema.prototype.pattern = function pattern(regexp) {\n\tconst schema = Schema(this);\n\tconst pattern = pick(regexp, [\"source\", \"flags\"]);\n\tschema.meta = {\n\t\t...schema.meta,\n\t\tpattern\n\t};\n\treturn schema;\n};\nSchema.prototype.simplify = function simplify(value) {\n\tif (isVolatile(value)) value = value.get();\n\tif (deepEqual(value, this.meta.default, this.type === \"dict\")) return null;\n\tif (isNullable(value)) return value;\n\tif (this.type === \"object\" || this.type === \"dict\") {\n\t\tconst result = {};\n\t\tfor (const key in value) {\n\t\t\tconst item = (this.type === \"object\" ? this.dict[key] : this.inner)?.simplify(value[key]);\n\t\t\tif (this.type === \"dict\" || !isNullable(item)) result[key] = item;\n\t\t}\n\t\tif (deepEqual(result, this.meta.default, this.type === \"dict\")) return null;\n\t\treturn result;\n\t} else if (this.type === \"array\" || this.type === \"tuple\") {\n\t\tconst result = [];\n\t\tvalue.forEach((value, index) => {\n\t\t\tconst schema = this.type === \"array\" ? this.inner : this.list[index];\n\t\t\tconst item = schema ? schema.simplify(value) : value;\n\t\t\tresult.push(item);\n\t\t});\n\t\treturn result;\n\t} else if (this.type === \"intersect\") {\n\t\tconst result = {};\n\t\tfor (const item of this.list) Object.assign(result, item.simplify(value));\n\t\treturn result;\n\t} else if (this.type === \"union\") for (const schema of this.list) try {\n\t\tSchema.resolve(value, schema, {});\n\t\treturn schema.simplify(value);\n\t} catch {}\n\treturn value;\n};\nSchema.prototype.toString = function toString(inline) {\n\treturn formatters[this.type]?.(this, inline) ?? `Schema<${this.type}>`;\n};\nSchema.prototype.role = function role(role, extra) {\n\tconst schema = Schema(this);\n\tschema.meta = {\n\t\t...schema.meta,\n\t\trole,\n\t\textra\n\t};\n\treturn schema;\n};\nfor (const key of [\n\t\"default\",\n\t\"link\",\n\t\"comment\",\n\t\"description\",\n\t\"max\",\n\t\"min\",\n\t\"step\"\n]) Object.assign(Schema.prototype, { [key](value) {\n\tconst schema = Schema(this);\n\tschema.meta = {\n\t\t...schema.meta,\n\t\t[key]: value\n\t};\n\treturn schema;\n} });\nSchema.prototype.volatile = function volatile() {\n\tif (this.meta.volatile) throw new TypeError(\"volatile schema is already wrapped\");\n\treturn this.extra(\"volatile\", true);\n};\nconst resolvers = {};\nconst checkedVolatile = Symbol(\"checked-volatile-schema\");\nfunction validateVolatileSchema(schema, path = [], blocked = false, seen = /* @__PURE__ */ new Map()) {\n\tconst states = seen.get(schema) ?? /* @__PURE__ */ new Set();\n\tif (states.has(blocked)) return;\n\tstates.add(blocked);\n\tseen.set(schema, states);\n\tif (schema.meta?.volatile && blocked) throw new ValidationError(\"volatile fields require a fixed object path without an enclosing volatile field\", { path });\n\tconst nested = blocked || !!schema.meta?.volatile;\n\tif (schema.dict) for (const [key, child] of Object.entries(schema.dict)) validateVolatileSchema(child, [...path, key], nested, seen);\n\tif (schema.sKey) validateVolatileSchema(schema.sKey, [...path, \"<key>\"], true, seen);\n\tif (schema.inner && (schema.type !== \"lazy\" || schema.inner[kSchema])) validateVolatileSchema(schema.inner, [...path, \"*\"], true, seen);\n\tif (schema.list) for (let index = 0; index < schema.list.length; index++) validateVolatileSchema(schema.list[index], [...path, String(index)], true, seen);\n}\nSchema.extend = function extend(type, resolve) {\n\tresolvers[type] = resolve;\n};\nSchema.resolve = function resolve(data, schema, options = {}, strict = false) {\n\tif (!schema) return [data];\n\tif (!options[checkedVolatile]) {\n\t\tvalidateVolatileSchema(schema, options.path);\n\t\toptions = {\n\t\t\t...options,\n\t\t\t[checkedVolatile]: true\n\t\t};\n\t}\n\tif (schema.meta?.volatile) {\n\t\tconst inner = Schema(schema);\n\t\tinner.meta = {\n\t\t\t...schema.meta,\n\t\t\tvolatile: false\n\t\t};\n\t\tconst [value, adapted] = Schema.resolve(data, inner, options, strict);\n\t\ttry {\n\t\t\treturn [createVolatile(value), adapted];\n\t\t} catch (error) {\n\t\t\tthrow new ValidationError(error instanceof Error ? error.message : String(error), options);\n\t\t}\n\t}\n\tif (options.ignore?.(data, schema)) return [data];\n\tif (isNullable(data) && schema.type !== \"lazy\") {\n\t\tif (schema.meta.required) throw new ValidationError(`missing required value`, options);\n\t\tlet current = schema;\n\t\tlet fallback = schema.meta.default;\n\t\twhile (current?.type === \"intersect\" && isNullable(fallback)) {\n\t\t\tcurrent = current.list[0];\n\t\t\tfallback = current?.meta.default;\n\t\t}\n\t\tif (isNullable(fallback)) return [data];\n\t\tdata = clone(fallback);\n\t}\n\tconst callback = resolvers[schema.type];\n\tif (!callback) throw new ValidationError(`unsupported type \"${schema.type}\"`, options);\n\ttry {\n\t\treturn callback(data, schema, options, strict);\n\t} catch (error) {\n\t\tif (!schema.meta.loose) throw error;\n\t\treturn [schema.meta.default];\n\t}\n};\nSchema.from = function from(source) {\n\tif (isNullable(source)) return Schema.any();\n\telse if ([\n\t\t\"string\",\n\t\t\"number\",\n\t\t\"boolean\"\n\t].includes(typeof source)) return Schema.const(source).required();\n\telse if (source[kSchema]) return source;\n\telse if (typeof source === \"function\") switch (source) {\n\t\tcase String: return Schema.string().required();\n\t\tcase Number: return Schema.number().required();\n\t\tcase Boolean: return Schema.boolean().required();\n\t\tcase Function: return Schema.function().required();\n\t\tdefault: return Schema.is(source).required();\n\t}\n\telse throw new TypeError(`cannot infer schema from ${source}`);\n};\nSchema.lazy = function lazy(builder) {\n\tconst toJSON = () => {\n\t\tif (!schema.inner[kSchema]) {\n\t\t\tschema.inner = schema.builder();\n\t\t\tschema.inner.meta = {\n\t\t\t\t...schema.meta,\n\t\t\t\t...schema.inner.meta\n\t\t\t};\n\t\t}\n\t\treturn schema.inner.toJSON();\n\t};\n\tconst schema = new Schema({\n\t\ttype: \"lazy\",\n\t\tbuilder,\n\t\tinner: { toJSON }\n\t});\n\treturn schema;\n};\nSchema.natural = function natural() {\n\treturn Schema.number().step(1).min(0);\n};\nSchema.percent = function percent() {\n\treturn Schema.number().step(.01).min(0).max(1).role(\"slider\");\n};\nSchema.date = function date() {\n\treturn Schema.union([Schema.is(Date), Schema.transform(Schema.string().role(\"datetime\"), (value, options) => {\n\t\tconst date = new Date(value);\n\t\tif (isNaN(+date)) throw new ValidationError(`invalid date \"${value}\"`, options);\n\t\treturn date;\n\t}, true)]);\n};\nSchema.regExp = function regExp(flag = \"\") {\n\treturn Schema.union([Schema.is(RegExp), Schema.transform(Schema.string().role(\"regexp\", { flag }), (value, options) => {\n\t\ttry {\n\t\t\treturn new RegExp(value, flag);\n\t\t} catch (e) {\n\t\t\tthrow new ValidationError(e.message, options);\n\t\t}\n\t}, true)]);\n};\nSchema.arrayBuffer = function arrayBuffer(encoding) {\n\treturn Schema.union([\n\t\tSchema.is(ArrayBuffer),\n\t\tSchema.is(SharedArrayBuffer),\n\t\tSchema.transform(Schema.any(), (value, options) => {\n\t\t\tif (Binary.isSource(value)) return Binary.fromSource(value);\n\t\t\tthrow new ValidationError(`expected ArrayBufferSource but got ${value}`, options);\n\t\t}, true),\n\t\t...encoding ? [Schema.transform(Schema.string(), (value, options) => {\n\t\t\ttry {\n\t\t\t\treturn encoding === \"base64\" ? Binary.fromBase64(value) : Binary.fromHex(value);\n\t\t\t} catch (e) {\n\t\t\t\tthrow new ValidationError(e.message, options);\n\t\t\t}\n\t\t}, true)] : []\n\t]);\n};\nSchema.extend(\"lazy\", (data, schema, options, strict) => {\n\tif (!schema.inner[kSchema]) {\n\t\tschema.inner = schema.builder();\n\t\tschema.inner.meta = {\n\t\t\t...schema.meta,\n\t\t\t...schema.inner.meta\n\t\t};\n\t\tvalidateVolatileSchema(schema.inner, options.path, true);\n\t}\n\treturn Schema.resolve(data, schema.inner, options, strict);\n});\nSchema.extend(\"any\", (data) => {\n\treturn [data];\n});\nSchema.extend(\"never\", (data, _, options) => {\n\tthrow new ValidationError(`expected nullable but got ${data}`, options);\n});\nSchema.extend(\"const\", (data, { value }, options) => {\n\tif (deepEqual(data, value)) return [value];\n\tthrow new ValidationError(`expected ${value} but got ${data}`, options);\n});\nfunction checkWithinRange(data, meta, description, options, skipMin = false) {\n\tconst { max = Infinity, min = -Infinity } = meta;\n\tif (data > max) throw new ValidationError(`expected ${description} <= ${max} but got ${data}`, options);\n\tif (data < min && !skipMin) throw new ValidationError(`expected ${description} >= ${min} but got ${data}`, options);\n}\nSchema.extend(\"string\", (data, { meta }, options) => {\n\tif (typeof data !== \"string\") throw new ValidationError(`expected string but got ${data}`, options);\n\tif (meta.pattern) {\n\t\tconst regexp = new RegExp(meta.pattern.source, meta.pattern.flags);\n\t\tif (!regexp.test(data)) throw new ValidationError(`expect string to match regexp ${regexp}`, options);\n\t}\n\tcheckWithinRange(data.length, meta, \"string length\", options);\n\treturn [data];\n});\nfunction decimalShift(data, digits) {\n\tconst str = data.toString();\n\tif (str.includes(\"e\")) return data * Math.pow(10, digits);\n\tconst index = str.indexOf(\".\");\n\tif (index === -1) return data * Math.pow(10, digits);\n\tconst frac = str.slice(index + 1);\n\tconst integer = str.slice(0, index);\n\tif (frac.length <= digits) return +(integer + frac.padEnd(digits, \"0\"));\n\treturn +(integer + frac.slice(0, digits) + \".\" + frac.slice(digits));\n}\nfunction isMultipleOf(data, min, step) {\n\tstep = Math.abs(step);\n\tif (!/^\\d+\\.\\d+$/.test(step.toString())) return (data - min) % step === 0;\n\tconst index = step.toString().indexOf(\".\");\n\tconst digits = step.toString().slice(index + 1).length;\n\treturn Math.abs(decimalShift(data, digits) - decimalShift(min, digits)) % decimalShift(step, digits) === 0;\n}\nSchema.extend(\"number\", (data, { meta }, options) => {\n\tif (typeof data !== \"number\") throw new ValidationError(`expected number but got ${data}`, options);\n\tcheckWithinRange(data, meta, \"number\", options);\n\tconst { step } = meta;\n\tif (step && !isMultipleOf(data, meta.min ?? 0, step)) throw new ValidationError(`expected number multiple of ${step} but got ${data}`, options);\n\treturn [data];\n});\nSchema.extend(\"boolean\", (data, _, options) => {\n\tif (typeof data === \"boolean\") return [data];\n\tthrow new ValidationError(`expected boolean but got ${data}`, options);\n});\nSchema.extend(\"bitset\", (data, { bits, meta }, options) => {\n\tlet value = 0, keys = [];\n\tif (typeof data === \"number\") {\n\t\tvalue = data;\n\t\tfor (const key in bits) if (data & bits[key]) keys.push(key);\n\t} else if (Array.isArray(data)) {\n\t\tkeys = data;\n\t\tfor (const key of keys) {\n\t\t\tif (typeof key !== \"string\") throw new ValidationError(`expected string but got ${key}`, options);\n\t\t\tif (key in bits) value |= bits[key];\n\t\t}\n\t} else throw new ValidationError(`expected number or array but got ${data}`, options);\n\tif (value === meta.default) return [value];\n\treturn [value, keys];\n});\nSchema.extend(\"function\", (data, _, options) => {\n\tif (typeof data === \"function\") return [data];\n\tthrow new ValidationError(`expected function but got ${data}`, options);\n});\nSchema.extend(\"is\", (data, { constructor }, options) => {\n\tif (typeof constructor === \"function\") {\n\t\tif (data instanceof constructor) return [data];\n\t\tthrow new ValidationError(`expected ${constructor.name} but got ${data}`, options);\n\t} else {\n\t\tif (isNullable(data)) throw new ValidationError(`expected ${constructor} but got ${data}`, options);\n\t\tlet prototype = Object.getPrototypeOf(data);\n\t\twhile (prototype) {\n\t\t\tif (prototype.constructor?.name === constructor) return [data];\n\t\t\tprototype = Object.getPrototypeOf(prototype);\n\t\t}\n\t\tthrow new ValidationError(`expected ${constructor} but got ${data}`, options);\n\t}\n});\nfunction property(data, key, schema, options) {\n\ttry {\n\t\tconst [value, adapted] = Schema.resolve(data[key], schema, {\n\t\t\t...options,\n\t\t\tpath: [...options.path || [], key]\n\t\t});\n\t\tif (adapted !== void 0) data[key] = adapted;\n\t\treturn value;\n\t} catch (e) {\n\t\tif (!options?.autofix) throw e;\n\t\tdelete data[key];\n\t\treturn schema.meta.volatile ? createVolatile(schema.meta.default) : schema.meta.default;\n\t}\n}\nSchema.extend(\"array\", (data, { inner, meta }, options) => {\n\tif (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options);\n\tcheckWithinRange(data.length, meta, \"array length\", options, !isNullable(inner.meta.default));\n\treturn [data.map((_, index) => property(data, index, inner, options))];\n});\nSchema.extend(\"dict\", (data, { inner, sKey }, options, strict) => {\n\tif (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options);\n\tconst result = {};\n\tfor (const key in data) {\n\t\tlet rKey;\n\t\ttry {\n\t\t\trKey = Schema.resolve(key, sKey, options)[0];\n\t\t} catch (error) {\n\t\t\tif (strict) continue;\n\t\t\tthrow error;\n\t\t}\n\t\tresult[rKey] = property(data, key, inner, options);\n\t\tdata[rKey] = data[key];\n\t\tif (key !== rKey) delete data[key];\n\t}\n\treturn [result];\n});\nSchema.extend(\"tuple\", (data, { list }, options, strict) => {\n\tif (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options);\n\tconst result = list.map((inner, index) => property(data, index, inner, options));\n\tif (strict) return [result];\n\tresult.push(...data.slice(list.length));\n\treturn [result];\n});\nfunction merge(result, data) {\n\tfor (const key in data) {\n\t\tif (key in result) continue;\n\t\tresult[key] = data[key];\n\t}\n}\nSchema.extend(\"object\", (data, { dict }, options, strict) => {\n\tif (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options);\n\tconst result = {};\n\tfor (const key in dict) {\n\t\tconst value = property(data, key, dict[key], options);\n\t\tif (!isNullable(value) || key in data) result[key] = value;\n\t}\n\tif (!strict) merge(result, data);\n\treturn [result];\n});\nSchema.extend(\"union\", (data, { list, toString }, options, strict) => {\n\tconst messages = [];\n\tfor (const inner of list) try {\n\t\treturn Schema.resolve(data, inner, options, strict);\n\t} catch (error) {\n\t\tmessages.push(error);\n\t}\n\tthrow new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);\n});\nSchema.extend(\"intersect\", (data, { list, toString }, options, strict) => {\n\tif (!list.length) return [data];\n\tlet result;\n\tfor (const inner of list) {\n\t\tconst value = Schema.resolve(data, inner, options, true)[0];\n\t\tif (isNullable(value)) continue;\n\t\tif (isNullable(result)) result = value;\n\t\telse if (typeof result !== typeof value) throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);\n\t\telse if (typeof value === \"object\") merge(result ??= {}, value);\n\t\telse if (result !== value) throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);\n\t}\n\tif (!strict && isPlainObject(data)) merge(result, data);\n\treturn [result];\n});\nSchema.extend(\"transform\", (data, { inner, callback, preserve }, options) => {\n\tconst [result, adapted = data] = Schema.resolve(data, inner, options, true);\n\tif (preserve) return [callback(result)];\n\telse return [callback(result), callback(adapted)];\n});\nconst formatters = {};\nfunction defineMethod(name, keys, format) {\n\tformatters[name] = format;\n\tObject.assign(Schema, { [name](...args) {\n\t\tconst schema = new Schema({ type: name });\n\t\tkeys.forEach((key, index) => {\n\t\t\tswitch (key) {\n\t\t\t\tcase \"sKey\":\n\t\t\t\t\tschema.sKey = args[index] ?? Schema.string();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"inner\":\n\t\t\t\t\tschema.inner = Schema.from(args[index]);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"list\":\n\t\t\t\t\tschema.list = args[index].map(Schema.from);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"dict\":\n\t\t\t\t\tschema.dict = valueMap(args[index], Schema.from);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"bits\":\n\t\t\t\t\tschema.bits = {};\n\t\t\t\t\tfor (const key in args[index]) {\n\t\t\t\t\t\tif (typeof args[index][key] !== \"number\") continue;\n\t\t\t\t\t\tschema.bits[key] = args[index][key];\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"callback\": {\n\t\t\t\t\tconst callback = schema.callback = args[index];\n\t\t\t\t\tcallback[\"toJSON\"] ||= () => callback.toString();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"constructor\": {\n\t\t\t\t\tconst constructor = schema.constructor = args[index];\n\t\t\t\t\tif (typeof constructor === \"function\") constructor[\"toJSON\"] ||= () => constructor[\"name\"];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: schema[key] = args[index];\n\t\t\t}\n\t\t});\n\t\tif (name === \"object\" || name === \"dict\") schema.meta.default = {};\n\t\telse if (name === \"array\" || name === \"tuple\") schema.meta.default = [];\n\t\telse if (name === \"bitset\") schema.meta.default = 0;\n\t\treturn schema;\n\t} });\n}\ndefineMethod(\"is\", [\"constructor\"], ({ constructor }) => {\n\tif (typeof constructor === \"function\") return constructor.name;\n\telse return constructor;\n});\ndefineMethod(\"any\", [], () => \"any\");\ndefineMethod(\"never\", [], () => \"never\");\ndefineMethod(\"const\", [\"value\"], ({ value }) => typeof value === \"string\" ? JSON.stringify(value) : value);\ndefineMethod(\"string\", [], () => \"string\");\ndefineMethod(\"number\", [], () => \"number\");\ndefineMethod(\"boolean\", [], () => \"boolean\");\ndefineMethod(\"bitset\", [\"bits\"], () => \"bitset\");\ndefineMethod(\"function\", [], () => \"function\");\ndefineMethod(\"array\", [\"inner\"], ({ inner }) => `${inner.toString(true)}[]`);\ndefineMethod(\"dict\", [\"inner\", \"sKey\"], ({ inner, sKey }) => `{ [key: ${sKey.toString()}]: ${inner.toString()} }`);\ndefineMethod(\"tuple\", [\"list\"], ({ list }) => `[${list.map((inner) => inner.toString()).join(\", \")}]`);\ndefineMethod(\"object\", [\"dict\"], ({ dict }) => {\n\tif (Object.keys(dict).length === 0) return \"{}\";\n\treturn `{ ${Object.entries(dict).map(([key, inner]) => {\n\t\treturn `${key}${inner.meta.required ? \"\" : \"?\"}: ${inner.toString()}`;\n\t}).join(\", \")} }`;\n});\ndefineMethod(\"union\", [\"list\"], ({ list }, inline) => {\n\tconst result = list.map(({ toString: format }) => format()).join(\" | \");\n\treturn inline ? `(${result})` : result;\n});\ndefineMethod(\"intersect\", [\"list\"], ({ list }) => {\n\treturn `${list.map((inner) => inner.toString(true)).join(\" & \")}`;\n});\ndefineMethod(\"transform\", [\n\t\"inner\",\n\t\"callback\",\n\t\"preserve\"\n], ({ inner }, isInner) => inner.toString(isInner));\n//#endregion\nexport { Schema as default };\n","// Card-editable rhythm config (v1.7.0): the heartbeat card edits five fields\n// over RPC and they persist in the plugin's OWN user layer, so the editor\n// behaves identically on every host generation (0.1.1 scope / 0.1.5\n// installSection / 0.1.7 profile forms all become irrelevant for these\n// values) and saves apply live without any plugin reload.\n// Startup precedence: factory policy < user policy < ui.json < Config fields.\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { PathGuard } from '../core/path-guard.js';\nimport { atomicWriteFileSync } from '../core/atomic-fs.js';\n\nexport const USER_UI_FILE = 'ui.json';\n\nexport interface UiConfig {\n intervalMin?: number;\n maxDailySend?: number;\n timeInjectMin?: number;\n statusbar?: boolean;\n idleMode?: boolean;\n /** Token-saver (v1.7.0): pause beats while the user is away / locked. */\n tokenSaver?: boolean;\n}\n\nconst RANGES = {\n intervalMin: { min: 1, max: 1440 },\n maxDailySend: { min: 1, max: 50 },\n timeInjectMin: { min: 0, max: 1440 },\n} as const;\n\nfunction sanitize(raw: unknown): UiConfig {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return {};\n const r = raw as Record<string, unknown>;\n const out: UiConfig = {};\n for (const key of ['intervalMin', 'maxDailySend', 'timeInjectMin'] as const) {\n const v = r[key];\n if (typeof v === 'number' && Number.isFinite(v) && v >= RANGES[key].min && v <= RANGES[key].max) {\n out[key] = Math.floor(v);\n }\n }\n if (typeof r.statusbar === 'boolean') out.statusbar = r.statusbar;\n if (typeof r.idleMode === 'boolean') out.idleMode = r.idleMode;\n if (typeof r.tokenSaver === 'boolean') out.tokenSaver = r.tokenSaver;\n return out;\n}\n\nexport function uiConfigPath(settingsDir: string): string {\n return path.join(settingsDir, USER_UI_FILE);\n}\n\n/** Missing user layer is normal; a corrupt layer fails open to defaults. */\nexport function loadUiConfig(guard: PathGuard, settingsDir: string): UiConfig {\n try {\n const raw: unknown = JSON.parse(fs.readFileSync(guard.assert(uiConfigPath(settingsDir)), 'utf8'));\n return sanitize(raw);\n } catch {\n return {};\n }\n}\n\n/** Merge `patch` over the stored layer, sanitize, and persist. */\nexport function saveUiConfig(guard: PathGuard, settingsDir: string, patch: UiConfig): UiConfig {\n const merged = sanitize({ ...loadUiConfig(guard, settingsDir), ...patch });\n const file = guard.assert(uiConfigPath(settingsDir));\n fs.mkdirSync(path.dirname(file), { recursive: true });\n atomicWriteFileSync(file, JSON.stringify(merged, null, 2) + '\\n');\n return merged;\n}\n","// M6: settings-card RPC (decision 1 = Plan B; transport reworked in v1.2.1, C21).\r\n//\r\n// Host registers an exact Fetch route under /api via ctx.inject(['connection'], ...)\r\n// once the connection service mounts; the web card calls\r\n// connection.rpc.call('/api', 'heartbeat', { endpoint, ...payload }).\r\n// (The original custom channel '/heartbeat' via rpc.handle() is unusable on\r\n// DSH 0.1.5+: cordis pins the service's this.ctx to the provider context, so\r\n// handle()'s internal owner.webServer.register always fails strict resolution.)\r\n// Bindings authority = data/settings/bindings.json (decision 2); the card is\r\n// just another client of the same host logic the CLI uses.\r\n// Every endpoint runs inside the workspace guard; results are {ok,value} or\r\n// {ok:false,error:{code,message,details}}.\r\n\r\nimport { spawn } from 'node:child_process';\r\nimport fs from 'node:fs';\r\nimport os from 'node:os';\r\nimport path from 'node:path';\r\nimport type { OrchestratorDeps } from './core/orchestrator.js';\r\nimport { getLastBeat, homeSessionId, resetHomeSession } from './core/orchestrator.js';\r\nimport { appendAuditLine } from './core/audit-log.js';\r\nimport type { UiConfig } from './config/ui-config.js';\r\nimport type { PathGuard } from './core/path-guard.js';\r\nimport type { WorkspacePaths } from './core/paths.js';\r\nimport { inQuietHours, readSentState } from './gate/gate.js';\r\nimport {\r\n activeSeeds,\r\n archivedSeeds,\r\n archiveSeedById,\r\n deleteSeed,\r\n loadPool,\r\n restoreSeed,\r\n seedsFilePath,\r\n} from './seeds/pool.js';\r\nimport { loadProfile, profileFilePath } from './profile/store.js';\r\nimport { buildDigest } from './profile/digest.js';\r\nimport { ledgerFilePath } from './ledger/ledger.js';\r\nimport { listWeeklyReports, readWeeklyReport } from './weekly/report.js';\r\nimport { addBinding, loadBindings, removeBinding } from './core/bindings.js';\r\nimport { addInterest, readEffective, removeInterest, setWanderWindows } from './browse/interests-edit.js';\r\nimport { writeText } from './vault/vault.js';\r\nimport { readStatus } from './statusbar/store.js';\r\nimport { loadTimeInjectState } from './statusbar/time-inject.js';\r\nimport type { Policy } from './config/schema.js';\r\n\r\n/** Exact Fetch route under /api (C21: custom rpc.handle channels are unusable\r\n * under 0.1.5's strict cordis service resolution — see installHeartbeatRpc). */\r\nexport const RPC_ROUTE_PATH = '/api/heartbeat';\r\n\r\n/**\r\n * H-41 (2026-10-07): the endpoints that change or expose state on disk. They\r\n * are only reachable through the host's `/api` gate — this plugin holds no\r\n * credential of its own — so when that gate cannot be found they are refused\r\n * rather than served unauthenticated (see installHeartbeatRpc).\r\n */\r\nconst DESTRUCTIVE_ENDPOINTS = new Set([\r\n 'seeds.delete',\r\n 'migrate.import',\r\n 'bindings.remove',\r\n 'config.set',\r\n 'profile.export',\r\n 'interests.remove',\r\n]);\r\n\r\ninterface RpcDeps {\r\n ctx: OrchestratorDeps['ctx'] & {\r\n inject(services: string[], callback: (scoped: unknown) => void): void;\r\n };\r\n paths: WorkspacePaths;\r\n guard: PathGuard;\r\n policy: Policy;\r\n /** Card-edited rhythm values (v1.7.0): live view getter + persist-and-apply setter. */\r\n ui: {\r\n get(): {\r\n intervalMin: number;\r\n maxDailySend: number;\r\n timeInjectMin: number;\r\n statusbar: boolean;\r\n idleMode: boolean;\r\n tokenSaver: boolean;\r\n psyEnabled: boolean;\r\n };\r\n set(patch: UiConfig & { psyEnabled?: boolean }): void;\r\n };\r\n}\r\n\r\ntype RpcResult = { ok: true; value: unknown } | { ok: false; error: { code: string; message: string; details: Record<string, never> } };\r\n\r\nconst ok = (value: unknown): RpcResult => ({ ok: true, value });\r\nconst err = (code: string, message: string): RpcResult => ({ ok: false, error: { code, message, details: {} } });\r\n\r\nlet cachedVersion: string | null = null;\r\n/** Plugin version for the card's status block (read once from package.json). */\r\nfunction pluginVersion(paths: WorkspacePaths): string {\r\n if (cachedVersion) return cachedVersion;\r\n try {\r\n const pkg = JSON.parse(fs.readFileSync(path.join(paths.packageRoot, 'package.json'), 'utf8')) as { version?: string };\r\n cachedVersion = typeof pkg.version === 'string' ? pkg.version : 'unknown';\r\n } catch {\r\n cachedVersion = 'unknown';\r\n }\r\n return cachedVersion;\r\n}\r\n\r\n/** 素材池生命周期的审计出口(v1.9.0):卡片上的归档/恢复/删除也留下痕迹。 */\r\nfunction seedAuditSink(paths: WorkspacePaths): (entry: Record<string, unknown>) => void {\r\n return (entry) => {\r\n try {\r\n appendAuditLine(paths.logsDir + '/heartbeat.jsonl', entry);\r\n } catch { /* audit must never break the RPC call */ }\r\n };\r\n}\r\n\r\n/** 兴趣/时段卡片编辑的审计留痕(成功才记;失败原因走 RPC err 回给卡片)。 */\r\nfunction auditInterests(paths: WorkspacePaths, action: string, r: { ok: boolean }, detail: unknown): void {\r\n try {\r\n appendAuditLine(paths.logsDir + '/heartbeat.jsonl', {\r\n event: `interests_${r.ok ? 'edit' : 'edit_failed'}`,\r\n action,\r\n detail: typeof detail === 'string' ? detail.slice(0, 80) : null,\r\n });\r\n } catch { /* audit must never break the RPC call */ }\r\n}\r\n\r\n/** Session titles from the host's projection cache. Titles are host data — the\r\n * client card merges them (client.js `nameOf`: title || id prefix).\r\n *\r\n * DSH 0.1.2 writes ONE RECORD PER SESSION under\r\n * `~/.dsh/storages/session_projcache/sessions/<sessionId>.json`\r\n * (`record.rows.title.val`). The single-file `session_projcache.json` we used\r\n * before is the older aggregate layout and goes stale: a session created after\r\n * the upgrade is simply absent from it, so `title` came back null and the card\r\n * printed the raw session id. Read the per-record layout FIRST, keep the\r\n * aggregate only as a legacy fallback. */\r\nfunction loadSessionTitles(): Record<string, string> {\r\n const titles: Record<string, string> = {};\r\n const take = (id: string, value: unknown): void => {\r\n const t = value as { rows?: { title?: { val?: unknown } }; title?: { val?: unknown } } | undefined;\r\n const row = t?.rows?.title ?? t?.title;\r\n if (row && typeof row.val === 'string' && row.val && !titles[id]) titles[id] = row.val;\r\n };\r\n // 1) per-record layout (current).\r\n try {\r\n const dir = path.join(os.homedir(), '.dsh', 'storages', 'session_projcache', 'sessions');\r\n for (const file of fs.readdirSync(dir)) {\r\n if (!file.endsWith('.json')) continue;\r\n const id = file.slice(0, -'.json'.length);\r\n if (!id.startsWith('session-')) continue;\r\n try {\r\n const record = JSON.parse(fs.readFileSync(path.join(dir, file), 'utf8')) as { record?: unknown };\r\n take(id, record.record);\r\n } catch { /* skip a record we cannot read */ }\r\n }\r\n } catch { /* no per-record dir on older hosts */ }\r\n // 2) legacy aggregate fallback.\r\n try {\r\n const raw = JSON.parse(fs.readFileSync(path.join(os.homedir(), '.dsh', 'storages', 'session_projcache.json'), 'utf8')) as unknown;\r\n const walk = (node: unknown): void => {\r\n if (!node || typeof node !== 'object') return;\r\n for (const [key, value] of Object.entries(node as Record<string, unknown>)) {\r\n if (key.startsWith('session-') && value && typeof value === 'object') {\r\n // Title lives at <session>.rows.title.val (host title service); the\r\n // val may be null while the title is still being generated.\r\n take(key, value);\r\n }\r\n walk(value);\r\n }\r\n };\r\n walk(raw);\r\n return titles;\r\n } catch {\r\n return titles;\r\n }\r\n}\r\n\r\n/** Host-side session registry (`~/.dsh/storages/workspace.json`) → the set of\r\n * session ids the USER actually sees in the sidebar.\r\n *\r\n * A persisted session is user-visible iff it belongs to some workspace's\r\n * `sessionIds` and is not in `archivedSessionIds`. Two exclusions fall out of\r\n * this for the bind picker (2026-09-30 user request):\r\n * - **archived** sessions (explicit `archivedSessionIds`, prefix formats are\r\n * mixed on disk — some entries carry `session-`, some don't — so match\r\n * both forms);\r\n * - **subagent child sessions**, which never join any workspace's\r\n * `sessionIds` (observed: they only ever land in the archive list).\r\n *\r\n * Fail-open: a missing/corrupt registry returns `registryFound: false` and\r\n * the caller shows everything — an unreadable registry must not blank the\r\n * picker. The heartbeat home is always shown regardless (caller-side). */\r\nexport function loadVisibleSessionIds(registryFile?: string): { visible: Set<string>; registryFound: boolean } {\r\n try {\r\n const file = registryFile ?? path.join(os.homedir(), '.dsh', 'storages', 'workspace.json');\r\n const j = JSON.parse(fs.readFileSync(file, 'utf8')) as {\r\n global?: { archivedSessionIds?: unknown };\r\n tables?: { workspaces?: Record<string, { sessionIds?: unknown }> };\r\n };\r\n const archived = new Set(\r\n (Array.isArray(j.global?.archivedSessionIds) ? (j.global!.archivedSessionIds as unknown[]) : [])\r\n .map((s) => String(s)),\r\n );\r\n const isArchived = (id: string): boolean =>\r\n archived.has(id) || archived.has(id.replace(/^session-/, ''));\r\n const visible = new Set<string>();\r\n for (const ws of Object.values(j.tables?.workspaces ?? {})) {\r\n const ids = Array.isArray(ws?.sessionIds) ? (ws.sessionIds as unknown[]) : [];\r\n for (const raw of ids) {\r\n const id = String(raw);\r\n if (!isArchived(id)) visible.add(id);\r\n }\r\n }\r\n return { visible, registryFound: true };\r\n } catch {\r\n return { visible: new Set(), registryFound: false };\r\n }\r\n}\r\n\r\n/** One RPC verb: payload in, envelope out. `guard` / `paths` / `policy` / `deps`\r\n * come from the closure built by {@link buildEndpoints}. */\r\ntype Endpoint = (p: Record<string, unknown>) => RpcResult | Promise<RpcResult>;\r\n\r\n/**\r\n * H-36: the endpoint table. This used to be a single `switch` at the bottom of\r\n * the route handler — 22 verbs and ~250 lines, with the guest list (which\r\n * endpoints exist) tangled up with the machinery (envelope validation, the\r\n * catch-all error wrapper). Adding a verb is now one entry here; the wrapper\r\n * stays in one place.\r\n */\r\nfunction buildEndpoints(deps: Omit<RpcDeps, 'ctx'>, isLive: (sessionId: string) => boolean): Record<string, Endpoint> {\r\n const { guard, paths, policy } = deps;\r\n return {\r\n async status() {\r\n const now = Date.now();\r\n const sent = readSentState(guard, paths, now);\r\n const beat = getLastBeat();\r\n // M7 statusbar block (§17.8): store + throttle-state + live flags.\r\n let lastTimeInjectAt: number | null = null;\r\n try {\r\n const state = loadTimeInjectState(guard, paths.dataDir);\r\n for (const v of Object.values(state)) {\r\n if (typeof v === 'number' && v > (lastTimeInjectAt ?? 0)) lastTimeInjectAt = v;\r\n }\r\n } catch { /* missing state file = never injected */ }\r\n let flags = { statusbarEnabled: true, timeInjectMin: 25, idleMode: false };\r\n try {\r\n const { getRuntime } = await import('./core/runtime.js');\r\n const f = getRuntime().flags;\r\n flags = { statusbarEnabled: f.statusbarEnabled(), timeInjectMin: f.timeInjectMin(), idleMode: f.idleMode() };\r\n } catch { /* pre-init: report defaults */ }\r\n return ok({\r\n now: new Date(now).toISOString(),\r\n version: pluginVersion(paths),\r\n intervalMin: policy.heartbeat.intervalMin,\r\n idleMode: policy.heartbeat.idleMode,\r\n cap: { used: sent.items.length, max: policy.gate.maxDailySend },\r\n quiet: inQuietHours(policy, now),\r\n lastBeat: beat,\r\n homeSessionId: homeSessionId(guard, paths),\r\n bindings: loadBindings(guard, paths.settingsDir).bindings.length,\r\n statusbar: {\r\n enabled: flags.statusbarEnabled,\r\n timeInjectMin: flags.timeInjectMin,\r\n lastStatus: readStatus(guard, paths),\r\n lastTimeInjectAt: lastTimeInjectAt === null ? null : new Date(lastTimeInjectAt).toISOString(),\r\n },\r\n });\r\n },\r\n\r\n 'sessions.list'() {\r\n const root = path.join(os.homedir(), '.dsh', 'sessions');\r\n const bindings = loadBindings(guard, paths.settingsDir).bindings;\r\n const home = homeSessionId(guard, paths);\r\n const titles = loadSessionTitles();\r\n // Bind picker visibility: hide archived and subagent sessions\r\n // (2026-09-30 user request). Fail-open when the registry is\r\n // unreadable; the home is always listed.\r\n const { visible, registryFound } = loadVisibleSessionIds();\r\n const out: Record<string, unknown>[] = [];\r\n if (fs.existsSync(root)) {\r\n for (const slug of fs.readdirSync(root)) {\r\n for (const id of fs.readdirSync(path.join(root, slug))) {\r\n if (registryFound && id !== home && !visible.has(id)) continue;\r\n const binding = bindings.find((b) => b.sessionId === id);\r\n out.push({\r\n id,\r\n title: titles[id] ?? null,\r\n cwdSlug: slug,\r\n live: isLive(id),\r\n home: id === home,\r\n deliver: binding?.deliver ?? false,\r\n observe: binding?.observe ?? false,\r\n });\r\n }\r\n }\r\n }\r\n return ok({ sessions: out });\r\n },\r\n\r\n 'bindings.get': () => ok(loadBindings(guard, paths.settingsDir)),\r\n\r\n 'bindings.add'(p) {\r\n const id = String(p.sessionId ?? '');\r\n if (!id.startsWith('session-')) return err('bad-request', 'sessionId must look like session-...');\r\n const home = homeSessionId(guard, paths);\r\n if (id === home) return err('bad-request', '该会话是心跳正身,无需绑定(决策轮次固定发生在正身)');\r\n // Callers send BOTH flags explicitly (the card's per-flag toggles), so\r\n // this stays a full-state write: deliver defaults on, observe off.\r\n const b = addBinding(guard, paths.settingsDir, id, {\r\n deliver: p.deliver !== false,\r\n observe: p.observe === true,\r\n });\r\n return ok(b);\r\n },\r\n\r\n 'bindings.remove'(p) {\r\n const id = String(p.sessionId ?? '');\r\n const removed = removeBinding(guard, paths.settingsDir, id);\r\n // H-09/H-45: one shared release path — gate.json, the home_reset audit\r\n // line and the orchestrator's cached agent — instead of an inline delete\r\n // that silently left the in-memory home behind.\r\n const homeReset = resetHomeSession(guard, paths, id);\r\n return ok({ removed, homeReset });\r\n },\r\n\r\n 'seeds.list'() {\r\n const db = loadPool(guard, seedsFilePath(paths.dataDir));\r\n return ok({\r\n active: activeSeeds(db),\r\n archived: archivedSeeds(db),\r\n cap: policy.seeds.maxActive,\r\n });\r\n },\r\n\r\n 'seeds.archive'(p) {\r\n const s = archiveSeedById(guard, seedsFilePath(paths.dataDir), String(p.id ?? ''), 'completed', Date.now(), seedAuditSink(paths));\r\n return s ? ok(s) : err('not-found', 'active seed not found');\r\n },\r\n\r\n 'seeds.restore'(p) {\r\n const r = restoreSeed(guard, seedsFilePath(paths.dataDir), policy, String(p.id ?? ''), Date.now(), seedAuditSink(paths));\r\n return r.ok ? ok(r.seed) : err('restore-failed', r.reason);\r\n },\r\n\r\n 'seeds.delete'(p) {\r\n return ok({ deleted: deleteSeed(guard, seedsFilePath(paths.dataDir), String(p.id ?? ''), seedAuditSink(paths)) });\r\n },\r\n\r\n // ── 兴趣范围 / 浏览时段(v1.4.0;首编继承出厂,见 interests-edit.ts)──\r\n 'interests.list': () => ok(readEffective(paths)),\r\n\r\n 'interests.add'(p) {\r\n const r = addInterest(guard, paths, String(p.text ?? ''));\r\n auditInterests(paths, 'add', r, p.text);\r\n return r.ok ? ok(r.doc) : err('bad-request', r.reason ?? 'add failed');\r\n },\r\n\r\n 'interests.remove'(p) {\r\n const r = removeInterest(guard, paths, String(p.text ?? ''));\r\n auditInterests(paths, 'remove', r, p.text);\r\n return r.ok ? ok(r.doc) : err('not-found', r.reason ?? 'remove failed');\r\n },\r\n\r\n 'interests.setWindows'(p) {\r\n const r = setWanderWindows(guard, paths, p.windows);\r\n auditInterests(paths, 'set-windows', r, JSON.stringify(p.windows ?? null));\r\n return r.ok ? ok(r.doc) : err('bad-request', r.reason ?? 'setWindows failed');\r\n },\r\n\r\n 'config.get': () => ok(deps.ui.get()),\r\n\r\n 'config.set'(p) {\r\n const patch = p as UiConfig;\r\n if (!patch || typeof patch !== 'object' || Array.isArray(patch)) {\r\n return err('bad-request', 'config.set needs a patch object');\r\n }\r\n const keys = Object.keys(patch).filter((k) =>\r\n ['intervalMin', 'maxDailySend', 'timeInjectMin', 'statusbar', 'idleMode', 'tokenSaver', 'psyEnabled'].includes(k),\r\n );\r\n if (keys.length === 0) return err('bad-request', 'config.set has no recognized field');\r\n try {\r\n deps.ui.set(patch);\r\n } catch (e) {\r\n return err('bad-request', String(e).slice(0, 120));\r\n }\r\n appendAuditLine(guard.assert(paths.logsDir + '/heartbeat.jsonl'), { event: 'ui_config_set', keys });\r\n return ok(deps.ui.get());\r\n },\r\n\r\n 'profile.digest'() {\r\n const d = buildDigest(guard, paths, policy, {});\r\n return ok({\r\n tact: d.tact,\r\n topic: d.topic,\r\n wander: d.wander,\r\n withinBudget: d.withinBudget,\r\n // v2.0 (item 6): the card shows the budget and what the caps dropped.\r\n totalChars: d.totalChars,\r\n budgetChars: d.budgetChars,\r\n omitted: d.omitted,\r\n });\r\n },\r\n\r\n 'profile.partitions'() {\r\n // v2.0 (item 6): the card shows ONE partition at a time, entry by entry.\r\n // The digest view was a wall of text and never showed what the profile\r\n // actually holds. Read-only, same data profile.export walks.\r\n const doc = loadProfile(guard, profileFilePath(paths.dataDir));\r\n const partitions: Record<string, { total: number; valid: number; entries: Record<string, unknown>[] }> = {};\r\n for (const part of ['interest', 'projects', 'comm', 'psy'] as const) {\r\n const all = doc.partitions[part]?.entries ?? [];\r\n const valid = all.filter((e) => e.validTo === null);\r\n partitions[part] = {\r\n total: all.length,\r\n valid: valid.length,\r\n entries: valid\r\n .slice()\r\n .sort((a, b) => b.confidence - a.confidence || (a.updatedAt < b.updatedAt ? 1 : -1))\r\n .map((e) => ({\r\n id: e.id,\r\n topic: e.topic,\r\n subTopic: e.subTopic,\r\n content: e.content,\r\n confidence: e.confidence,\r\n temporal: e.temporal,\r\n updatedAt: e.updatedAt,\r\n lowActivity: e.lowActivity === true,\r\n })),\r\n };\r\n }\r\n return ok({ partitions });\r\n },\r\n\r\n 'profile.export'() {\r\n const doc = loadProfile(guard, profileFilePath(paths.dataDir));\r\n const lines = [`# 画像导出 ${new Date().toISOString()}`, ''];\r\n for (const part of ['interest', 'projects', 'comm', 'psy'] as const) {\r\n lines.push(`## ${part}`);\r\n for (const e of doc.partitions[part]!.entries) {\r\n if (e.validTo !== null) continue;\r\n lines.push(`- [${e.topic}/${e.subTopic}] ${e.content} (conf ${e.confidence.toFixed(2)}, ${e.temporal})`);\r\n }\r\n }\r\n const out = path.join(paths.exportsDir, `profile-export-${Date.now()}.md`);\r\n writeText(guard, out, lines.join('\\n') + '\\n');\r\n return ok({ path: out });\r\n },\r\n\r\n 'ledger.open'() {\r\n const f = ledgerFilePath(paths.dataDir);\r\n if (!fs.existsSync(guard.assert(f))) fs.writeFileSync(f, '# 账本\\n', 'utf8');\r\n spawn('cmd', ['/c', 'start', '', f], { detached: true, stdio: 'ignore' }).unref();\r\n return ok({ path: f });\r\n },\r\n\r\n 'weekly.list': () => ok({ reports: listWeeklyReports(guard, paths.dataDir, policy.weekly.keepReports) }),\r\n\r\n 'weekly.get'(p) {\r\n const file = String(p.file ?? '');\r\n const rep = readWeeklyReport(guard, paths.dataDir, file);\r\n if (!rep) return err('bad-request', `no such report: ${file}`);\r\n return ok(rep);\r\n },\r\n\r\n async 'migrate.export'(p) {\r\n // Card-side export (v1.8.0): same container as the CLI. The\r\n // passphrase lives only in this call — never audited, never logged.\r\n const passphrase = String(p.passphrase ?? '');\r\n if (!passphrase) return err('bad-request', '需要设置口令');\r\n const { collectMigrationEntries, encryptContainer } = await import('./vault/migrate.js');\r\n const { entries } = collectMigrationEntries(guard, paths);\r\n if (entries.length === 0) return err('bad-request', '没有可打包的记忆文件(data/ 是空的)');\r\n const out = path.join(paths.exportsDir, `heartbeat-memory-${new Date().toISOString().slice(0, 10)}.hbmig`);\r\n writeText(guard, out, encryptContainer(entries, passphrase));\r\n appendAuditLine(guard.assert(paths.logsDir + '/heartbeat.jsonl'), { event: 'migrate_export', files: entries.length });\r\n return ok({ path: out, count: entries.length });\r\n },\r\n\r\n async 'migrate.import'(p) {\r\n const passphrase = String(p.passphrase ?? '');\r\n const file = String(p.file ?? '');\r\n if (!passphrase || !file) return err('bad-request', '需要容器路径与口令');\r\n const { decryptContainer, applyMigrationEntries } = await import('./vault/migrate.js');\r\n let text: string;\r\n try {\r\n // Read-only from a user-chosen path (likely OUTSIDE data/); the\r\n // path guard still gates every file we WRITE back.\r\n text = fs.readFileSync(file, 'utf8');\r\n } catch {\r\n return err('bad-request', `读不到迁移包:${file}`);\r\n }\r\n let container: ReturnType<typeof decryptContainer>;\r\n try {\r\n container = decryptContainer(text, passphrase);\r\n } catch (e) {\r\n return err('bad-request', String(e instanceof Error ? e.message : e));\r\n }\r\n const result = applyMigrationEntries(guard, paths, container.files);\r\n appendAuditLine(guard.assert(paths.logsDir + '/heartbeat.jsonl'), {\r\n event: 'migrate_import', restored: result.restored.length, backedUp: result.backedUp.length, skipped: result.skipped.length,\r\n rolledBack: result.rolledBack?.length ?? 0, error: result.error ?? null,\r\n });\r\n return ok(result);\r\n },\r\n };\r\n}\r\n\r\nexport function installHeartbeatRpc(\r\n ctx: OrchestratorDeps['ctx'] & { inject(services: string[], callback: (scoped: unknown) => void): void },\r\n deps: Omit<RpcDeps, 'ctx'>,\r\n): void {\r\n // ── 0.1.5 适配(C21)─────────────────────────────────────────────────\r\n // 自定义通道 rpc.handle('/heartbeat') 在 0.1.5 的 cordis 严格服务解析下不可\r\n // 用:Service 把 this.ctx 固定在 client-connection 自己的上下文(其模块\r\n // inject 只有 ['credentials']),handle() 内部 owner.webServer.register 是在\r\n // 别人的 fiber 上读 webServer → `cannot get property \"webServer\" without\r\n // inject`,调用方怎么声明都救不了(现场取证 2026-09-12:合并 inject 三件套\r\n // + effect 包裹仍是这个错)。改走 connection.fetch.register():在 /api 下注册\r\n // 精确路由,只写 connection 内部路由表、不碰任何其他服务;0.1.2 与 0.1.5 的\r\n // /api 共享处理器都先查精确路由再落 interceptor,两代宿主通用。浏览器认证\r\n // 由 /api 前缀的 requestRejection 统一把关。客户端相应改为\r\n // rpc.call('/api', 'heartbeat', { endpoint, ...args })。\r\n ctx.inject(['connection'], (scoped: unknown) => {\r\n const remoteCtx = scoped as {\r\n connection: {\r\n fetch: { register(route: {\r\n path: string;\r\n methods: string[];\r\n requestBody?: string;\r\n fetch(request: Request): Promise<Response>;\r\n }): unknown };\r\n };\r\n agents: OrchestratorDeps['ctx']['agents'];\r\n effect(fn: () => unknown, label?: string): () => void;\r\n };\r\n\r\n const isLive = (sessionId: string): boolean => {\r\n try {\r\n return !!remoteCtx.agents.get(sessionId);\r\n } catch {\r\n return false;\r\n }\r\n };\r\n\r\n const endpoints = buildEndpoints(deps, isLive);\r\n\r\n // ── H-41 (2026-10-07): explicit dependency on the host's /api gate ────\r\n // This route is mounted under the host's `/api` prefix, and that prefix's\r\n // check is the ONLY authentication it has — the plugin keeps no credential\r\n // of its own. The host implements it as `connection.admit(req)`, which\r\n // returns `requestRejection(req)`'s verdict (Host/Origin fence + the\r\n // browser-auth secret; the `/api` prefix route calls it before dispatching,\r\n // so this exact path can never be reached without it). If a future host\r\n // drops or renames that check, the destructive endpoints above would be\r\n // reachable by anything that can POST to loopback — so fail closed on them\r\n // instead of guessing, and say so in the audit log once at registration.\r\n const gate = remoteCtx.connection as unknown as { admit?: unknown; requestRejection?: unknown };\r\n const hostGuarded = typeof gate.admit === 'function' || typeof gate.requestRejection === 'function';\r\n if (!hostGuarded) {\r\n try {\r\n appendAuditLine(deps.guard.assert(deps.paths.logsDir + '/heartbeat.jsonl'), {\r\n event: 'rpc_host_gate_missing',\r\n detail: 'connection.admit/requestRejection absent; destructive endpoints disabled',\r\n destructive: [...DESTRUCTIVE_ENDPOINTS],\r\n });\r\n } catch { /* 审计失败不影响注册 */ }\r\n }\r\n\r\n const handler = async (endpoint: unknown, payload: unknown): Promise<RpcResult> => {\r\n const p = (payload ?? {}) as Record<string, unknown>;\r\n const fn = typeof endpoint === 'string' ? endpoints[endpoint] : undefined;\r\n if (!fn) return err('bad-request', `unknown endpoint ${JSON.stringify(endpoint)}`);\r\n if (!hostGuarded && DESTRUCTIVE_ENDPOINTS.has(endpoint as string)) {\r\n return err('forbidden', `host gate unavailable; ${endpoint} is refused (H-41)`);\r\n }\r\n try {\r\n return await fn(p);\r\n } catch (e) {\r\n return err('internal', String(e).slice(0, 200));\r\n }\r\n };\r\n\r\n // RPC 信封与 /api 通道的 client-request/server-response 同构(客户端仍是\r\n // connection.rpc.call),端点名改走 payload.endpoint 字段。\r\n remoteCtx.effect(\r\n () => remoteCtx.connection.fetch.register({\r\n path: RPC_ROUTE_PATH,\r\n methods: ['POST'],\r\n requestBody: 'buffered',\r\n fetch: async (request: Request): Promise<Response> => {\r\n let envelope: { type?: unknown; rpcId?: unknown; payload?: unknown };\r\n try {\r\n envelope = await request.json() as typeof envelope;\r\n } catch {\r\n return new Response('body is not JSON', { status: 400 });\r\n }\r\n const rpcId = envelope?.rpcId;\r\n if (envelope?.type !== 'client-request' || typeof rpcId !== 'string' || typeof envelope.payload !== 'object' || envelope.payload === null) {\r\n return new Response('invalid envelope', { status: 400 });\r\n }\r\n const p = envelope.payload as Record<string, unknown>;\r\n const endpoint = typeof p.endpoint === 'string' ? p.endpoint : '(missing endpoint)';\r\n const result = await handler(endpoint, p);\r\n return Response.json({ type: 'server-response', rpcId, result });\r\n },\r\n }),\r\n 'heartbeat: rpc route',\r\n );\r\n ctx.logger.info('heartbeat: rpc route ready (%s)', RPC_ROUTE_PATH);\r\n try {\r\n appendAuditLine(deps.guard.assert(deps.paths.logsDir + '/heartbeat.jsonl'), { event: 'rpc_registered', route: RPC_ROUTE_PATH });\r\n } catch { /* 审计失败不影响注册 */ }\r\n });\r\n}\r\n","// Interest-scope editing for the settings card (v1.4.0).\n//\n// The wander adjudicator picks its focus from `interests.json` (browse.ts\n// `loadInterests`): the factory copy in config/ is read-only, and a user layer\n// at data/settings/interests.json REPLACES it wholesale. That replace-not-merge\n// semantics is why every successful edit funnels through `ensureUserLayer`: the\n// FIRST edit copies the factory file (interests + _schedule, verbatim) into the\n// user layer before applying the change, so the card becomes the single\n// management entry point without silently dropping the other factory rows.\n// Reads and FAILED validations stay read-only (`readEffective`) — merely\n// opening the card must not take the user layer over.\n//\n// All writes stay inside the guard; unknown top-level keys (e.g. _comment) are\n// preserved on save so hand-written annotations survive card edits.\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { PathGuard } from '../core/path-guard.js';\nimport type { WorkspacePaths } from '../core/paths.js';\n\n/** Mirrors browse.ts's InterestsConfig; kept local so this module owns the\n * editing shape (windows gain mandatory ids on save). */\nexport interface InterestsDoc {\n interests: string[];\n _schedule?: {\n daily_sessions?: number;\n focus_per_session?: number;\n max_seeds_per_focus?: number;\n focus_cooldown_days?: number;\n min_interval_hours?: number;\n windows?: { id?: string; start: string; end: string }[];\n };\n [key: string]: unknown;\n}\n\nexport interface WanderWindow {\n id: string;\n start: string;\n end: string;\n}\n\nexport const MAX_INTERESTS = 32;\nexport const MAX_INTEREST_LEN = 60;\nconst MAX_WINDOWS = 6;\nconst HHMM = /^([01]\\d|2[0-3]):([0-5]\\d)$/;\n\nexport function userInterestsPath(paths: WorkspacePaths): string {\n return path.join(paths.settingsDir, 'interests.json');\n}\n\nexport function factoryInterestsPath(paths: WorkspacePaths): string {\n return path.join(paths.configDir, 'interests.json');\n}\n\nfunction readDoc(file: string): InterestsDoc | null {\n try {\n const raw = JSON.parse(fs.readFileSync(file, 'utf8')) as Partial<InterestsDoc>;\n if (!Array.isArray(raw.interests)) return null;\n return { ...raw, interests: raw.interests.map(String) };\n } catch {\n return null;\n }\n}\n\n/** What the wander adjudicator sees right now — WITHOUT creating the user\n * layer. Fallback chain: user layer -> factory -> empty. */\nexport function readEffective(paths: WorkspacePaths): InterestsDoc {\n return (\n readDoc(userInterestsPath(paths)) ??\n readDoc(factoryInterestsPath(paths)) ?? { interests: [] }\n );\n}\n\n/**\n * The user layer, created on first EDIT by copying the factory file verbatim\n * (decision: 首编继承出厂). Call only from mutation paths that are about to\n * succeed; the doc it returns equals `readEffective` at call time.\n */\nexport function ensureUserLayer(guard: PathGuard, paths: WorkspacePaths): InterestsDoc {\n const existing = readDoc(userInterestsPath(paths));\n if (existing) return existing;\n const doc: InterestsDoc = readDoc(factoryInterestsPath(paths)) ?? { interests: [] };\n saveDoc(guard, userInterestsPath(paths), doc);\n return doc;\n}\n\nfunction saveDoc(guard: PathGuard, file: string, doc: InterestsDoc): void {\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.writeFileSync(guard.assert(file), JSON.stringify(doc, null, 2), 'utf8');\n}\n\nexport interface InterestsResult {\n ok: boolean;\n reason?: string;\n doc: InterestsDoc;\n}\n\n/** Normalize: trim + collapse internal whitespace. Case-insensitive dedupe. */\nexport function normalizeInterest(text: string): string {\n return text.trim().replace(/\\s+/g, ' ');\n}\n\nexport function addInterest(\n guard: PathGuard,\n paths: WorkspacePaths,\n rawText: string,\n): InterestsResult {\n const text = normalizeInterest(rawText);\n if (!text) return { ok: false, reason: 'empty', doc: readEffective(paths) };\n if (text.length > MAX_INTEREST_LEN) {\n return { ok: false, reason: `too-long (max ${MAX_INTEREST_LEN})`, doc: readEffective(paths) };\n }\n const current = readEffective(paths);\n if (current.interests.some((t) => normalizeInterest(t).toLowerCase() === text.toLowerCase())) {\n return { ok: false, reason: 'duplicate', doc: current };\n }\n if (current.interests.length >= MAX_INTERESTS) {\n return { ok: false, reason: `cap (${MAX_INTERESTS})`, doc: current };\n }\n const doc = ensureUserLayer(guard, paths);\n doc.interests.push(text);\n saveDoc(guard, userInterestsPath(paths), doc);\n return { ok: true, doc };\n}\n\nexport function removeInterest(\n guard: PathGuard,\n paths: WorkspacePaths,\n rawText: string,\n): InterestsResult {\n const current = readEffective(paths);\n const text = normalizeInterest(rawText);\n if (!current.interests.some((t) => normalizeInterest(t) === text)) {\n return { ok: false, reason: 'not-found', doc: current };\n }\n const doc = ensureUserLayer(guard, paths);\n doc.interests = doc.interests.filter((t) => normalizeInterest(t) !== text);\n saveDoc(guard, userInterestsPath(paths), doc);\n return { ok: true, doc };\n}\n\n/** Validate \"HH:MM\" and same-day ordering (the wander windows are intra-day). */\nexport function parseWindow(w: unknown): { ok: true; window: WanderWindow } | { ok: false; reason: string } {\n if (typeof w !== 'object' || w === null) return { ok: false, reason: 'not-an-object' };\n const { id, start, end } = w as { id?: unknown; start?: unknown; end?: unknown };\n if (typeof start !== 'string' || !HHMM.test(start)) return { ok: false, reason: `bad start ${JSON.stringify(start)}` };\n if (typeof end !== 'string' || !HHMM.test(end)) return { ok: false, reason: `bad end ${JSON.stringify(end)}` };\n if (start >= end) return { ok: false, reason: `start ${start} must be before end ${end}` };\n return { ok: true, window: { id: typeof id === 'string' && id ? id : `${start}-${end}`, start, end } };\n}\n\n/** Full-state write of the wander windows (the card sends all rows each time). */\nexport function setWanderWindows(\n guard: PathGuard,\n paths: WorkspacePaths,\n rawWindows: unknown,\n): InterestsResult {\n const fail = (reason: string): InterestsResult => ({ ok: false, reason, doc: readEffective(paths) });\n if (!Array.isArray(rawWindows)) return fail('windows-must-be-array');\n if (rawWindows.length === 0) return fail('at-least-one-window');\n if (rawWindows.length > MAX_WINDOWS) return fail(`cap (${MAX_WINDOWS})`);\n const windows: WanderWindow[] = [];\n for (const raw of rawWindows) {\n const parsed = parseWindow(raw);\n if (!parsed.ok) return fail(parsed.reason);\n windows.push(parsed.window);\n }\n // Overlap check: the adjudicator returns the FIRST matching window, so\n // overlapping rows would silently change which window \"wins\".\n const sorted = [...windows].sort((a, b) => a.start.localeCompare(b.start));\n for (let i = 1; i < sorted.length; i += 1) {\n if (sorted[i]!.start < sorted[i - 1]!.end) {\n return fail(`windows overlap: ${sorted[i - 1]!.id} / ${sorted[i]!.id}`);\n }\n }\n const doc = ensureUserLayer(guard, paths);\n doc._schedule = { ...doc._schedule, windows };\n saveDoc(guard, userInterestsPath(paths), doc);\n return { ok: true, doc };\n}\n","// M7b: self-built time injection (design doc §17.6, D20).\n//\n// Replaces the official dsh-time-context (disabled via the user patch — B9 is\n// superseded by D20: time injection has exactly one owner, this module).\n//\n// Gate (all must pass): step === 1 AND the turn was user-initiated (last\n// session event is `agent/inbox/spliced`, P1 ① conclusion) AND the per-session\n// throttle interval has elapsed. Mid-task steps are never injected.\n// Content: precise local time (+ timezone) and elapsed-since-last-message.\n// Transport: pre-step waterfall append — a strict `createUserMessage` message\n// (r5 rule: never splice hand-rolled objects). Source attribution\n// kind='plugin' keeps the observe phase from ingesting these (C-track rule).\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { atomicWriteJsonSync } from '../core/atomic-fs.js';\nimport { appendAuditLine } from '../core/audit-log.js';\nimport type { PathGuard } from '../core/path-guard.js';\nimport type { WorkspacePaths } from '../core/paths.js';\nimport { sessionEvents } from '../core/orchestrator.js';\nimport type { HostSession } from '../core/orchestrator.js';\n\n/** Pure gate (§17.6): every condition must hold for an injection. */\nexport function shouldInjectTime(input: {\n step: number;\n /** Turn-origin probe (see {@link turnOriginIsInboxSplice}). */\n originIsInboxSplice: boolean;\n lastInjectAt: number;\n now: number;\n intervalMs: number;\n}): boolean {\n if (input.step !== 1) return false;\n if (!input.originIsInboxSplice) return false;\n if (input.intervalMs <= 0) return false;\n return input.now - input.lastInjectAt >= input.intervalMs;\n}\n\n/** Turn-origin probe (review 2026-09-13 #2): does the OPEN turn begin\n * with an inbox splice?\n *\n * An exact \"last event is spliced\" check silently breaks the moment any other\n * plugin writes a session event between the splice and this hook. Instead,\n * scan backwards for the last `agent/inbox/spliced` vs the last `turn/end`:\n * the turn is inbox-driven iff a splice happened after the previous turn\n * finished. This is stable against arbitrary interleaving events. Known\n * semantic: our own delivery followups also splice, so a delivery turn counts\n * as inbox-driven — acceptable (throttled like any other; the alternative,\n * inspecting the spliced messages' sources, is deferred until it matters).\n * Cost: bounded by one turn length, and only paid at step === 1. */\nexport function turnOriginIsInboxSplice(session: HostSession): boolean {\n const events = sessionEvents(session);\n let splicedIdx = -1;\n let turnEndIdx = -1;\n for (let i = events.length - 1; i >= 0 && (splicedIdx < 0 || turnEndIdx < 0); i--) {\n const t = events[i]!.type;\n if (t === 'agent/inbox/spliced' && splicedIdx < 0) splicedIdx = i;\n else if (t === 'turn/end' && turnEndIdx < 0) turnEndIdx = i;\n }\n if (splicedIdx < 0) return false;\n return splicedIdx > turnEndIdx; // no turn/end at all (-1) → splice wins\n}\n\nfunction formatElapsed(ms: number): string {\n const minutes = Math.max(1, Math.round(ms / 60_000));\n if (minutes < 60) return `${minutes} 分钟`;\n const hours = Math.floor(minutes / 60);\n const rest = minutes % 60;\n return rest === 0 ? `${hours} 小时` : `${hours} 小时 ${rest} 分钟`;\n}\n\nfunction localFormatter(timeZone: string | undefined): Intl.DateTimeFormat {\n const options: Intl.DateTimeFormatOptions = {\n year: 'numeric', month: '2-digit', day: '2-digit',\n hour: '2-digit', minute: '2-digit', hour12: false,\n timeZoneName: 'shortOffset',\n };\n if (timeZone !== undefined) return new Intl.DateTimeFormat('zh-CN', { ...options, timeZone });\n return new Intl.DateTimeFormat('zh-CN', options);\n}\n\n/** Render the injected text (§17.6): precise local time + elapsed. Timezone\n * resolution failures fall back to the system zone (never throw to the hook). */\nexport function renderTimeText(input: {\n now: number;\n timeZone?: string;\n /** Timestamp (`event.time`) of the session's last message event. */\n lastMessageTime?: number;\n}): string {\n let timeLine: string;\n try {\n const parts = localFormatter(input.timeZone).formatToParts(new Date(input.now));\n const get = (type: string): string => parts.find((p) => p.type === type)?.value ?? '';\n timeLine = `当前本地时间:${get('year')}-${get('month')}-${get('day')} ${get('hour')}:${get('minute')}(${parts.find((p) => p.type === 'timeZoneName')?.value ?? ''})。`;\n } catch {\n timeLine = `当前本地时间:${new Date(input.now).toISOString()}。`;\n }\n const elapsedLine = input.lastMessageTime === undefined\n ? ''\n : `\\n距本会话上一条消息已过去 ${formatElapsed(input.now - input.lastMessageTime)}。`;\n return timeLine + elapsedLine;\n}\n\n/** Timestamp of the session's last user/assistant/tool message event. */\nexport function lastMessageTime(session: HostSession): number | undefined {\n const events = sessionEvents(session);\n for (let i = events.length - 1; i >= 0; i--) {\n const e = events[i]!;\n const t = (e as { time?: number }).time;\n if (typeof t === 'number' && /user\\/message|assistant\\/message|tool\\/result/.test(e.type)) return t;\n }\n return undefined;\n}\n\n// ── per-session throttle state (survives restarts, like cursors.json) ───\n\nexport interface TimeInjectState {\n [sessionId: string]: number;\n}\n\nexport function timeInjectStatePath(dataDir: string): string {\n return path.join(dataDir, 'time-inject-state.json');\n}\n\nexport function loadTimeInjectState(guard: PathGuard, dataDir: string): TimeInjectState {\n try {\n const parsed = JSON.parse(fs.readFileSync(guard.assert(timeInjectStatePath(dataDir)), 'utf8')) as TimeInjectState;\n return parsed && typeof parsed === 'object' ? parsed : {};\n } catch {\n return {};\n }\n}\n\nexport function saveTimeInjectState(guard: PathGuard, dataDir: string, state: TimeInjectState): void {\n atomicWriteJsonSync(guard.assert(timeInjectStatePath(dataDir)), state);\n}\n\n// ── registration ─────────────────────────────────────────────────────────\n\nexport interface TimeInjectionOptions {\n /** Live-read on every gate check (UI-settable in M7d). */\n getTimeInjectMin(): number;\n timeZone?: string;\n paths: WorkspacePaths;\n logger: { info(msg: string, ...a: unknown[]): void; warn(msg: string, ...a: unknown[]): void };\n onError(error: unknown): void;\n /** Track B status line (§17.5): '' when the statusbar is off or the session\n * rides Track A. Receives the TURN-PINNED track (review #5) so the status\n * line and the system-prompt section can never split one turn. */\n getStatusLine?(session: HostSession, track: 'system-prompt' | 'pre-step'): string;\n /** Pin this turn's track at step===1 (before throttle logic) — every turn\n * start re-pins, so mid-turn capability flips land at the next boundary. */\n pinTrack(sessionId: string, session: HostSession): 'system-prompt' | 'pre-step';\n}\n\ninterface PreStepPayload {\n agent: { session: HostSession };\n step: number;\n signal?: { aborted?: boolean };\n}\n\ninterface EnterDecision {\n kind: string;\n messages: unknown[];\n}\n\n/**\n * Register the gated time injector on `ctx` (all agents, like the official\n * plugin it replaces). Returns the disposer conceptually owned by the caller's\n * fiber via `ctx.effect`.\n */\nexport function registerTimeInjection(\n ctx: {\n on(event: string, listener: (payload: PreStepPayload, next: () => Promise<unknown>) => Promise<unknown>, opts?: { prepend?: boolean }): unknown;\n },\n guard: PathGuard,\n dataDir: string,\n opts: TimeInjectionOptions,\n): void {\n const state = loadTimeInjectState(guard, dataDir);\n ctx.on('agent/pre-step', async (payload, next) => {\n const decision = await next() as EnterDecision;\n if (decision.kind === 'reject' || payload.signal?.aborted) return decision;\n const sessionId = payload.agent.session.id;\n const now = Date.now();\n // Turn-start track pin (review #5): re-pinned at EVERY step===1, before\n // any throttle logic, so the pin never goes stale across turns.\n const track = payload.step === 1 ? opts.pinTrack(sessionId, payload.agent.session) : undefined;\n const intervalMs = Math.max(0, opts.getTimeInjectMin()) * 60_000;\n if (!shouldInjectTime({\n step: payload.step,\n originIsInboxSplice: payload.step === 1 ? turnOriginIsInboxSplice(payload.agent.session) : false,\n lastInjectAt: state[sessionId] ?? 0,\n now,\n intervalMs,\n })) return decision;\n try {\n const { createUserMessage } = await import('@deepseek-ai/dsh-llm');\n let text = renderTimeText({\n now,\n timeZone: opts.timeZone,\n lastMessageTime: lastMessageTime(payload.agent.session),\n });\n // §17.5: Track B rides the same message with a trailing status line\n // (D21: status text itself never carries time words).\n if (opts.getStatusLine && track) {\n const statusLine = opts.getStatusLine(payload.agent.session, track);\n if (statusLine) text += `\\n${statusLine}`;\n }\n const message = createUserMessage({\n content: [{ type: 'text', text }],\n // 0.1.7 V4: producer-owned kind (retired generic 'plugin' is refused).\n source: { kind: 'heartbeat', plugin: 'heartbeat', form: 'snapshot', sections: [{ name: 'heartbeat-time', text }] },\n });\n state[sessionId] = now;\n saveTimeInjectState(guard, dataDir, state);\n appendAuditLine(opts.paths.logsDir + '/heartbeat.jsonl', {\n event: 'time_injected', sessionId, intervalMin: opts.getTimeInjectMin(),\n });\n return { ...decision, messages: [...decision.messages, message] };\n } catch (e) {\n opts.onError(e);\n return decision;\n }\n }, { prepend: true });\n}\n","// M7c: statusbar tracks (design doc §17.4–17.5, §17.7, D19/D21).\n//\n// One status store, two transports, picked per agent by model capability:\n// Track A — in-history-capable models: a dynamic system-prompt section\n// (`heartbeat:status`). The host projection layer dedupes (text\n// unchanged → zero commit) and appends changed prompts after the\n// cached history (KV-safe). Incapable/disabled → the text function\n// returns '' and the section drops out of the render entirely.\n// Track B — every other model: the pre-step time-injection message gains a\n// trailing status line (see time-inject.ts `getStatusLine`).\n// Track evidence: the session log's latest `request/context` event carries the\n// route's `systemPromptUpdate` mode. No evidence yet (fresh session) → Track B\n// (§17.7 default). Red line D21: status text NEVER contains time words.\n\nimport { appendAuditLine } from '../core/audit-log.js';\nimport { sessionEventCount, sessionEvents } from '../core/orchestrator.js';\nimport type { HostSession } from '../core/orchestrator.js';\nimport type { PathGuard } from '../core/path-guard.js';\nimport type { WorkspacePaths } from '../core/paths.js';\nimport { StatusReader } from './store.js';\nimport type { StatusState } from './store.js';\n\n// ── capability probe (review 2026-09-13 #1: incremental tail scan) ───\n// Cache keyed by \"how far we've scanned\", NOT by log length: the length grows\n// every step, so a length key would miss (and rescan the whole log backwards)\n// on every assembly. We remember the scan watermark and, on new events, read\n// only the tail (snapshotEvents(fromSeq) range) for NEW request/context rows.\ninterface CapabilityCache {\n /** Event count at the time of the last scan. */\n scannedUpTo: number;\n supported: boolean;\n}\nconst capabilityCache = new Map<string, CapabilityCache>();\n\nexport function supportsInHistory(session: HostSession): boolean {\n const key = session.id;\n const len = sessionEventCount(session);\n const hit = capabilityCache.get(key);\n if (hit && hit.scannedUpTo === len) return hit.supported;\n // Log shrank (session reset under the same id) → rescan from zero.\n const from = hit && len >= hit.scannedUpTo ? hit.scannedUpTo : 0;\n let supported = false;\n if (from !== 0 && hit) supported = hit.supported;\n const readTail = (fromSeq: number): { type: string; data?: unknown }[] => {\n if (typeof session.snapshotEvents === 'function') {\n try {\n const slice = session.snapshotEvents(fromSeq);\n if (Array.isArray(slice)) return slice;\n } catch { /* fall through to the legacy full read */ }\n }\n return sessionEvents(session).slice(fromSeq);\n };\n for (const e of readTail(from)) {\n if (e.type === 'request/context') {\n supported = (e.data as { systemPromptUpdate?: string } | undefined)?.systemPromptUpdate === 'in-history';\n }\n }\n capabilityCache.set(key, { scannedUpTo: len, supported });\n return supported;\n}\n\n/** Forget cached capability (test helper; also bounds memory across deletes). */\nexport function resetCapabilityCache(): void {\n capabilityCache.clear();\n}\n\nconst SCENE_LABELS: Record<StatusState['scene'], string> = {\n 'quiet-hours': '静默时段,世界睡了',\n 'just-spoke': '刚去和你说过话',\n wandering: '正在闲逛看新东西',\n busy: '看到你在忙,不去打扰',\n present: '在场待着',\n away: '你不在,自己待着',\n};\n\n/** Render the one-line status text (D21 red line: zero time words).\n *\n * RENDER PURITY RED LINE (2026-09-13 review): this MUST stay a pure function\n * of the status state — no clock reads, no counters, no per-call variability.\n * The host projection already refuses to commit identical text (project()\n * emits no updates when the rendered prompt is byte-identical), so purity here\n * is what keeps the in-history append cadence at \"per scene change\", not \"per\n * step\". Any field varying faster than the scene belongs in the time\n * injection, never here.\n *\n * NOTE POLICY (review 2026-09-13 #3): `withNote: false` for the Track A\n * section — the scene label is a constant-table mapping (maximally stable),\n * while the note is engine-room free text that can differ every beat and\n * would defeat the host's byte-dedupe. The note is for the UI and the Track B\n * pre-step line (where each message is small and already event-shaped). */\nexport function renderStatusText(\n status: StatusState | null,\n opts?: { withNote?: boolean },\n): string {\n if (!status) return '';\n const label = SCENE_LABELS[status.scene] ?? '在场';\n const note = opts?.withNote === false ? '' : status.note ? `——${status.note}` : '';\n return `心跳此刻:${label}${note}。`;\n}\n\n// ── turn-pinned track decision (2026-09-13 review #5) ────────────────────\n// The track must be decided ONCE per turn, at its start (step===1 in the\n// pre-step listener), and both transports read that pin. Otherwise a\n// capability flip mid-turn (e.g. the very first request of a fresh capable\n// session lands `request/context` after step 1) splits the turn: the pre-step\n// status line already in history AND the section activating from the next\n// step. A pin updates only at turn starts, so a flip always lands cleanly at\n// the next turn boundary.\nconst pinnedTrack = new Map<string, 'system-prompt' | 'pre-step'>();\n\n/** Pin and return this turn's track. Call from the pre-step listener at\n * step===1 (before any throttle logic) — every turn start re-pins. */\nexport function pinTrack(sessionId: string, session: HostSession): 'system-prompt' | 'pre-step' {\n const track = trackFor(session);\n pinnedTrack.set(sessionId, track);\n return track;\n}\n\n/** The pinned track when one exists for this session, else the live probe\n * (fallback for assemblies that somehow precede any turn-start pin). */\nexport function pinnedTrackFor(sessionId: string, session: HostSession): 'system-prompt' | 'pre-step' {\n return pinnedTrack.get(sessionId) ?? trackFor(session);\n}\n\nexport function resetPins(): void {\n pinnedTrack.clear();\n}\n\n/** Track-change auditor: emits `statusbar_track` only when an agent's track\n * actually flips (bounded spam; called from the two render paths). */\nconst lastTrack = new Map<string, string>();\n\nexport function noteTrack(auditFile: string, sessionId: string, track: 'system-prompt' | 'pre-step' | 'off'): void {\n if (lastTrack.get(sessionId) === track) return;\n lastTrack.set(sessionId, track);\n try {\n appendAuditLine(auditFile, { event: 'statusbar_track', sessionId, track });\n } catch { /* audit failure must not break rendering */ }\n}\n\n/** Forget a session's track memo (test helper). */\nexport function resetTrackMemo(): void {\n lastTrack.clear();\n}\n\n/** Which transport serves this session right now (§17.7: no evidence yet →\n * Track B; the section flip happens once a request/context event lands). */\nexport function trackFor(session: HostSession): 'system-prompt' | 'pre-step' {\n return supportsInHistory(session) ? 'system-prompt' : 'pre-step';\n}\n\n/** Register the Track A section on the host systemPrompt service. The text\n * provider returns '' (section drops from the render) when the statusbar is\n * off, the agent is unknown, or the session rides Track B. */\nexport function registerStatusbarSection(\n ctx: {\n inject(services: string[], callback: (scoped: unknown) => void): void;\n },\n guard: PathGuard,\n paths: WorkspacePaths,\n opts: { enabled(): boolean; reader: StatusReader },\n): void {\n ctx.inject(['systemPrompt'], (scoped) => {\n const spCtx = scoped as {\n systemPrompt?: {\n section(def: { name: string; order: number; text: string | ((context: unknown) => string) }): unknown;\n };\n effect(fn: () => unknown, label?: string): () => void;\n logger?: { warn(msg: string, ...a: unknown[]): void };\n };\n const section = spCtx.systemPrompt?.section;\n if (typeof section !== 'function') {\n spCtx.logger?.warn('heartbeat: systemPrompt service has no section API, statusbar Track A unavailable');\n return;\n }\n spCtx.effect(() => section.call(spCtx.systemPrompt, {\n name: 'heartbeat:status',\n order: 5000, // between the persona prefix (0) and the harness block (10000)\n text: (context: unknown) => {\n if (!opts.enabled()) {\n noteTrack(paths.logsDir + '/heartbeat.jsonl', (context as { agent?: { session: HostSession } }).agent?.session.id ?? '(none)', 'off');\n return '';\n }\n const agent = (context as { agent?: { session?: HostSession } }).agent;\n if (!agent?.session) return '';\n // Read the TURN-PINNED track (2026-09-13 review #5): a mid-turn\n // capability flip must not activate the section inside the same turn\n // whose pre-step status line already went out on Track B.\n const track = pinnedTrackFor(agent.session.id, agent.session);\n noteTrack(paths.logsDir + '/heartbeat.jsonl', agent.session.id, track);\n if (track !== 'system-prompt') return '';\n return renderStatusText(opts.reader.read(guard, paths), { withNote: false });\n },\n }), 'heartbeat: statusbar section');\n });\n}\n","// The heartbeat agent preset, as a runtime registration (issue #2, 2026-10-10).\n//\n// 0.1.7+ mounts presets from the profile COMPOSITION: a row named\n// `@deepseek-ai/dsh-agent-preset` whose `config` is the definition. That row\n// makes the PROFILE resolve the package — and `@deepseek-ai/dsh-agent-preset`\n// is thin (it only forwards its config to `agentPresets.register`), but its\n// peer closure contains `cordis-plugin-loader` / `cordis-plugin-include` /\n// `cordis-plugin-group`, i.e. the loading machinery itself. So a profile that\n// cannot resolve it fails the WHOLE plugin tree (\"plugin tree failed to load\"\n// on 0.1.5), and one that satisfies it by hand double-instances the machinery\n// (\"prompt section deployment:persona-prefix is already registered\", every\n// session then refuses to resume). Both were reported with reproductions.\n//\n// The registry exposes `register(definition)` for exactly this case — its\n// docstring: \"Parsed configuration supplied by the declaring plugin\" — so the\n// plugin now registers its own preset at runtime and the bundle patch carries\n// no host-package reference at all. The definition below is the same content\n// the composition used to hold (and the same as\n// `assets/presets/heartbeat/agent.cordis.yml`, which older hosts still read\n// off the filesystem).\n//\n// Deliberately NO persona row: the deployment persona (soul card) plus the\n// heartbeat prompt already cover it, and a \"You are a coding agent\" line would\n// overwrite the persona.\n\n/** One child row of the preset, in Cordis entry-list shape. */\nexport interface PresetEntry {\n readonly id?: string;\n readonly name?: string;\n /** `cordis:group` marker: this row nests `config` as child entries. */\n readonly group?: boolean;\n /** Isolation flags a group row may carry (kept verbatim). */\n readonly isolate?: Record<string, unknown>;\n readonly config?: unknown;\n}\n\n/** Identity, display fields and child plugins of one preset. */\nexport interface HeartbeatPresetDefinition {\n readonly id: string;\n readonly name: string;\n readonly description: string;\n readonly order: number;\n readonly plugins: readonly PresetEntry[];\n}\n\n/**\n * The bundled preset definition for `id`.\n *\n * Content = `assets/presets/heartbeat/agent.cordis.yml`: a compaction group\n * (basic + command-compact + tool-result-pruner) plus the single model-facing\n * tool `tool-web` with `fetch: false` (web_search only — no page fetching,\n * no shell, no filesystem, no subagents).\n */\nexport function heartbeatPresetDefinition(id: string = 'heartbeat'): HeartbeatPresetDefinition {\n return {\n id,\n name: '心跳模式',\n description: '心跳 agent 专用:仅 web_search + 上下文折叠;无 shell、无文件、无子代理。',\n order: 20,\n plugins: [\n {\n id: 'compaction',\n name: 'cordis:group',\n group: true,\n isolate: { compaction: true, toolResultPruner: true },\n config: [\n { id: 'compaction-basic', name: '@deepseek-ai/dsh-compaction-basic' },\n { id: 'command-compact', name: '@deepseek-ai/dsh-command-compact' },\n {\n id: 'tool-result-pruner',\n name: '@deepseek-ai/dsh-compaction-tool-result-pruner',\n config: { thresholdChars: 8192, headChars: 4096, tailChars: 1024 },\n },\n ],\n },\n { id: 'tool-web', name: '@deepseek-ai/dsh-tool-web', config: { fetch: false, searchTimeoutMs: 60000 } },\n ],\n };\n}\n\n/** Registration result, for the audit line and the log. */\nexport type PresetRegisterAction = 'registered' | 'skipped-disabled' | 'skipped-no-api' | 'error';\n\nexport interface PresetRegisterResult {\n action: PresetRegisterAction;\n id: string;\n detail?: string;\n}\n\n/** Minimal shape of the registry we call (`AgentPresetRegistry.register`). */\ninterface RegistrarLike {\n register?(definition: unknown): Promise<() => Promise<void>> | (() => Promise<void>);\n}\n\n/**\n * Register the bundled preset at runtime, tolerating every missing-API case.\n *\n * A host whose registry has no `register` (0.1.7-alpha.1 and other partial\n * builds) or no `agentPresets` service at all (pre-0.1.7) must NOT take the\n * host down: the heartbeat simply runs without its preset — degraded (no\n * `web_search`), which the acquire path already audits as `preset=no-api`.\n *\n * @param service The resolved `agentPresets` service, if any.\n * @param id Preset identity to register.\n * @param enabled False when the operator manages the preset themselves.\n * @returns What happened, for the audit line.\n */\nexport async function registerHeartbeatPreset(\n service: unknown,\n id: string = 'heartbeat',\n enabled: boolean = true,\n): Promise<PresetRegisterResult> {\n if (!enabled) return { action: 'skipped-disabled', id };\n const registrar = service as RegistrarLike | undefined;\n if (registrar === undefined || registrar === null || typeof registrar.register !== 'function') {\n return { action: 'skipped-no-api', id };\n }\n try {\n await registrar.register(heartbeatPresetDefinition(id));\n return { action: 'registered', id };\n } catch (e) {\n return { action: 'error', id, detail: String(e).slice(0, 200) };\n }\n}\n","// Ledger as a MODEL TOOL (v1.8.0): the chat agents can record / list / check\r\n// off ledger items themselves, so a todo mentioned in conversation lands in\r\n// the shared ledger without the user commanding anyone to \"write it down\".\r\n//\r\n// Registration is host-side (`ToolRuntime.register`, 0.2.0-rc.2 verified):\r\n// the definition is built as a PLAIN OBJECT here — `parameters` is a raw JSON\r\n// Schema per ToolSchema (dsh-llm), so we do not import `defineTool` and the\r\n// module carries zero new runtime dependencies. `ToolRuntime.register` is the\r\n// only host entry point (looked up dynamically by the caller); on a host\r\n// without it the caller audits and moves on, nothing else is affected.\r\n//\r\n// Scope: registration happens through the plugin's ROOT context, which lands\r\n// the tool in the GLOBAL layer — every agent sees it. The engine room is\r\n// unaffected: its preset restrict({allow:['web_search']}) masks global tools,\r\n// so the heartbeat's own turns cannot touch the ledger.\r\n\r\nimport {\r\n appendEntry,\r\n markDone,\r\n readLedger,\r\n scanPending,\r\n type LedgerEntry,\r\n} from './ledger.js';\r\nimport type { PathGuard } from '../core/path-guard.js';\r\n\r\n/** Minimal structural typing of the host shape — we deliberately do not\r\n * depend on @deepseek-ai/dsh-tools at runtime. */\r\nexport interface RegisterableToolRuntime {\r\n register(definition: unknown): () => void;\r\n}\r\n\r\ninterface LedgerToolArgs {\r\n action?: unknown;\r\n text?: unknown;\r\n key?: unknown;\r\n}\r\n\r\nconst MAX_TEXT = 120;\r\n\r\nfunction clean(v: unknown): string {\r\n return String(v ?? '').replace(/\\s+/g, ' ').trim().slice(0, MAX_TEXT);\r\n}\r\n\r\nfunction fmtEntry(e: LedgerEntry): string {\r\n return `#${e.id} [${e.status}] ${e.date} ${e.text}`;\r\n}\r\n\r\nexport function buildLedgerTool(guard: PathGuard, file: string): unknown {\r\n return {\r\n name: 'ledger',\r\n description:\r\n '共享账本工具(心跳插件的待办与事项记录)。当用户提到计划、待办、承诺、想做的事,' +\r\n '或者某件事已经完成时,主动调用本工具登记或勾掉——不需要等用户明确说\"记一下\"。' +\r\n 'action=add 登记新事项(text 必填);action=list 查看当前未完成事项;action=done 勾掉一条(key 为 #id 或文本子串)。',\r\n parameters: {\r\n type: 'object',\r\n properties: {\r\n action: { type: 'string', enum: ['add', 'list', 'done'], description: 'add=登记,list=查未完成,done=勾掉' },\r\n text: { type: 'string', description: 'action=add 时必填:事项内容(一句话)' },\r\n key: { type: 'string', description: 'action=done 时必填:#id 或事项文本的唯一子串' },\r\n },\r\n required: ['action'],\r\n additionalProperties: false,\r\n },\r\n output: {\r\n schema: {\r\n type: 'object',\r\n properties: {\r\n ok: { type: 'boolean' },\r\n message: { type: 'string' },\r\n },\r\n required: ['ok', 'message'],\r\n additionalProperties: false,\r\n },\r\n render: (_args: unknown, value: unknown) => {\r\n const v = value as { message?: string };\r\n return [{ type: 'text', text: String(v.message ?? '') }];\r\n },\r\n },\r\n timeoutMs: 5000,\r\n // Ledger writes go through read-modify-write on one file; never parallel.\r\n isConcurrencySafe: () => false,\r\n async execute(args: unknown): Promise<unknown> {\r\n const a = (args ?? {}) as LedgerToolArgs;\r\n const action = String(a.action ?? '');\r\n if (action === 'add') {\r\n const text = clean(a.text);\r\n if (!text) return { ok: false, message: 'add 需要非空 text' };\r\n const e = appendEntry(guard, file, text);\r\n return { ok: true, message: `已登记 ${fmtEntry(e)}` };\r\n }\r\n if (action === 'done') {\r\n const key = clean(a.key);\r\n if (!key) return { ok: false, message: 'done 需要 key(#id 或文本子串)' };\r\n const e = markDone(guard, file, key);\r\n if (!e) return { ok: false, message: `没有找到匹配「${key}」的未完成事项(先用 list 查)` };\r\n return { ok: true, message: `已完成 ${fmtEntry(e)}` };\r\n }\r\n if (action === 'list') {\r\n const items = scanPending(guard, file).map(fmtEntry);\r\n return { ok: true, message: items.length > 0 ? `当前未完成 ${items.length} 项:\\n${items.join('\\n')}` : '账本里没有未完成事项' };\r\n }\r\n // Unsupported action shapes should be rare (schema-enforced); stay total.\r\n const total = readLedger(guard, file).entries.length;\r\n return { ok: false, message: `未知 action,账本共 ${total} 条` };\r\n },\r\n };\r\n}\r\n","// dsh-heartbeat plugin entry.\r\n//\r\n// Contract (verified against DSH 0.1.1-rc.2 + dsh-vision-router as the\r\n// third-party reference): the package main exports a cordis plugin -\r\n// { name, inject, Config, apply(ctx, config) }. The bundle-level\r\n// cordis.patch.yml (dsh.bundle.patch) mounts it via\r\n// - insert: - id: heartbeat, name: dsh-heartbeat\r\n// and the loader resolves `name` to this package's main export.\r\n\r\nimport z from '@deepseek-ai/schemastery';\r\nimport { initWorkspace } from './core/paths.js';\r\nimport { createPathGuard } from './core/path-guard.js';\r\nimport { appendAuditLine } from './core/audit-log.js';\r\nimport { loadPolicy, updateUserPolicy } from './config/load.js';\r\nimport { loadUiConfig, saveUiConfig, type UiConfig } from './config/ui-config.js';\r\nimport { deepMerge } from './config/schema.js';\r\nimport { setRuntime, getRuntime } from './core/runtime.js';\r\nimport { startOrchestrator, applyHeartbeatInterval, type OrchestratorDeps } from './core/orchestrator.js';\r\nimport { installHeartbeatRpc } from './rpc.js';\r\nimport { registerTimeInjection } from './statusbar/time-inject.js';\r\nimport { registerStatusbarSection, noteTrack, pinTrack } from './statusbar/track.js';\r\nimport { StatusReader } from './statusbar/store.js';\r\nimport { renderStatusText } from './statusbar/track.js';\r\nimport { installBundledPreset, userPresetRoot, describeInstall } from './core/preset-install.js';\r\nimport { registerHeartbeatPreset } from './core/preset-definition.js';\r\nimport { buildLedgerTool } from './ledger/tool.js';\r\nimport { buildSeedReportTool, reportFilePath } from './seeds/report.js';\r\nimport { ledgerFilePath } from './ledger/ledger.js';\r\n\r\nexport const name = 'heartbeat';\r\n\r\n/**\r\n * Host services required by the orchestrator (verified present in\r\n * DSH 0.1.1-rc.2 via hb-probe: agents service + agent/created + followup).\r\n * `settings` = the host SettingsProvider service (0.1.5): the web card's\r\n * rhythm edits live there. 0.1.5's strict resolution refuses undeclared\r\n * service access, so the name must be declared here.\r\n */\r\nexport const inject = ['agents', 'settings'];\r\n\r\nexport const Config = z.object({\r\n /** Override the runtime data dir (workspace guard boundary). Empty = default (<packageRoot>/data). */\r\n dataDir: z.string().default(''),\r\n /** UI-editable: heartbeat interval in minutes. 0 = use policy file / factory. */\r\n intervalMin: z.number().default(0),\r\n /** UI-editable: daily expression cap. 0 = use policy file / factory. */\r\n maxDailySend: z.number().default(0),\r\n /**\r\n * Agent preset the heartbeat agent joins (`<dshHome>/.agent-presets/<id>/`).\r\n * Without a preset the agent is a BARE agent: tools/prompt sections resolve\r\n * against the empty global layer, so it cannot even see `web_search`.\r\n */\r\n agentPreset: z.string().default('heartbeat'),\r\n /**\r\n * Install the bundled preset (see `agentPreset`) into the roster's user root\r\n * on first run, so setup needs no manual file copy. An existing preset is\r\n * never overwritten; set false to manage the preset entirely by hand.\r\n */\r\n installPreset: z.boolean().default(true),\r\n /** Self-built time injection interval (D20, §17.6). 0 disables injection. */\r\n timeInjectMin: z.number().default(25),\r\n /** IANA timezone for the injected clock; empty = process zone. */\r\n timeZone: z.string().default(''),\r\n /** Statusbar master switch (D19). Off = no section/pre-step status; time injection unaffected. */\r\n statusbar: z.boolean().default(false),\r\n /** v1.6.3 闲着模式:素材池为空时用画像话题兜底主动搭话(默认关)。 */\r\n idleMode: z.boolean().default(false),\r\n /** v1.7.0 节省 token 模式:用户离开(闲置 ≥30 分钟)或锁屏时整跳暂停(默认关)。 */\r\n tokenSaver: z.boolean().default(false),\r\n /** v1.8.0 账本工具:向所有日常会话 agent 注册共享账本工具(默认开)。 */\r\n ledgerTool: z.boolean().default(true),\r\n /** v1.9.0 素材报账工具:投递后由陪伴 agent 主动报账(默认开)。 */\r\n seedReportTool: z.boolean().default(true),\r\n /** v1.8.0 引擎室追加工具:逗号分隔的全局工具名,存在才加入白名单(bili 压缩工具自动探测,无需手填)。 */\r\n extraTools: z.string().default(''),\r\n});\r\n\r\nexport interface HeartbeatConfig {\r\n dataDir?: string | null;\r\n intervalMin?: number;\r\n maxDailySend?: number;\r\n agentPreset?: string;\r\n installPreset?: boolean;\r\n timeInjectMin?: number;\r\n timeZone?: string;\r\n statusbar?: boolean;\r\n idleMode?: boolean;\r\n tokenSaver?: boolean;\r\n ledgerTool?: boolean;\r\n seedReportTool?: boolean;\r\n extraTools?: string;\r\n}\r\n\r\nexport function apply(ctx: OrchestratorDeps['ctx'] & {\r\n get(name: string): unknown;\r\n /** Cordis lazy service declaration: callback runs once the named services mount. */\r\n inject(services: string[], callback: (scoped: unknown) => void): void;\r\n /** Cordis event subscription (pre-step waterfall etc.); returns a disposer. */\r\n on(event: string, listener: (payload: never, next: () => Promise<unknown>) => Promise<unknown>, opts?: { prepend?: boolean }): unknown;\r\n}, config: HeartbeatConfig = {}): void {\r\n const paths = initWorkspace(config.dataDir ? { dataDir: config.dataDir } : {});\r\n const guard = createPathGuard(paths.dataDir);\r\n let policy = loadPolicy(guard, paths.configDir, paths.settingsDir);\r\n\r\n // Card-edited rhythm values (v1.7.0, data/settings/ui.json): the settings\r\n // card writes these over RPC. Precedence: policy layers < ui.json < the\r\n // composition-entry config below.\r\n const ui = loadUiConfig(guard, paths.settingsDir);\r\n if (ui.intervalMin && ui.intervalMin >= 1) {\r\n policy = { ...policy, heartbeat: { ...policy.heartbeat, intervalMin: ui.intervalMin } };\r\n }\r\n if (ui.maxDailySend && ui.maxDailySend >= 1) {\r\n policy = { ...policy, gate: { ...policy.gate, maxDailySend: ui.maxDailySend } };\r\n }\r\n\r\n // Composition-entry overrides (the patch row's config block).\r\n if (config.intervalMin && config.intervalMin >= 1) {\r\n policy = { ...policy, heartbeat: { ...policy.heartbeat, intervalMin: config.intervalMin } };\r\n }\r\n if (config.maxDailySend && config.maxDailySend >= 1) {\r\n policy = { ...policy, gate: { ...policy.gate, maxDailySend: config.maxDailySend } };\r\n }\r\n\r\n const deps: OrchestratorDeps = {\r\n ctx, paths, guard, policy,\r\n agentPreset: config.agentPreset || 'heartbeat',\r\n extraTools: (config.extraTools ?? '').split(',').map((s) => s.trim()).filter(Boolean),\r\n presetRegistration: () => presetRegistration ?? Promise.resolve(),\r\n };\r\n setRuntime({\r\n paths,\r\n guard,\r\n policy,\r\n flags: {\r\n statusbarEnabled: () => statusbarEnabledRef,\r\n timeInjectMin: () => timeInjectMinRef,\r\n idleMode: () => idleModeRef,\r\n tokenSaver: () => tokenSaverRef,\r\n },\r\n });\r\n\r\n // Runtime preset registration (issue #2). The `agentPresets` inject below\r\n // assigns it; the acquire path awaits it before mounting the preset.\r\n let presetRegistration: Promise<void> | undefined;\r\n\r\n // ── Preset: runtime registration + filesystem install (C13 / issue #2) ───\r\n // The preset is what lets the heartbeat agent see `web_search` at all, so\r\n // the plugin owns it in both senses:\r\n //\r\n // 1. RUNTIME REGISTRATION (0.1.7+). The registry takes a definition\r\n // straight from the declaring plugin (`AgentPresetRegistry.register`),\r\n // so nothing in the composition has to name\r\n // `@deepseek-ai/dsh-agent-preset`. That matters: a profile cannot always\r\n // resolve it, and its peer closure contains Cordis's own loader — a\r\n // profile that ships those by hand double-instances the machinery, and\r\n // then every session refuses to resume (\"prompt section\r\n // deployment:persona-prefix is already registered\"), while one that\r\n // cannot resolve the package fails the WHOLE plugin tree at load\r\n // (reported 2026-10-10, both with reproductions). A host whose registry\r\n // has no `register` degrades to an audit line, never a throw.\r\n // 2. FILESYSTEM INSTALL, kept for hosts that still scan the roster's user\r\n // root (`agentPresets.roots`, trust === \"user\"): first run writes the\r\n // bundled template under the roster's OWN root instead of a guessed\r\n // `~/.dsh`, so `$DSH_HOME`/a configured home are honoured; an existing\r\n // preset is never overwritten.\r\n //\r\n // `installPreset: false` means \"the operator manages the preset by hand\", so\r\n // it switches BOTH off. Audit lines: `preset_register`, `preset_install`.\r\n ctx.inject(['agentPresets'], (presetCtx: unknown) => {\r\n const service = (presetCtx as {\r\n agentPresets?: { roots?: Array<{ path?: string; trust?: string }> };\r\n }).agentPresets;\r\n const presetId = config.agentPreset || 'heartbeat';\r\n const installEnabled = config.installPreset !== false;\r\n const audit = (entry: Record<string, unknown>): void => {\r\n try {\r\n appendAuditLine(guard.assert(paths.logsDir + '/heartbeat.jsonl'), entry);\r\n } catch (e) {\r\n ctx.logger.warn('heartbeat: preset audit failed (%s)', String(e).slice(0, 120));\r\n }\r\n };\r\n\r\n presetRegistration = registerHeartbeatPreset(service, presetId, installEnabled).then((result) => {\r\n audit({ event: 'preset_register', ...result });\r\n if (result.action === 'error') {\r\n ctx.logger.warn('heartbeat: preset register failed (%s) — the engine room runs without it', result.detail ?? '');\r\n } else if (result.action === 'registered') {\r\n ctx.logger.info('heartbeat: preset %s registered at runtime', result.id);\r\n } else {\r\n ctx.logger.info('heartbeat: preset registration skipped (%s)', result.action);\r\n }\r\n });\r\n\r\n const root = userPresetRoot(service?.roots);\r\n const result = installBundledPreset({\r\n moduleUrl: import.meta.url,\r\n id: presetId,\r\n ...(root === undefined ? { rosterKnown: service !== undefined } : { root }),\r\n enabled: installEnabled,\r\n });\r\n audit({ event: 'preset_install', ...result });\r\n const line = describeInstall(result);\r\n if (result.action === 'error' || result.action === 'skipped-no-root') {\r\n ctx.logger.warn('heartbeat: %s', line);\r\n } else {\r\n ctx.logger.info('heartbeat: %s', line);\r\n }\r\n });\r\n\r\n // M6: settings section (namespace 'heartbeat') - the web card edits this\r\n // namespace; resolved values apply live (interval reschedules the timer).\r\n let sectionSource: (() => HeartbeatConfig) | null = null;\r\n let timeInjectMinRef = ui.timeInjectMin ?? (config.timeInjectMin ?? 25);\r\n let statusbarEnabledRef = ui.statusbar ?? (config.statusbar !== false);\r\n let idleModeRef = ui.idleMode ?? (config.idleMode === true);\r\n let tokenSaverRef = ui.tokenSaver ?? (config.tokenSaver === true);\r\n\r\n // H-48: ONE setter table for the live-settable fields. The settings section\r\n // and the RPC uiSet path used to carry a copy each of the same six ifs, so a\r\n // new field had to be added twice — and the two copies had already drifted\r\n // (timeInjectMin's lower bound, tokenSaver's absence from the section path).\r\n const applyLiveSettings = (v: {\r\n intervalMin?: number;\r\n maxDailySend?: number;\r\n timeInjectMin?: number;\r\n statusbar?: boolean;\r\n idleMode?: boolean;\r\n tokenSaver?: boolean;\r\n }): void => {\r\n if (v.intervalMin && v.intervalMin >= 1) applyHeartbeatInterval(deps, v.intervalMin);\r\n if (v.maxDailySend && v.maxDailySend >= 1) getRuntime().policy.gate.maxDailySend = v.maxDailySend;\r\n if (typeof v.timeInjectMin === 'number' && v.timeInjectMin >= 0) timeInjectMinRef = v.timeInjectMin;\r\n if (typeof v.statusbar === 'boolean') statusbarEnabledRef = v.statusbar;\r\n if (typeof v.idleMode === 'boolean') {\r\n idleModeRef = v.idleMode;\r\n getRuntime().policy.heartbeat.idleMode = v.idleMode;\r\n }\r\n if (typeof v.tokenSaver === 'boolean') tokenSaverRef = v.tokenSaver;\r\n };\r\n\r\n const applySettingsOverrides = (): void => {\r\n try {\r\n const v = sectionSource?.();\r\n if (!v) return;\r\n applyLiveSettings(v);\r\n ctx.logger.info('heartbeat: settings overrides live (interval %s, cap %s, timeInject %s)', v.intervalMin ?? '-', v.maxDailySend ?? '-', v.timeInjectMin ?? '-');\r\n } catch (e) {\r\n ctx.logger.warn('heartbeat: settings override failed (%s)', String(e).slice(0, 120));\r\n }\r\n };\r\n void (async () => {\r\n try {\r\n // Three settings generations, feature-detected in order:\r\n // - 0.1.5 (dsh-settings 0.1.5-rc.2): the free function moved onto the\r\n // host `settings` service as the `installSection` METHOD.\r\n // - 0.1.7+: the service is `SettingsForms` — plugin config forms render\r\n // from the Config schema on the Plugins page, and an edit RELOADS\r\n // this plugin (timers dispose via ctx.effect, so reloads are safe).\r\n // Nothing to register; the apply-time `config` is the live source.\r\n // - 0.1.1/0.1.2 era hosts: the free function still exists on the\r\n // package. Only consulted when NO settings service is present —\r\n // running it against a 0.1.7 host would poke foreign internals.\r\n const settingsService = (ctx as unknown as { get(name: string): unknown }).get('settings') as\r\n | {\r\n installSection(\r\n owner: unknown,\r\n ns: string,\r\n schema: unknown,\r\n entry: unknown,\r\n hooks: { setSource(fn: () => unknown): void; onChange(): void },\r\n ): void;\r\n describe?(options?: unknown): unknown;\r\n }\r\n | undefined;\r\n if (settingsService && typeof settingsService.installSection === 'function') {\r\n settingsService.installSection(ctx, 'heartbeat', Config, config, {\r\n setSource: (current) => { sectionSource = current as () => HeartbeatConfig; },\r\n onChange: () => { applySettingsOverrides(); },\r\n });\r\n applySettingsOverrides();\r\n ctx.logger.info('heartbeat: settings section registered (0.1.5 settings service)');\r\n return;\r\n }\r\n if (settingsService && typeof settingsService.describe === 'function') {\r\n sectionSource = () => config;\r\n applySettingsOverrides();\r\n ctx.logger.info('heartbeat: config served by the 0.1.7 profile form (edits reload the plugin)');\r\n return;\r\n }\r\n const legacy = (await import('@deepseek-ai/dsh-settings')) as {\r\n settingsNamespace?(ns: string): string;\r\n installSettingsSection?(ctx: unknown, ns: string, schema: unknown, entry: unknown, hooks: object): void;\r\n };\r\n if (typeof legacy.installSettingsSection === 'function' && typeof legacy.settingsNamespace === 'function') {\r\n legacy.installSettingsSection(ctx as never, legacy.settingsNamespace('heartbeat'), Config as never, config as never, {\r\n setSource: (current: unknown) => { sectionSource = current as () => HeartbeatConfig; },\r\n onChange: () => { applySettingsOverrides(); },\r\n });\r\n applySettingsOverrides();\r\n ctx.logger.info('heartbeat: settings section registered (legacy 0.1.1 settings)');\r\n return;\r\n }\r\n ctx.logger.warn('heartbeat: no settings integration found; policy file values only');\r\n } catch (e) {\r\n ctx.logger.warn('heartbeat: settings section unavailable (%s)', String(e).slice(0, 120));\r\n }\r\n })();\r\n\r\n appendAuditLine(\r\n guard.assert(paths.logsDir + '/heartbeat.jsonl'),\r\n { event: 'plugin_init', dataDir: paths.dataDir },\r\n );\r\n\r\n // issue #2: a package-local data dir is moved out of the package on first\r\n // sight. The audit line is the only durable trace; a failed move keeps\r\n // serving the legacy tree (and never deletes it).\r\n if (paths.relocation) {\r\n const auditFile = guard.assert(paths.logsDir + '/heartbeat.jsonl');\r\n if (paths.relocation.action === 'relocated') {\r\n appendAuditLine(auditFile, {\r\n event: 'data_dir_relocated',\r\n from: paths.relocation.srcDir,\r\n to: paths.relocation.dstDir,\r\n files: paths.relocation.files,\r\n bytes: paths.relocation.bytes,\r\n warnings: paths.relocation.warnings,\r\n leftovers: paths.relocation.leftovers,\r\n });\r\n ctx.logger.info(\r\n 'heartbeat: data dir moved out of the package (%s files, %s bytes)',\r\n paths.relocation.files,\r\n paths.relocation.bytes,\r\n );\r\n } else if (paths.relocation.action === 'failed') {\r\n appendAuditLine(auditFile, {\r\n event: 'data_dir_relocate_failed',\r\n stage: paths.relocation.stage,\r\n problems: paths.relocation.problems,\r\n });\r\n ctx.logger.warn(\r\n 'heartbeat: data dir relocation failed (%s); continuing in the package dir',\r\n paths.relocation.stage,\r\n );\r\n }\r\n }\r\n\r\n // ── M6 拓展:正式 RPC 通道(决策 1 = B 方案,探针已验证)──────────\r\n // connection 晚挂载 → ctx.inject(['connection'], ...) 声明式等待;\r\n // 端点分发见 src/rpc.ts(bindings/seeds/status/profile/ledger/config)。\r\n // ui.get/uiSet:节律配置的活视图与\"落盘+即时生效\"(v1.7.0,data/settings/ui.json)。\r\n // psyEnabled 例外:它是 policy 字段,写 data/settings/policy.json 用户层。\r\n const uiGet = () => ({\r\n intervalMin: getRuntime().policy.heartbeat.intervalMin,\r\n maxDailySend: getRuntime().policy.gate.maxDailySend,\r\n timeInjectMin: timeInjectMinRef,\r\n statusbar: statusbarEnabledRef,\r\n idleMode: idleModeRef,\r\n tokenSaver: tokenSaverRef,\r\n psyEnabled: getRuntime().policy.profile.psyEnabled,\r\n });\r\n const uiSet = (patch: UiConfig & { psyEnabled?: boolean }): void => {\r\n if (typeof patch.psyEnabled === 'boolean') {\r\n updateUserPolicy(guard, paths.settingsDir, { profile: { psyEnabled: patch.psyEnabled } });\r\n getRuntime().policy.profile.psyEnabled = patch.psyEnabled;\r\n }\r\n const merged = saveUiConfig(guard, paths.settingsDir, patch);\r\n applyLiveSettings(merged);\r\n };\r\n installHeartbeatRpc(ctx, { paths, guard, policy, ui: { get: uiGet, set: uiSet } });\r\n\r\n // H-49: the ledger (v1.8.0) and seed_report (v1.9.0) registrations were two\r\n // copies of one block — same audit closure, same try/catch, same degradation\r\n // to an audit line on a host without a registerable ToolRuntime. One factory\r\n // now covers both; the audit event names are unchanged.\r\n const registerGlobalTool = (name: string, build: () => unknown): void => {\r\n ctx.inject(['tools'], (scoped: unknown) => {\r\n const audit = (entry: Record<string, unknown>): void => {\r\n try {\r\n appendAuditLine(guard.assert(paths.logsDir + '/heartbeat.jsonl'), entry);\r\n } catch { /* audit must never break startup */ }\r\n };\r\n try {\r\n const tools = (scoped as { tools?: { register(definition: unknown): () => void } }).tools;\r\n if (!tools || typeof tools.register !== 'function') throw new Error('ToolRuntime.register unavailable on this host');\r\n tools.register(build());\r\n audit({ event: `${name}_tool_registered` });\r\n } catch (e) {\r\n audit({ event: `${name}_tool_register_failed`, error: String(e).slice(0, 160) });\r\n }\r\n });\r\n };\r\n\r\n // ── Ledger as a model tool (v1.8.0) ─────────────────────────────────────\r\n // Registers a shared `ledger` tool in the GLOBAL tool layer so every chat\r\n // agent can record/complete todos without being commanded to. The engine\r\n // room never sees it (its preset allow-list masks global tools). Definition\r\n // is a plain object (no dsh-tools import); a host without a registerable\r\n // ToolRuntime degrades to an audit line only.\r\n if (config.ledgerTool !== false) {\r\n registerGlobalTool('ledger', () => buildLedgerTool(guard, ledgerFilePath(paths.dataDir)));\r\n }\r\n\r\n // ── Seed report tool (v1.9.0): the persona files ONE report per delivery ─\r\n // spoken / seed_ids / profile_ids / reason — the unified bookkeeping channel\r\n // that replaced containment-match attribution. Same global-layer pattern as\r\n // the ledger tool; the engine room never sees it.\r\n if (config.seedReportTool !== false) {\r\n registerGlobalTool('seed_report', () => buildSeedReportTool(guard, reportFilePath(paths.dataDir)));\r\n }\r\n\r\n // §7 main loop: dedicated session/agent + timer (first beat after 15s).\r\n startOrchestrator(deps);\r\n\r\n // ── M7b: self-built time injection (D20, §17.6) ────────────────────────\r\n // Gate: step===1 AND user-initiated AND ≥ timeInjectMin since the last\r\n // injection for that session. Official dsh-time-context is disabled via the\r\n // user patch (B9 superseded by D20 — single owner). The interval is\r\n // live-settable: `timeInjectMinRef` is re-read on every gate check.\r\n // ── M7c: statusbar two tracks (D19, §17.4–17.5) ─────────────────────────\r\n // Track A (in-history models) rides a dynamic system-prompt section; Track B\r\n // rides the same pre-step message as the time injection (§17.5 combined).\r\n const statusReader = new StatusReader();\r\n registerStatusbarSection(ctx, guard, paths, {\r\n enabled: () => statusbarEnabledRef,\r\n reader: statusReader,\r\n });\r\n ctx.effect(() => {\r\n registerTimeInjection(ctx, guard, paths.dataDir, {\r\n getTimeInjectMin: () => timeInjectMinRef,\r\n timeZone: config.timeZone || undefined,\r\n paths,\r\n logger: ctx.logger,\r\n onError: (e) => ctx.logger.warn('heartbeat: time injection skipped (%s)', String(e).slice(0, 120)),\r\n pinTrack: (sessionId, session) => {\r\n const track = pinTrack(sessionId, session);\r\n noteTrack(paths.logsDir + '/heartbeat.jsonl', sessionId, track);\r\n return track;\r\n },\r\n getStatusLine: (session, track) => {\r\n if (!statusbarEnabledRef) {\r\n noteTrack(paths.logsDir + '/heartbeat.jsonl', session.id, 'off');\r\n return '';\r\n }\r\n return track === 'pre-step' ? renderStatusText(statusReader.read(guard, paths)) : '';\r\n },\r\n });\r\n return undefined;\r\n }, 'heartbeat: time injection');\r\n\r\n // Host effect contract: fn runs immediately, returns the disposer.\r\n ctx.effect(() => {\r\n return () => {\r\n ctx.logger.info('heartbeat: disposed, timers cleaned up');\r\n };\r\n }, 'heartbeat: lifecycle');\r\n}\r\n\r\n// deepMerge is re-exported for the CLI status command layering.\r\nexport { deepMerge };\r\n"],"mappings":"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","names":["value","value","Binary","result","a","b","Time","date","template","options","pattern","value","extra","path","resolve","toJSON","date","toString","name","key","fs","path","fs","path","fs","path","path","fs","fs","path","getRuntime","from","result","name"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config/ui-config.ts","../src/rpc.ts","../src/browse/interests-edit.ts","../src/statusbar/time-inject.ts","../src/statusbar/track.ts","../src/core/preset-definition.ts","../src/ledger/tool.ts","../src/notepad/tool.ts","../src/excerpt/tool.ts"],"sourcesContent":["// dsh-heartbeat plugin entry.\n//\n// Contract (verified against DSH 0.1.1-rc.2 + dsh-vision-router as the\n// third-party reference): the package main exports a cordis plugin -\n// { name, inject, Config, apply(ctx, config) }. The bundle-level\n// cordis.patch.yml (dsh.bundle.patch) mounts it via\n// - insert: - id: heartbeat, name: dsh-heartbeat\n// and the loader resolves `name` to this package's main export.\n\nimport z from '@deepseek-ai/schemastery';\nimport { initWorkspace } from './core/paths.js';\nimport { createPathGuard } from './core/path-guard.js';\nimport { appendAuditLine } from './core/audit-log.js';\nimport { loadPolicy, updateUserPolicy } from './config/load.js';\nimport { loadUiConfig, saveUiConfig, type UiConfig } from './config/ui-config.js';\nimport { deepMerge } from './config/schema.js';\nimport { setRuntime, getRuntime } from './core/runtime.js';\nimport { startOrchestrator, applyHeartbeatInterval, type OrchestratorDeps } from './core/orchestrator.js';\nimport { installHeartbeatRpc } from './rpc.js';\nimport { registerTimeInjection } from './statusbar/time-inject.js';\nimport { registerStatusbarSection, noteTrack, pinTrack } from './statusbar/track.js';\nimport { StatusReader } from './statusbar/store.js';\nimport { renderStatusText } from './statusbar/track.js';\nimport { installBundledPreset, userPresetRoot, describeInstall } from './core/preset-install.js';\nimport { registerHeartbeatPreset } from './core/preset-definition.js';\nimport { buildLedgerTool } from './ledger/tool.js';\nimport { buildSeedReportTool, reportFilePath } from './seeds/report.js';\nimport { ledgerFilePath } from './ledger/ledger.js';\nimport { buildNotepadTool } from './notepad/tool.js';\nimport { notepadFilePath } from './notepad/store.js';\nimport { buildExcerptTool } from './excerpt/tool.js';\nimport { excerptFilePath } from './excerpt/excerpt.js';\n\nexport const name = 'heartbeat';\n\n/**\n * Host services required by the orchestrator (verified present in\n * DSH 0.1.1-rc.2 via hb-probe: agents service + agent/created + followup).\n * `settings` = the host SettingsProvider service (0.1.5): the web card's\n * rhythm edits live there. 0.1.5's strict resolution refuses undeclared\n * service access, so the name must be declared here.\n */\nexport const inject = ['agents', 'settings'];\n\nexport const Config = z.object({\n /** Override the runtime data dir (workspace guard boundary). Empty = default (<packageRoot>/data). */\n dataDir: z.string().default(''),\n /** UI-editable: heartbeat interval in minutes. 0 = use policy file / factory. */\n intervalMin: z.number().default(0),\n /** UI-editable: daily expression cap. 0 = use policy file / factory. */\n maxDailySend: z.number().default(0),\n /**\n * Agent preset the heartbeat agent joins (`<dshHome>/.agent-presets/<id>/`).\n * Without a preset the agent is a BARE agent: tools/prompt sections resolve\n * against the empty global layer, so it cannot even see `web_search`.\n */\n agentPreset: z.string().default('heartbeat'),\n /**\n * Install the bundled preset (see `agentPreset`) into the roster's user root\n * on first run, so setup needs no manual file copy. An existing preset is\n * never overwritten; set false to manage the preset entirely by hand.\n */\n installPreset: z.boolean().default(true),\n /** Self-built time injection interval (D20, §17.6). 0 disables injection.\n * Left OPTIONAL on purpose (2026-10-17): a schema default here is\n * indistinguishable from an explicit choice, and `applySettingsOverrides`\n * applies this value over ui.json — so a default would silently undo the\n * card on every reload. Unset falls back at the refs below. */\n timeInjectMin: z.number(),\n /** IANA timezone for the injected clock; empty = process zone. */\n timeZone: z.string().default(''),\n /** Statusbar master switch (D19). Off = no section/pre-step status; time injection unaffected. */\n statusbar: z.boolean(),\n /** v1.6.3 闲着模式:素材池为空时用画像话题兜底主动搭话(默认关)。 */\n idleMode: z.boolean(),\n /** v1.7.0 节省 token 模式:用户离开(闲置 ≥30 分钟)或锁屏时整跳暂停(默认关)。 */\n tokenSaver: z.boolean(),\n /** v1.8.0 账本工具:向所有日常会话 agent 注册共享账本工具(默认开)。 */\n ledgerTool: z.boolean().default(true),\n /** v1.9.0 素材报账工具:投递后由陪伴 agent 主动报账(默认开)。 */\n seedReportTool: z.boolean().default(true),\n /** v2.0.0 心事匣工具:留给下一跳的一句便签(默认开)。 */\n notepadTool: z.boolean().default(true),\n /** v2.0.0 摘抄本工具:留句子和小事的地方(默认开)。 */\n excerptTool: z.boolean().default(true),\n /** v1.8.0 引擎室追加工具:逗号分隔的全局工具名,存在才加入白名单(bili 压缩工具自动探测,无需手填)。 */\n extraTools: z.string().default(''),\n});\n\nexport interface HeartbeatConfig {\n dataDir?: string | null;\n intervalMin?: number;\n maxDailySend?: number;\n agentPreset?: string;\n installPreset?: boolean;\n timeInjectMin?: number;\n timeZone?: string;\n statusbar?: boolean;\n idleMode?: boolean;\n tokenSaver?: boolean;\n ledgerTool?: boolean;\n seedReportTool?: boolean;\n notepadTool?: boolean;\n excerptTool?: boolean;\n extraTools?: string;\n}\n\nexport function apply(ctx: OrchestratorDeps['ctx'] & {\n get(name: string): unknown;\n /** Cordis lazy service declaration: callback runs once the named services mount. */\n inject(services: string[], callback: (scoped: unknown) => void): void;\n /** Cordis event subscription (pre-step waterfall etc.); returns a disposer. */\n on(event: string, listener: (payload: never, next: () => Promise<unknown>) => Promise<unknown>, opts?: { prepend?: boolean }): unknown;\n}, config: HeartbeatConfig = {}): void {\n const paths = initWorkspace(config.dataDir ? { dataDir: config.dataDir } : {});\n const guard = createPathGuard(paths.dataDir);\n let policy = loadPolicy(guard, paths.configDir, paths.settingsDir);\n\n // Card-edited rhythm values (v1.7.0, data/settings/ui.json): the settings\n // card writes these over RPC. Precedence: policy layers < ui.json < the\n // composition-entry config below.\n const ui = loadUiConfig(guard, paths.settingsDir);\n if (ui.intervalMin && ui.intervalMin >= 1) {\n policy = { ...policy, heartbeat: { ...policy.heartbeat, intervalMin: ui.intervalMin } };\n }\n if (ui.maxDailySend && ui.maxDailySend >= 1) {\n policy = { ...policy, gate: { ...policy.gate, maxDailySend: ui.maxDailySend } };\n }\n\n // Composition-entry overrides (the patch row's config block).\n if (config.intervalMin && config.intervalMin >= 1) {\n policy = { ...policy, heartbeat: { ...policy.heartbeat, intervalMin: config.intervalMin } };\n }\n if (config.maxDailySend && config.maxDailySend >= 1) {\n policy = { ...policy, gate: { ...policy.gate, maxDailySend: config.maxDailySend } };\n }\n\n const deps: OrchestratorDeps = {\n ctx, paths, guard, policy,\n agentPreset: config.agentPreset || 'heartbeat',\n extraTools: (config.extraTools ?? '').split(',').map((s) => s.trim()).filter(Boolean),\n presetRegistration: () => presetRegistration ?? Promise.resolve(),\n };\n setRuntime({\n paths,\n guard,\n policy,\n flags: {\n statusbarEnabled: () => statusbarEnabledRef,\n timeInjectMin: () => timeInjectMinRef,\n idleMode: () => idleModeRef,\n tokenSaver: () => tokenSaverRef,\n },\n });\n\n // Runtime preset registration (issue #2). The `agentPresets` inject below\n // assigns it; the acquire path awaits it before mounting the preset.\n let presetRegistration: Promise<void> | undefined;\n /** HB-17: registry undo hook + whether dispose already ran (a reload must\n * not leave the preset behind, and an in-flight registration must still be\n * undone if dispose wins the race). */\n let presetDisposer: (() => Promise<void>) | undefined;\n let presetDisposed = false;\n\n // ── Preset: runtime registration + filesystem install (C13 / issue #2) ───\n // The preset is what lets the heartbeat agent see `web_search` at all, so\n // the plugin owns it in both senses:\n //\n // 1. RUNTIME REGISTRATION (0.1.7+). The registry takes a definition\n // straight from the declaring plugin (`AgentPresetRegistry.register`),\n // so nothing in the composition has to name\n // `@deepseek-ai/dsh-agent-preset`. That matters: a profile cannot always\n // resolve it, and its peer closure contains Cordis's own loader — a\n // profile that ships those by hand double-instances the machinery, and\n // then every session refuses to resume (\"prompt section\n // deployment:persona-prefix is already registered\"), while one that\n // cannot resolve the package fails the WHOLE plugin tree at load\n // (reported 2026-10-10, both with reproductions). A host whose registry\n // has no `register` degrades to an audit line, never a throw.\n // 2. FILESYSTEM INSTALL, kept for hosts that still scan the roster's user\n // root (`agentPresets.roots`, trust === \"user\"): first run writes the\n // bundled template under the roster's OWN root instead of a guessed\n // `~/.dsh`, so `$DSH_HOME`/a configured home are honoured; an existing\n // preset is never overwritten.\n //\n // `installPreset: false` means \"the operator manages the preset by hand\", so\n // it switches BOTH off. Audit lines: `preset_register`, `preset_install`.\n ctx.inject(['agentPresets'], (presetCtx: unknown) => {\n const service = (presetCtx as {\n agentPresets?: { roots?: Array<{ path?: string; trust?: string }> };\n }).agentPresets;\n const presetId = config.agentPreset || 'heartbeat';\n const installEnabled = config.installPreset !== false;\n const audit = (entry: Record<string, unknown>): void => {\n try {\n appendAuditLine(guard.assert(paths.logsDir + '/heartbeat.jsonl'), entry);\n } catch (e) {\n ctx.logger.warn('heartbeat: preset audit failed (%s)', String(e).slice(0, 120));\n }\n };\n\n presetRegistration = registerHeartbeatPreset(service, presetId, installEnabled).then((result) => {\n audit({ event: 'preset_register', ...result });\n if (typeof result.disposer === 'function') {\n if (presetDisposed) {\n // dispose already ran while registration was in flight: undo now.\n void Promise.resolve(result.disposer()).catch((e) => {\n ctx.logger.warn('heartbeat: preset dispose failed (%s)', String(e).slice(0, 120));\n });\n } else {\n presetDisposer = result.disposer;\n }\n }\n if (result.action === 'error') {\n ctx.logger.warn('heartbeat: preset register failed (%s) — the engine room runs without it', result.detail ?? '');\n } else if (result.action === 'registered') {\n ctx.logger.info('heartbeat: preset %s registered at runtime', result.id);\n } else {\n ctx.logger.info('heartbeat: preset registration skipped (%s)', result.action);\n }\n });\n\n const root = userPresetRoot(service?.roots);\n const result = installBundledPreset({\n moduleUrl: import.meta.url,\n id: presetId,\n ...(root === undefined ? { rosterKnown: service !== undefined } : { root }),\n enabled: installEnabled,\n });\n audit({ event: 'preset_install', ...result });\n const line = describeInstall(result);\n if (result.action === 'error' || result.action === 'skipped-no-root') {\n ctx.logger.warn('heartbeat: %s', line);\n } else {\n ctx.logger.info('heartbeat: %s', line);\n }\n });\n\n // M6: settings section (namespace 'heartbeat') - the web card edits this\n // namespace; resolved values apply live (interval reschedules the timer).\n let sectionSource: (() => HeartbeatConfig) | null = null;\n let timeInjectMinRef = ui.timeInjectMin ?? (config.timeInjectMin ?? 25);\n // Factory default is OFF (v1.9.3); `=== true` so an UNSET config no longer\n // reads as \"not false = on\" now that the schema leaves it optional.\n let statusbarEnabledRef = ui.statusbar ?? (config.statusbar === true);\n let idleModeRef = ui.idleMode ?? (config.idleMode === true);\n let tokenSaverRef = ui.tokenSaver ?? (config.tokenSaver === true);\n\n // H-48: ONE setter table for the live-settable fields. The settings section\n // and the RPC uiSet path used to carry a copy each of the same six ifs, so a\n // new field had to be added twice — and the two copies had already drifted\n // (timeInjectMin's lower bound, tokenSaver's absence from the section path).\n const applyLiveSettings = (v: {\n intervalMin?: number;\n maxDailySend?: number;\n timeInjectMin?: number;\n statusbar?: boolean;\n idleMode?: boolean;\n tokenSaver?: boolean;\n }): void => {\n if (v.intervalMin && v.intervalMin >= 1) applyHeartbeatInterval(deps, v.intervalMin);\n if (v.maxDailySend && v.maxDailySend >= 1) getRuntime().policy.gate.maxDailySend = v.maxDailySend;\n if (typeof v.timeInjectMin === 'number' && v.timeInjectMin >= 0) timeInjectMinRef = v.timeInjectMin;\n if (typeof v.statusbar === 'boolean') statusbarEnabledRef = v.statusbar;\n if (typeof v.idleMode === 'boolean') {\n idleModeRef = v.idleMode;\n getRuntime().policy.heartbeat.idleMode = v.idleMode;\n }\n if (typeof v.tokenSaver === 'boolean') tokenSaverRef = v.tokenSaver;\n };\n\n const applySettingsOverrides = (): void => {\n try {\n const v = sectionSource?.();\n if (!v) return;\n applyLiveSettings(v);\n ctx.logger.info('heartbeat: settings overrides live (interval %s, cap %s, timeInject %s)', v.intervalMin ?? '-', v.maxDailySend ?? '-', v.timeInjectMin ?? '-');\n } catch (e) {\n ctx.logger.warn('heartbeat: settings override failed (%s)', String(e).slice(0, 120));\n }\n };\n void (async () => {\n try {\n // Three settings generations, feature-detected in order:\n // - 0.1.5 (dsh-settings 0.1.5-rc.2): the free function moved onto the\n // host `settings` service as the `installSection` METHOD.\n // - 0.1.7+: the service is `SettingsForms` — plugin config forms render\n // from the Config schema on the Plugins page, and an edit RELOADS\n // this plugin (timers dispose via ctx.effect, so reloads are safe).\n // Nothing to register; the apply-time `config` is the live source.\n // - 0.1.1/0.1.2 era hosts: the free function still exists on the\n // package. Only consulted when NO settings service is present —\n // running it against a 0.1.7 host would poke foreign internals.\n const settingsService = (ctx as unknown as { get(name: string): unknown }).get('settings') as\n | {\n installSection(\n owner: unknown,\n ns: string,\n schema: unknown,\n entry: unknown,\n hooks: { setSource(fn: () => unknown): void; onChange(): void },\n ): void;\n describe?(options?: unknown): unknown;\n }\n | undefined;\n if (settingsService && typeof settingsService.installSection === 'function') {\n settingsService.installSection(ctx, 'heartbeat', Config, config, {\n setSource: (current) => { sectionSource = current as () => HeartbeatConfig; },\n onChange: () => { applySettingsOverrides(); },\n });\n applySettingsOverrides();\n ctx.logger.info('heartbeat: settings section registered (0.1.5 settings service)');\n return;\n }\n if (settingsService && typeof settingsService.describe === 'function') {\n sectionSource = () => config;\n applySettingsOverrides();\n ctx.logger.info('heartbeat: config served by the 0.1.7 profile form (edits reload the plugin)');\n return;\n }\n const legacy = (await import('@deepseek-ai/dsh-settings')) as {\n settingsNamespace?(ns: string): string;\n installSettingsSection?(ctx: unknown, ns: string, schema: unknown, entry: unknown, hooks: object): void;\n };\n if (typeof legacy.installSettingsSection === 'function' && typeof legacy.settingsNamespace === 'function') {\n legacy.installSettingsSection(ctx as never, legacy.settingsNamespace('heartbeat'), Config as never, config as never, {\n setSource: (current: unknown) => { sectionSource = current as () => HeartbeatConfig; },\n onChange: () => { applySettingsOverrides(); },\n });\n applySettingsOverrides();\n ctx.logger.info('heartbeat: settings section registered (legacy 0.1.1 settings)');\n return;\n }\n ctx.logger.warn('heartbeat: no settings integration found; policy file values only');\n } catch (e) {\n ctx.logger.warn('heartbeat: settings section unavailable (%s)', String(e).slice(0, 120));\n }\n })();\n\n appendAuditLine(\n guard.assert(paths.logsDir + '/heartbeat.jsonl'),\n { event: 'plugin_init', dataDir: paths.dataDir },\n );\n\n // issue #2: a package-local data dir is moved out of the package on first\n // sight. The audit line is the only durable trace; a failed move keeps\n // serving the legacy tree (and never deletes it).\n if (paths.relocation) {\n const auditFile = guard.assert(paths.logsDir + '/heartbeat.jsonl');\n if (paths.relocation.action === 'relocated') {\n appendAuditLine(auditFile, {\n event: 'data_dir_relocated',\n from: paths.relocation.srcDir,\n to: paths.relocation.dstDir,\n files: paths.relocation.files,\n bytes: paths.relocation.bytes,\n warnings: paths.relocation.warnings,\n leftovers: paths.relocation.leftovers,\n });\n ctx.logger.info(\n 'heartbeat: data dir moved out of the package (%s files, %s bytes)',\n paths.relocation.files,\n paths.relocation.bytes,\n );\n } else if (paths.relocation.action === 'failed') {\n appendAuditLine(auditFile, {\n event: 'data_dir_relocate_failed',\n stage: paths.relocation.stage,\n problems: paths.relocation.problems,\n });\n ctx.logger.warn(\n 'heartbeat: data dir relocation failed (%s); continuing in the package dir',\n paths.relocation.stage,\n );\n }\n }\n\n // ── M6 拓展:正式 RPC 通道(决策 1 = B 方案,探针已验证)──────────\n // connection 晚挂载 → ctx.inject(['connection'], ...) 声明式等待;\n // 端点分发见 src/rpc.ts(bindings/seeds/status/profile/ledger/config)。\n // ui.get/uiSet:节律配置的活视图与\"落盘+即时生效\"(v1.7.0,data/settings/ui.json)。\n // psyEnabled 例外:它是 policy 字段,写 data/settings/policy.json 用户层。\n const uiGet = () => ({\n intervalMin: getRuntime().policy.heartbeat.intervalMin,\n maxDailySend: getRuntime().policy.gate.maxDailySend,\n timeInjectMin: timeInjectMinRef,\n statusbar: statusbarEnabledRef,\n idleMode: idleModeRef,\n tokenSaver: tokenSaverRef,\n psyEnabled: getRuntime().policy.profile.psyEnabled,\n });\n const uiSet = (patch: UiConfig & { psyEnabled?: boolean }): void => {\n if (typeof patch.psyEnabled === 'boolean') {\n updateUserPolicy(guard, paths.settingsDir, { profile: { psyEnabled: patch.psyEnabled } });\n getRuntime().policy.profile.psyEnabled = patch.psyEnabled;\n }\n const merged = saveUiConfig(guard, paths.settingsDir, patch);\n applyLiveSettings(merged);\n };\n installHeartbeatRpc(ctx, { paths, guard, policy, ui: { get: uiGet, set: uiSet } });\n\n // H-49: the ledger (v1.8.0) and seed_report (v1.9.0) registrations were two\n // copies of one block — same audit closure, same try/catch, same degradation\n // to an audit line on a host without a registerable ToolRuntime. One factory\n // now covers both; the audit event names are unchanged.\n const registerGlobalTool = (name: string, build: () => unknown): void => {\n ctx.inject(['tools'], (scoped: unknown) => {\n const audit = (entry: Record<string, unknown>): void => {\n try {\n appendAuditLine(guard.assert(paths.logsDir + '/heartbeat.jsonl'), entry);\n } catch { /* audit must never break startup */ }\n };\n try {\n const tools = (scoped as { tools?: { register(definition: unknown): () => void } }).tools;\n if (!tools || typeof tools.register !== 'function') throw new Error('ToolRuntime.register unavailable on this host');\n tools.register(build());\n audit({ event: `${name}_tool_registered` });\n } catch (e) {\n audit({ event: `${name}_tool_register_failed`, error: String(e).slice(0, 160) });\n }\n });\n };\n\n // ── Ledger as a model tool (v1.8.0) ─────────────────────────────────────\n // Registers a shared `ledger` tool in the GLOBAL tool layer so every chat\n // agent can record/complete todos without being commanded to. The engine\n // room never sees it (its preset allow-list masks global tools). Definition\n // is a plain object (no dsh-tools import); a host without a registerable\n // ToolRuntime degrades to an audit line only.\n if (config.ledgerTool !== false) {\n registerGlobalTool('ledger', () => buildLedgerTool(guard, ledgerFilePath(paths.dataDir)));\n }\n\n // ── Seed report tool (v1.9.0): the persona files ONE report per delivery ─\n // spoken / seed_ids / profile_ids / reason — the unified bookkeeping channel\n // that replaced containment-match attribution. Same global-layer pattern as\n // the ledger tool; the engine room never sees it.\n if (config.seedReportTool !== false) {\n registerGlobalTool('seed_report', () => buildSeedReportTool(guard, reportFilePath(paths.dataDir)));\n }\n\n // ── 心事匣 (v2.0.0): one note she leaves for the next beat ──────────────\n // Same global-layer pattern, and the same reason as above: the engine room\n // never sees this tool. It does not need to — the note reaches the next beat\n // through the delivery package (material.ts notepadLines), which the engine\n // room builds but never authors. Storage is encrypted (it is more private\n // than the ledger), so the module goes through the vault, not plain text.\n if (config.notepadTool !== false) {\n registerGlobalTool('notepad', () => buildNotepadTool(guard, notepadFilePath(paths.dataDir)));\n }\n\n // ── 摘抄本 (v2.0.0): a line worth keeping, kept in plain text ───────────\n // Same global-layer pattern. Unlike the notepad this one is plaintext on\n // purpose: the settings card opens the file for the user, and a notebook\n // nobody can read is not a notebook. The ledger is the other plaintext file.\n if (config.excerptTool !== false) {\n registerGlobalTool('excerpt', () => buildExcerptTool(guard, excerptFilePath(paths.dataDir)));\n }\n\n // §7 main loop: dedicated session/agent + timer (first beat after 15s).\n startOrchestrator(deps);\n\n // ── M7b: self-built time injection (D20, §17.6) ────────────────────────\n // Gate: step===1 AND user-initiated AND ≥ timeInjectMin since the last\n // injection for that session. Official dsh-time-context is disabled via the\n // user patch (B9 superseded by D20 — single owner). The interval is\n // live-settable: `timeInjectMinRef` is re-read on every gate check.\n // ── M7c: statusbar two tracks (D19, §17.4–17.5) ─────────────────────────\n // Track A (in-history models) rides a dynamic system-prompt section; Track B\n // rides the same pre-step message as the time injection (§17.5 combined).\n const statusReader = new StatusReader();\n registerStatusbarSection(ctx, guard, paths, {\n enabled: () => statusbarEnabledRef,\n reader: statusReader,\n });\n ctx.effect(() => {\n registerTimeInjection(ctx, guard, paths.dataDir, {\n getTimeInjectMin: () => timeInjectMinRef,\n timeZone: config.timeZone || undefined,\n paths,\n logger: ctx.logger,\n onError: (e) => ctx.logger.warn('heartbeat: time injection skipped (%s)', String(e).slice(0, 120)),\n pinTrack: (sessionId, session) => {\n const track = pinTrack(sessionId, session);\n noteTrack(paths.logsDir + '/heartbeat.jsonl', sessionId, track);\n return track;\n },\n getStatusLine: (session, track) => {\n if (!statusbarEnabledRef) {\n noteTrack(paths.logsDir + '/heartbeat.jsonl', session.id, 'off');\n return '';\n }\n return track === 'pre-step' ? renderStatusText(statusReader.read(guard, paths)) : '';\n },\n });\n return undefined;\n }, 'heartbeat: time injection');\n\n // Host effect contract: fn runs immediately, returns the disposer.\n ctx.effect(() => {\n return () => {\n presetDisposed = true;\n const undoPreset = presetDisposer;\n presetDisposer = undefined;\n if (typeof undoPreset === 'function') {\n void Promise.resolve(undoPreset()).catch((e) => {\n ctx.logger.warn('heartbeat: preset dispose failed (%s)', String(e).slice(0, 120));\n });\n }\n ctx.logger.info('heartbeat: disposed, timers cleaned up');\n };\n }, 'heartbeat: lifecycle');\n}\n\n// deepMerge is re-exported for the CLI status command layering.\nexport { deepMerge };\n","// Card-editable rhythm config (v1.7.0): the heartbeat card edits five fields\n// over RPC and they persist in the plugin's OWN user layer, so the editor\n// behaves identically on every host generation (0.1.1 scope / 0.1.5\n// installSection / 0.1.7 profile forms all become irrelevant for these\n// values) and saves apply live without any plugin reload.\n// Startup precedence: factory policy < user policy < ui.json < Config fields.\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { PathGuard } from '../core/path-guard.js';\nimport { atomicWriteFileSync } from '../core/atomic-fs.js';\n\nexport const USER_UI_FILE = 'ui.json';\n\nexport interface UiConfig {\n intervalMin?: number;\n maxDailySend?: number;\n timeInjectMin?: number;\n statusbar?: boolean;\n idleMode?: boolean;\n /** Token-saver (v1.7.0): pause beats while the user is away / locked. */\n tokenSaver?: boolean;\n}\n\nconst RANGES = {\n intervalMin: { min: 1, max: 1440 },\n maxDailySend: { min: 1, max: 50 },\n timeInjectMin: { min: 0, max: 1440 },\n} as const;\n\nfunction sanitize(raw: unknown): UiConfig {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return {};\n const r = raw as Record<string, unknown>;\n const out: UiConfig = {};\n for (const key of ['intervalMin', 'maxDailySend', 'timeInjectMin'] as const) {\n const v = r[key];\n if (typeof v === 'number' && Number.isFinite(v) && v >= RANGES[key].min && v <= RANGES[key].max) {\n out[key] = Math.floor(v);\n }\n }\n if (typeof r.statusbar === 'boolean') out.statusbar = r.statusbar;\n if (typeof r.idleMode === 'boolean') out.idleMode = r.idleMode;\n if (typeof r.tokenSaver === 'boolean') out.tokenSaver = r.tokenSaver;\n return out;\n}\n\nexport function uiConfigPath(settingsDir: string): string {\n return path.join(settingsDir, USER_UI_FILE);\n}\n\n/** Missing user layer is normal; a corrupt layer fails open to defaults. */\nexport function loadUiConfig(guard: PathGuard, settingsDir: string): UiConfig {\n try {\n const raw: unknown = JSON.parse(fs.readFileSync(guard.assert(uiConfigPath(settingsDir)), 'utf8'));\n return sanitize(raw);\n } catch {\n return {};\n }\n}\n\n/** Merge `patch` over the stored layer, sanitize, and persist. */\nexport function saveUiConfig(guard: PathGuard, settingsDir: string, patch: UiConfig): UiConfig {\n const merged = sanitize({ ...loadUiConfig(guard, settingsDir), ...patch });\n const file = guard.assert(uiConfigPath(settingsDir));\n fs.mkdirSync(path.dirname(file), { recursive: true });\n atomicWriteFileSync(file, JSON.stringify(merged, null, 2) + '\\n');\n return merged;\n}\n","// M6: settings-card RPC (decision 1 = Plan B; transport reworked in v1.2.1, C21).\n//\n// Host registers an exact Fetch route under /api via ctx.inject(['connection'], ...)\n// once the connection service mounts; the web card calls\n// connection.rpc.call('/api', 'heartbeat', { endpoint, ...payload }).\n// (The original custom channel '/heartbeat' via rpc.handle() is unusable on\n// DSH 0.1.5+: cordis pins the service's this.ctx to the provider context, so\n// handle()'s internal owner.webServer.register always fails strict resolution.)\n// Bindings authority = data/settings/bindings.json (decision 2); the card is\n// just another client of the same host logic the CLI uses.\n// Every endpoint runs inside the workspace guard; results are {ok,value} or\n// {ok:false,error:{code,message,details}}. Verbs are dispatched through a Map\n// and, when the host's /api gate is missing, only GATE_SAFE_ENDPOINTS serve\n// (⑦A / HB-19, 2026-10-17).\n\nimport { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { OrchestratorDeps } from './core/orchestrator.js';\nimport { getLastBeat, homeSessionId, resetHomeSession } from './core/orchestrator.js';\nimport { appendAuditLine } from './core/audit-log.js';\nimport type { UiConfig } from './config/ui-config.js';\nimport type { PathGuard } from './core/path-guard.js';\nimport { dshHomeDir } from './core/paths.js';\nimport type { WorkspacePaths } from './core/paths.js';\nimport { inQuietHours, readSentState } from './gate/gate.js';\nimport {\n activeSeeds,\n archivedSeeds,\n archiveSeedById,\n deleteSeed,\n loadPool,\n restoreSeed,\n seedsFilePath,\n} from './seeds/pool.js';\nimport { loadProfile, profileFilePath } from './profile/store.js';\nimport { buildDigest } from './profile/digest.js';\nimport { ledgerFilePath } from './ledger/ledger.js';\nimport { EXCERPT_HEADER, excerptFilePath } from './excerpt/excerpt.js';\nimport { listWeeklyReports, readWeeklyReport } from './weekly/report.js';\nimport { addBinding, loadBindings, removeBinding } from './core/bindings.js';\nimport { addInterest, readEffective, removeInterest, setWanderWindows } from './browse/interests-edit.js';\nimport { writeText } from './vault/vault.js';\nimport { readStatus } from './statusbar/store.js';\nimport { loadTimeInjectState } from './statusbar/time-inject.js';\nimport type { Policy } from './config/schema.js';\n\n/** Exact Fetch route under /api (C21: custom rpc.handle channels are unusable\n * under 0.1.5's strict cordis service resolution — see installHeartbeatRpc). */\nexport const RPC_ROUTE_PATH = '/api/heartbeat';\n\n/**\n * ⑦A (2026-10-17 review, tightening H-41): the host's `/api` prefix gate is the\n * only authentication this route has — the plugin holds no credential of its own.\n * When that gate cannot be found the route fails closed: every verb is refused\n * except this short list of read-only, low-sensitivity ones (liveness plus what\n * the settings card needs to render). H-41+HB-19 refused six \"destructive\" verbs\n * and served everything else, which left every memory-bearing read —\n * `profile.digest`, `profile.partitions`, `seeds.list`, `interests.list`,\n * `weekly.get`, `migrate.export` — open to anything that could POST to loopback.\n */\nconst GATE_SAFE_ENDPOINTS = new Set([\n 'status',\n 'config.get',\n 'sessions.list',\n 'bindings.get',\n 'weekly.list',\n]);\n\ninterface RpcDeps {\n ctx: OrchestratorDeps['ctx'] & {\n inject(services: string[], callback: (scoped: unknown) => void): void;\n };\n paths: WorkspacePaths;\n guard: PathGuard;\n policy: Policy;\n /** Card-edited rhythm values (v1.7.0): live view getter + persist-and-apply setter. */\n ui: {\n get(): {\n intervalMin: number;\n maxDailySend: number;\n timeInjectMin: number;\n statusbar: boolean;\n idleMode: boolean;\n tokenSaver: boolean;\n psyEnabled: boolean;\n };\n set(patch: UiConfig & { psyEnabled?: boolean }): void;\n };\n}\n\ntype RpcResult = { ok: true; value: unknown } | { ok: false; error: { code: string; message: string; details: Record<string, never> } };\n\nconst ok = (value: unknown): RpcResult => ({ ok: true, value });\nconst err = (code: string, message: string): RpcResult => ({ ok: false, error: { code, message, details: {} } });\n\nlet cachedVersion: string | null = null;\n/** Plugin version for the card's status block (read once from package.json). */\nfunction pluginVersion(paths: WorkspacePaths): string {\n if (cachedVersion) return cachedVersion;\n try {\n const pkg = JSON.parse(fs.readFileSync(path.join(paths.packageRoot, 'package.json'), 'utf8')) as { version?: string };\n cachedVersion = typeof pkg.version === 'string' ? pkg.version : 'unknown';\n } catch {\n cachedVersion = 'unknown';\n }\n return cachedVersion;\n}\n\n/** 素材池生命周期的审计出口(v1.9.0):卡片上的归档/恢复/删除也留下痕迹。 */\nfunction seedAuditSink(paths: WorkspacePaths): (entry: Record<string, unknown>) => void {\n return (entry) => {\n try {\n appendAuditLine(paths.logsDir + '/heartbeat.jsonl', entry);\n } catch { /* audit must never break the RPC call */ }\n };\n}\n\n/** 兴趣/时段卡片编辑的审计留痕(成功才记;失败原因走 RPC err 回给卡片)。 */\nfunction auditInterests(paths: WorkspacePaths, action: string, r: { ok: boolean }, detail: unknown): void {\n try {\n appendAuditLine(paths.logsDir + '/heartbeat.jsonl', {\n event: `interests_${r.ok ? 'edit' : 'edit_failed'}`,\n action,\n detail: typeof detail === 'string' ? detail.slice(0, 80) : null,\n });\n } catch { /* audit must never break the RPC call */ }\n}\n\n/** Session titles from the host's projection cache. Titles are host data — the\n * client card merges them (client.js `nameOf`: title || id prefix).\n *\n * DSH 0.1.2 writes ONE RECORD PER SESSION under\n * `~/.dsh/storages/session_projcache/sessions/<sessionId>.json`\n * (`record.rows.title.val`). The single-file `session_projcache.json` we used\n * before is the older aggregate layout and goes stale: a session created after\n * the upgrade is simply absent from it, so `title` came back null and the card\n * printed the raw session id. Read the per-record layout FIRST, keep the\n * aggregate only as a legacy fallback. */\nfunction loadSessionTitles(): Record<string, string> {\n const titles: Record<string, string> = {};\n const take = (id: string, value: unknown): void => {\n const t = value as { rows?: { title?: { val?: unknown } }; title?: { val?: unknown } } | undefined;\n const row = t?.rows?.title ?? t?.title;\n if (row && typeof row.val === 'string' && row.val && !titles[id]) titles[id] = row.val;\n };\n // 1) per-record layout (current).\n try {\n const dir = path.join(dshHomeDir(), 'storages', 'session_projcache', 'sessions');\n for (const file of fs.readdirSync(dir)) {\n if (!file.endsWith('.json')) continue;\n const id = file.slice(0, -'.json'.length);\n if (!id.startsWith('session-')) continue;\n try {\n const record = JSON.parse(fs.readFileSync(path.join(dir, file), 'utf8')) as { record?: unknown };\n take(id, record.record);\n } catch { /* skip a record we cannot read */ }\n }\n } catch { /* no per-record dir on older hosts */ }\n // 2) legacy aggregate fallback.\n try {\n const raw = JSON.parse(fs.readFileSync(path.join(dshHomeDir(), 'storages', 'session_projcache.json'), 'utf8')) as unknown;\n const walk = (node: unknown): void => {\n if (!node || typeof node !== 'object') return;\n for (const [key, value] of Object.entries(node as Record<string, unknown>)) {\n if (key.startsWith('session-') && value && typeof value === 'object') {\n // Title lives at <session>.rows.title.val (host title service); the\n // val may be null while the title is still being generated.\n take(key, value);\n }\n walk(value);\n }\n };\n walk(raw);\n return titles;\n } catch {\n return titles;\n }\n}\n\n/** Host-side session registry (`~/.dsh/storages/workspace.json`) → the set of\n * session ids the USER actually sees in the sidebar.\n *\n * A persisted session is user-visible iff it belongs to some workspace's\n * `sessionIds` and is not in `archivedSessionIds`. Two exclusions fall out of\n * this for the bind picker (2026-09-30 user request):\n * - **archived** sessions (explicit `archivedSessionIds`, prefix formats are\n * mixed on disk — some entries carry `session-`, some don't — so match\n * both forms);\n * - **subagent child sessions**, which never join any workspace's\n * `sessionIds` (observed: they only ever land in the archive list).\n *\n * Fail-open: a missing/corrupt registry returns `registryFound: false` and\n * the caller shows everything — an unreadable registry must not blank the\n * picker. The heartbeat home is always shown regardless (caller-side). */\nexport function loadVisibleSessionIds(registryFile?: string): { visible: Set<string>; registryFound: boolean } {\n try {\n const file = registryFile ?? path.join(dshHomeDir(), 'storages', 'workspace.json');\n const j = JSON.parse(fs.readFileSync(file, 'utf8')) as {\n global?: { archivedSessionIds?: unknown };\n tables?: { workspaces?: Record<string, { sessionIds?: unknown }> };\n };\n const archived = new Set(\n (Array.isArray(j.global?.archivedSessionIds) ? (j.global!.archivedSessionIds as unknown[]) : [])\n .map((s) => String(s)),\n );\n const isArchived = (id: string): boolean =>\n archived.has(id) || archived.has(id.replace(/^session-/, ''));\n const visible = new Set<string>();\n for (const ws of Object.values(j.tables?.workspaces ?? {})) {\n const ids = Array.isArray(ws?.sessionIds) ? (ws.sessionIds as unknown[]) : [];\n for (const raw of ids) {\n const id = String(raw);\n if (!isArchived(id)) visible.add(id);\n }\n }\n return { visible, registryFound: true };\n } catch {\n return { visible: new Set(), registryFound: false };\n }\n}\n\n/** One RPC verb: payload in, envelope out. `guard` / `paths` / `policy` / `deps`\n * come from the closure built by {@link buildEndpoints}. */\ntype Endpoint = (p: Record<string, unknown>) => RpcResult | Promise<RpcResult>;\n\n/**\n * H-36: the endpoint table. This used to be a single `switch` at the bottom of\n * the route handler — 22 verbs and ~250 lines, with the guest list (which\n * endpoints exist) tangled up with the machinery (envelope validation, the\n * catch-all error wrapper). Adding a verb is now one entry here; the wrapper\n * stays in one place.\n */\nfunction buildEndpoints(deps: Omit<RpcDeps, 'ctx'>, isLive: (sessionId: string) => boolean): Record<string, Endpoint> {\n const { guard, paths, policy } = deps;\n return {\n async status() {\n const now = Date.now();\n const sent = readSentState(guard, paths, now);\n const beat = getLastBeat();\n // M7 statusbar block (§17.8): store + throttle-state + live flags.\n let lastTimeInjectAt: number | null = null;\n try {\n const state = loadTimeInjectState(guard, paths.dataDir);\n for (const v of Object.values(state)) {\n if (typeof v === 'number' && v > (lastTimeInjectAt ?? 0)) lastTimeInjectAt = v;\n }\n } catch { /* missing state file = never injected */ }\n let flags = { statusbarEnabled: true, timeInjectMin: 25, idleMode: false };\n try {\n const { getRuntime } = await import('./core/runtime.js');\n const f = getRuntime().flags;\n flags = { statusbarEnabled: f.statusbarEnabled(), timeInjectMin: f.timeInjectMin(), idleMode: f.idleMode() };\n } catch { /* pre-init: report defaults */ }\n return ok({\n now: new Date(now).toISOString(),\n version: pluginVersion(paths),\n intervalMin: policy.heartbeat.intervalMin,\n idleMode: policy.heartbeat.idleMode,\n cap: { used: sent.items.length, max: policy.gate.maxDailySend },\n quiet: inQuietHours(policy, now),\n lastBeat: beat,\n homeSessionId: homeSessionId(guard, paths),\n bindings: loadBindings(guard, paths.settingsDir).bindings.length,\n statusbar: {\n enabled: flags.statusbarEnabled,\n timeInjectMin: flags.timeInjectMin,\n lastStatus: readStatus(guard, paths),\n lastTimeInjectAt: lastTimeInjectAt === null ? null : new Date(lastTimeInjectAt).toISOString(),\n },\n });\n },\n\n 'sessions.list'() {\n const root = path.join(dshHomeDir(), 'sessions');\n const bindings = loadBindings(guard, paths.settingsDir).bindings;\n const home = homeSessionId(guard, paths);\n const titles = loadSessionTitles();\n // Bind picker visibility: hide archived and subagent sessions\n // (2026-09-30 user request). Fail-open when the registry is\n // unreadable; the home is always listed.\n const { visible, registryFound } = loadVisibleSessionIds();\n const out: Record<string, unknown>[] = [];\n if (fs.existsSync(root)) {\n for (const slug of fs.readdirSync(root)) {\n for (const id of fs.readdirSync(path.join(root, slug))) {\n if (registryFound && id !== home && !visible.has(id)) continue;\n const binding = bindings.find((b) => b.sessionId === id);\n out.push({\n id,\n title: titles[id] ?? null,\n cwdSlug: slug,\n live: isLive(id),\n home: id === home,\n deliver: binding?.deliver ?? false,\n observe: binding?.observe ?? false,\n });\n }\n }\n }\n return ok({ sessions: out });\n },\n\n 'bindings.get': () => ok(loadBindings(guard, paths.settingsDir)),\n\n 'bindings.add'(p) {\n const id = String(p.sessionId ?? '');\n if (!id.startsWith('session-')) return err('bad-request', 'sessionId must look like session-...');\n const home = homeSessionId(guard, paths);\n if (id === home) return err('bad-request', '该会话是心跳正身,无需绑定(决策轮次固定发生在正身)');\n // Callers send BOTH flags explicitly (the card's per-flag toggles), so\n // this stays a full-state write: deliver defaults on, observe off.\n const b = addBinding(guard, paths.settingsDir, id, {\n deliver: p.deliver !== false,\n observe: p.observe === true,\n });\n return ok(b);\n },\n\n 'bindings.remove'(p) {\n const id = String(p.sessionId ?? '');\n const removed = removeBinding(guard, paths.settingsDir, id);\n // H-09/H-45: one shared release path — gate.json, the home_reset audit\n // line and the orchestrator's cached agent — instead of an inline delete\n // that silently left the in-memory home behind.\n const homeReset = resetHomeSession(guard, paths, id);\n return ok({ removed, homeReset });\n },\n\n 'seeds.list'() {\n const db = loadPool(guard, seedsFilePath(paths.dataDir));\n return ok({\n active: activeSeeds(db),\n archived: archivedSeeds(db),\n cap: policy.seeds.maxActive,\n });\n },\n\n 'seeds.archive'(p) {\n const s = archiveSeedById(guard, seedsFilePath(paths.dataDir), String(p.id ?? ''), 'completed', Date.now(), seedAuditSink(paths));\n return s ? ok(s) : err('not-found', 'active seed not found');\n },\n\n 'seeds.restore'(p) {\n const r = restoreSeed(guard, seedsFilePath(paths.dataDir), policy, String(p.id ?? ''), Date.now(), seedAuditSink(paths));\n return r.ok ? ok(r.seed) : err('restore-failed', r.reason);\n },\n\n 'seeds.delete'(p) {\n return ok({ deleted: deleteSeed(guard, seedsFilePath(paths.dataDir), String(p.id ?? ''), seedAuditSink(paths)) });\n },\n\n // ── 兴趣范围 / 浏览时段(v1.4.0;首编继承出厂,见 interests-edit.ts)──\n 'interests.list': () => ok(readEffective(paths)),\n\n 'interests.add'(p) {\n const r = addInterest(guard, paths, String(p.text ?? ''));\n auditInterests(paths, 'add', r, p.text);\n return r.ok ? ok(r.doc) : err('bad-request', r.reason ?? 'add failed');\n },\n\n 'interests.remove'(p) {\n const r = removeInterest(guard, paths, String(p.text ?? ''));\n auditInterests(paths, 'remove', r, p.text);\n return r.ok ? ok(r.doc) : err('not-found', r.reason ?? 'remove failed');\n },\n\n 'interests.setWindows'(p) {\n const r = setWanderWindows(guard, paths, p.windows);\n auditInterests(paths, 'set-windows', r, JSON.stringify(p.windows ?? null));\n return r.ok ? ok(r.doc) : err('bad-request', r.reason ?? 'setWindows failed');\n },\n\n 'config.get': () => ok(deps.ui.get()),\n\n 'config.set'(p) {\n const patch = p as UiConfig;\n if (!patch || typeof patch !== 'object' || Array.isArray(patch)) {\n return err('bad-request', 'config.set needs a patch object');\n }\n const keys = Object.keys(patch).filter((k) =>\n ['intervalMin', 'maxDailySend', 'timeInjectMin', 'statusbar', 'idleMode', 'tokenSaver', 'psyEnabled'].includes(k),\n );\n if (keys.length === 0) return err('bad-request', 'config.set has no recognized field');\n try {\n deps.ui.set(patch);\n } catch (e) {\n return err('bad-request', String(e).slice(0, 120));\n }\n appendAuditLine(guard.assert(paths.logsDir + '/heartbeat.jsonl'), { event: 'ui_config_set', keys });\n return ok(deps.ui.get());\n },\n\n 'profile.digest'() {\n const d = buildDigest(guard, paths, policy, {});\n return ok({\n tact: d.tact,\n topic: d.topic,\n wander: d.wander,\n withinBudget: d.withinBudget,\n // v2.0 (item 6): the card shows the budget and what the caps dropped.\n totalChars: d.totalChars,\n budgetChars: d.budgetChars,\n omitted: d.omitted,\n });\n },\n\n 'profile.partitions'() {\n // v2.0 (item 6): the card shows ONE partition at a time, entry by entry.\n // The digest view was a wall of text and never showed what the profile\n // actually holds. Read-only, same data profile.export walks.\n const doc = loadProfile(guard, profileFilePath(paths.dataDir));\n const partitions: Record<string, { total: number; valid: number; entries: Record<string, unknown>[] }> = {};\n for (const part of ['interest', 'projects', 'comm', 'psy'] as const) {\n const all = doc.partitions[part]?.entries ?? [];\n const valid = all.filter((e) => e.validTo === null);\n partitions[part] = {\n total: all.length,\n valid: valid.length,\n entries: valid\n .slice()\n .sort((a, b) => b.confidence - a.confidence || (a.updatedAt < b.updatedAt ? 1 : -1))\n .map((e) => ({\n id: e.id,\n topic: e.topic,\n subTopic: e.subTopic,\n content: e.content,\n confidence: e.confidence,\n temporal: e.temporal,\n updatedAt: e.updatedAt,\n lowActivity: e.lowActivity === true,\n })),\n };\n }\n return ok({ partitions });\n },\n\n 'profile.export'() {\n const doc = loadProfile(guard, profileFilePath(paths.dataDir));\n const lines = [`# 画像导出 ${new Date().toISOString()}`, ''];\n for (const part of ['interest', 'projects', 'comm', 'psy'] as const) {\n lines.push(`## ${part}`);\n for (const e of doc.partitions[part]!.entries) {\n if (e.validTo !== null) continue;\n lines.push(`- [${e.topic}/${e.subTopic}] ${e.content} (conf ${e.confidence.toFixed(2)}, ${e.temporal})`);\n }\n }\n const out = path.join(paths.exportsDir, `profile-export-${Date.now()}.md`);\n writeText(guard, out, lines.join('\\n') + '\\n');\n return ok({ path: out });\n },\n\n 'ledger.open'() {\n const f = ledgerFilePath(paths.dataDir);\n if (!fs.existsSync(guard.assert(f))) fs.writeFileSync(f, '# 账本\\n', 'utf8');\n spawn('cmd', ['/c', 'start', '', f], { detached: true, stdio: 'ignore' }).unref();\n return ok({ path: f });\n },\n\n 'excerpt.open'() {\n const f = excerptFilePath(paths.dataDir);\n if (!fs.existsSync(guard.assert(f))) fs.writeFileSync(f, EXCERPT_HEADER, 'utf8');\n spawn('cmd', ['/c', 'start', '', f], { detached: true, stdio: 'ignore' }).unref();\n return ok({ path: f });\n },\n\n 'weekly.list': () => ok({ reports: listWeeklyReports(guard, paths.dataDir, policy.weekly.keepReports) }),\n\n 'weekly.get'(p) {\n const file = String(p.file ?? '');\n const rep = readWeeklyReport(guard, paths.dataDir, file);\n if (!rep) return err('bad-request', `no such report: ${file}`);\n return ok(rep);\n },\n\n async 'migrate.export'(p) {\n // Card-side export (v1.8.0): same container as the CLI. The\n // passphrase lives only in this call — never audited, never logged.\n const passphrase = String(p.passphrase ?? '');\n if (!passphrase) return err('bad-request', '需要设置口令');\n const { collectMigrationEntries, encryptContainer } = await import('./vault/migrate.js');\n const { entries } = collectMigrationEntries(guard, paths);\n if (entries.length === 0) return err('bad-request', '没有可打包的记忆文件(data/ 是空的)');\n const out = path.join(paths.exportsDir, `heartbeat-memory-${new Date().toISOString().slice(0, 10)}.hbmig`);\n writeText(guard, out, encryptContainer(entries, passphrase));\n appendAuditLine(guard.assert(paths.logsDir + '/heartbeat.jsonl'), { event: 'migrate_export', files: entries.length });\n return ok({ path: out, count: entries.length });\n },\n\n async 'migrate.import'(p) {\n const passphrase = String(p.passphrase ?? '');\n const file = String(p.file ?? '');\n if (!passphrase || !file) return err('bad-request', '需要容器路径与口令');\n const { decryptContainer, applyMigrationEntries } = await import('./vault/migrate.js');\n let text: string;\n try {\n // Read-only from a user-chosen path (likely OUTSIDE data/); the\n // path guard still gates every file we WRITE back.\n text = fs.readFileSync(file, 'utf8');\n } catch {\n return err('bad-request', `读不到迁移包:${file}`);\n }\n let container: ReturnType<typeof decryptContainer>;\n try {\n container = decryptContainer(text, passphrase);\n } catch (e) {\n return err('bad-request', String(e instanceof Error ? e.message : e));\n }\n const result = applyMigrationEntries(guard, paths, container.files);\n appendAuditLine(guard.assert(paths.logsDir + '/heartbeat.jsonl'), {\n event: 'migrate_import', restored: result.restored.length, backedUp: result.backedUp.length, skipped: result.skipped.length,\n rolledBack: result.rolledBack?.length ?? 0, error: result.error ?? null,\n });\n // HB-06: an import that wrote nothing is a failure, not a cheerful ok with\n // the reason buried in the payload.\n if (result.error) return err('migrate-failed', result.error);\n return ok(result);\n },\n };\n}\n\nexport function installHeartbeatRpc(\n ctx: OrchestratorDeps['ctx'] & { inject(services: string[], callback: (scoped: unknown) => void): void },\n deps: Omit<RpcDeps, 'ctx'>,\n): void {\n // ── 0.1.5 适配(C21)─────────────────────────────────────────────────\n // 自定义通道 rpc.handle('/heartbeat') 在 0.1.5 的 cordis 严格服务解析下不可\n // 用:Service 把 this.ctx 固定在 client-connection 自己的上下文(其模块\n // inject 只有 ['credentials']),handle() 内部 owner.webServer.register 是在\n // 别人的 fiber 上读 webServer → `cannot get property \"webServer\" without\n // inject`,调用方怎么声明都救不了(现场取证 2026-09-12:合并 inject 三件套\n // + effect 包裹仍是这个错)。改走 connection.fetch.register():在 /api 下注册\n // 精确路由,只写 connection 内部路由表、不碰任何其他服务;0.1.2 与 0.1.5 的\n // /api 共享处理器都先查精确路由再落 interceptor,两代宿主通用。浏览器认证\n // 由 /api 前缀的 requestRejection 统一把关。客户端相应改为\n // rpc.call('/api', 'heartbeat', { endpoint, ...args })。\n ctx.inject(['connection'], (scoped: unknown) => {\n const remoteCtx = scoped as {\n connection: {\n fetch: { register(route: {\n path: string;\n methods: string[];\n requestBody?: string;\n fetch(request: Request): Promise<Response>;\n }): unknown };\n };\n agents: OrchestratorDeps['ctx']['agents'];\n effect(fn: () => unknown, label?: string): () => void;\n };\n\n const isLive = (sessionId: string): boolean => {\n try {\n return !!remoteCtx.agents.get(sessionId);\n } catch {\n return false;\n }\n };\n\n // HB-19 (2026-10-17): a Map, not an object literal. `endpoints[verb]` on a\n // plain object also resolves inherited keys (\"constructor\", \"toString\",\n // \"__proto__\"), so a crafted verb could reach something that was never\n // registered as an endpoint. Map.get has no prototype chain.\n const endpoints = new Map<string, Endpoint>(Object.entries(buildEndpoints(deps, isLive)));\n\n // ── H-41 (2026-10-07): explicit dependency on the host's /api gate ────\n // This route is mounted under the host's `/api` prefix, and that prefix's\n // check is the ONLY authentication it has — the plugin keeps no credential\n // of its own. The host implements it as `connection.admit(req)`, which\n // returns `requestRejection(req)`'s verdict (Host/Origin fence + the\n // browser-auth secret; the `/api` prefix route calls it before dispatching,\n // so this exact path can never be reached without it). If a future host\n // drops or renames that check, the destructive endpoints above would be\n // reachable by anything that can POST to loopback — so fail closed on them\n // instead of guessing, and say so in the audit log once at registration.\n const gate = remoteCtx.connection as unknown as { admit?: unknown; requestRejection?: unknown };\n const hostGuarded = typeof gate.admit === 'function' || typeof gate.requestRejection === 'function';\n if (!hostGuarded) {\n try {\n appendAuditLine(deps.guard.assert(deps.paths.logsDir + '/heartbeat.jsonl'), {\n event: 'rpc_host_gate_missing',\n detail: 'connection.admit/requestRejection absent; all but the low-sensitivity read-only verbs are refused (⑦A)',\n allowed: [...GATE_SAFE_ENDPOINTS],\n });\n } catch { /* 审计失败不影响注册 */ }\n }\n\n const handler = async (endpoint: unknown, payload: unknown): Promise<RpcResult> => {\n const p = (payload ?? {}) as Record<string, unknown>;\n const fn = typeof endpoint === 'string' ? endpoints.get(endpoint) : undefined;\n if (!fn) return err('bad-request', `unknown endpoint ${JSON.stringify(endpoint)}`);\n if (!hostGuarded && !GATE_SAFE_ENDPOINTS.has(endpoint as string)) {\n return err('forbidden', `host gate unavailable; ${endpoint} is refused (H-41, ⑦A)`);\n }\n try {\n return await fn(p);\n } catch (e) {\n return err('internal', String(e).slice(0, 200));\n }\n };\n\n // RPC 信封与 /api 通道的 client-request/server-response 同构(客户端仍是\n // connection.rpc.call),端点名改走 payload.endpoint 字段。\n remoteCtx.effect(\n () => remoteCtx.connection.fetch.register({\n path: RPC_ROUTE_PATH,\n methods: ['POST'],\n requestBody: 'buffered',\n fetch: async (request: Request): Promise<Response> => {\n let envelope: { type?: unknown; rpcId?: unknown; payload?: unknown };\n try {\n envelope = await request.json() as typeof envelope;\n } catch {\n return new Response('body is not JSON', { status: 400 });\n }\n const rpcId = envelope?.rpcId;\n if (envelope?.type !== 'client-request' || typeof rpcId !== 'string' || typeof envelope.payload !== 'object' || envelope.payload === null) {\n return new Response('invalid envelope', { status: 400 });\n }\n const p = envelope.payload as Record<string, unknown>;\n const endpoint = typeof p.endpoint === 'string' ? p.endpoint : '(missing endpoint)';\n const result = await handler(endpoint, p);\n return Response.json({ type: 'server-response', rpcId, result });\n },\n }),\n 'heartbeat: rpc route',\n );\n ctx.logger.info('heartbeat: rpc route ready (%s)', RPC_ROUTE_PATH);\n try {\n appendAuditLine(deps.guard.assert(deps.paths.logsDir + '/heartbeat.jsonl'), { event: 'rpc_registered', route: RPC_ROUTE_PATH });\n } catch { /* 审计失败不影响注册 */ }\n });\n}\n","// Interest-scope editing for the settings card (v1.4.0).\n//\n// The wander adjudicator picks its focus from `interests.json` (browse.ts\n// `loadInterests`): the factory copy in config/ is read-only, and a user layer\n// at data/settings/interests.json REPLACES it wholesale. That replace-not-merge\n// semantics is why every successful edit funnels through `ensureUserLayer`: the\n// FIRST edit copies the factory file (interests + _schedule, verbatim) into the\n// user layer before applying the change, so the card becomes the single\n// management entry point without silently dropping the other factory rows.\n// Reads and FAILED validations stay read-only (`readEffective`) — merely\n// opening the card must not take the user layer over.\n//\n// All writes stay inside the guard; unknown top-level keys (e.g. _comment) are\n// preserved on save so hand-written annotations survive card edits.\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { PathGuard } from '../core/path-guard.js';\nimport type { WorkspacePaths } from '../core/paths.js';\n\n/** Mirrors browse.ts's InterestsConfig; kept local so this module owns the\n * editing shape (windows gain mandatory ids on save). */\nexport interface InterestsDoc {\n interests: string[];\n _schedule?: {\n daily_sessions?: number;\n focus_per_session?: number;\n max_seeds_per_focus?: number;\n focus_cooldown_days?: number;\n min_interval_hours?: number;\n windows?: { id?: string; start: string; end: string }[];\n };\n [key: string]: unknown;\n}\n\nexport interface WanderWindow {\n id: string;\n start: string;\n end: string;\n}\n\nexport const MAX_INTERESTS = 32;\nexport const MAX_INTEREST_LEN = 60;\nconst MAX_WINDOWS = 6;\nconst HHMM = /^([01]\\d|2[0-3]):([0-5]\\d)$/;\n\nexport function userInterestsPath(paths: WorkspacePaths): string {\n return path.join(paths.settingsDir, 'interests.json');\n}\n\nexport function factoryInterestsPath(paths: WorkspacePaths): string {\n return path.join(paths.configDir, 'interests.json');\n}\n\nfunction readDoc(file: string): InterestsDoc | null {\n try {\n const raw = JSON.parse(fs.readFileSync(file, 'utf8')) as Partial<InterestsDoc>;\n if (!Array.isArray(raw.interests)) return null;\n return { ...raw, interests: raw.interests.map(String) };\n } catch {\n return null;\n }\n}\n\n/** What the wander adjudicator sees right now — WITHOUT creating the user\n * layer. Fallback chain: user layer -> factory -> empty. */\nexport function readEffective(paths: WorkspacePaths): InterestsDoc {\n return (\n readDoc(userInterestsPath(paths)) ??\n readDoc(factoryInterestsPath(paths)) ?? { interests: [] }\n );\n}\n\n/**\n * The user layer, created on first EDIT by copying the factory file verbatim\n * (decision: 首编继承出厂). Call only from mutation paths that are about to\n * succeed; the doc it returns equals `readEffective` at call time.\n */\nexport function ensureUserLayer(guard: PathGuard, paths: WorkspacePaths): InterestsDoc {\n const existing = readDoc(userInterestsPath(paths));\n if (existing) return existing;\n const doc: InterestsDoc = readDoc(factoryInterestsPath(paths)) ?? { interests: [] };\n saveDoc(guard, userInterestsPath(paths), doc);\n return doc;\n}\n\nfunction saveDoc(guard: PathGuard, file: string, doc: InterestsDoc): void {\n fs.mkdirSync(path.dirname(file), { recursive: true });\n fs.writeFileSync(guard.assert(file), JSON.stringify(doc, null, 2), 'utf8');\n}\n\nexport interface InterestsResult {\n ok: boolean;\n reason?: string;\n doc: InterestsDoc;\n}\n\n/** Normalize: trim + collapse internal whitespace. Case-insensitive dedupe. */\nexport function normalizeInterest(text: string): string {\n return text.trim().replace(/\\s+/g, ' ');\n}\n\nexport function addInterest(\n guard: PathGuard,\n paths: WorkspacePaths,\n rawText: string,\n): InterestsResult {\n const text = normalizeInterest(rawText);\n if (!text) return { ok: false, reason: 'empty', doc: readEffective(paths) };\n if (text.length > MAX_INTEREST_LEN) {\n return { ok: false, reason: `too-long (max ${MAX_INTEREST_LEN})`, doc: readEffective(paths) };\n }\n const current = readEffective(paths);\n if (current.interests.some((t) => normalizeInterest(t).toLowerCase() === text.toLowerCase())) {\n return { ok: false, reason: 'duplicate', doc: current };\n }\n if (current.interests.length >= MAX_INTERESTS) {\n return { ok: false, reason: `cap (${MAX_INTERESTS})`, doc: current };\n }\n const doc = ensureUserLayer(guard, paths);\n doc.interests.push(text);\n saveDoc(guard, userInterestsPath(paths), doc);\n return { ok: true, doc };\n}\n\nexport function removeInterest(\n guard: PathGuard,\n paths: WorkspacePaths,\n rawText: string,\n): InterestsResult {\n const current = readEffective(paths);\n const text = normalizeInterest(rawText);\n if (!current.interests.some((t) => normalizeInterest(t) === text)) {\n return { ok: false, reason: 'not-found', doc: current };\n }\n const doc = ensureUserLayer(guard, paths);\n doc.interests = doc.interests.filter((t) => normalizeInterest(t) !== text);\n saveDoc(guard, userInterestsPath(paths), doc);\n return { ok: true, doc };\n}\n\n/** Validate \"HH:MM\" and same-day ordering (the wander windows are intra-day). */\nexport function parseWindow(w: unknown): { ok: true; window: WanderWindow } | { ok: false; reason: string } {\n if (typeof w !== 'object' || w === null) return { ok: false, reason: 'not-an-object' };\n const { id, start, end } = w as { id?: unknown; start?: unknown; end?: unknown };\n if (typeof start !== 'string' || !HHMM.test(start)) return { ok: false, reason: `bad start ${JSON.stringify(start)}` };\n if (typeof end !== 'string' || !HHMM.test(end)) return { ok: false, reason: `bad end ${JSON.stringify(end)}` };\n if (start >= end) return { ok: false, reason: `start ${start} must be before end ${end}` };\n return { ok: true, window: { id: typeof id === 'string' && id ? id : `${start}-${end}`, start, end } };\n}\n\n/** Full-state write of the wander windows (the card sends all rows each time). */\nexport function setWanderWindows(\n guard: PathGuard,\n paths: WorkspacePaths,\n rawWindows: unknown,\n): InterestsResult {\n const fail = (reason: string): InterestsResult => ({ ok: false, reason, doc: readEffective(paths) });\n if (!Array.isArray(rawWindows)) return fail('windows-must-be-array');\n if (rawWindows.length === 0) return fail('at-least-one-window');\n if (rawWindows.length > MAX_WINDOWS) return fail(`cap (${MAX_WINDOWS})`);\n const windows: WanderWindow[] = [];\n for (const raw of rawWindows) {\n const parsed = parseWindow(raw);\n if (!parsed.ok) return fail(parsed.reason);\n windows.push(parsed.window);\n }\n // Overlap check: the adjudicator returns the FIRST matching window, so\n // overlapping rows would silently change which window \"wins\".\n const sorted = [...windows].sort((a, b) => a.start.localeCompare(b.start));\n for (let i = 1; i < sorted.length; i += 1) {\n if (sorted[i]!.start < sorted[i - 1]!.end) {\n return fail(`windows overlap: ${sorted[i - 1]!.id} / ${sorted[i]!.id}`);\n }\n }\n const doc = ensureUserLayer(guard, paths);\n doc._schedule = { ...doc._schedule, windows };\n saveDoc(guard, userInterestsPath(paths), doc);\n return { ok: true, doc };\n}\n","// M7b: self-built time injection (design doc §17.6, D20).\n//\n// Replaces the official dsh-time-context (disabled via the user patch — B9 is\n// superseded by D20: time injection has exactly one owner, this module).\n//\n// Gate (all must pass): step === 1 AND the turn was user-initiated (last\n// session event is `agent/inbox/spliced`, P1 ① conclusion) AND the per-session\n// throttle interval has elapsed. Mid-task steps are never injected.\n// Content: precise local time (+ timezone) and elapsed-since-last-message.\n// Transport: pre-step waterfall append — a strict `createUserMessage` message\n// (r5 rule: never splice hand-rolled objects). Source attribution\n// kind='plugin' keeps the observe phase from ingesting these (C-track rule).\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { atomicWriteJsonSync } from '../core/atomic-fs.js';\nimport { appendAuditLine } from '../core/audit-log.js';\nimport type { PathGuard } from '../core/path-guard.js';\nimport type { WorkspacePaths } from '../core/paths.js';\nimport { sessionEvents } from '../core/orchestrator.js';\nimport type { HostSession } from '../core/orchestrator.js';\n\n/** Pure gate (§17.6): every condition must hold for an injection. */\nexport function shouldInjectTime(input: {\n step: number;\n /** Turn-origin probe (see {@link turnOriginIsInboxSplice}). */\n originIsInboxSplice: boolean;\n lastInjectAt: number;\n now: number;\n intervalMs: number;\n}): boolean {\n if (input.step !== 1) return false;\n if (!input.originIsInboxSplice) return false;\n if (input.intervalMs <= 0) return false;\n return input.now - input.lastInjectAt >= input.intervalMs;\n}\n\n/** Turn-origin probe (review 2026-09-13 #2): does the OPEN turn begin\n * with an inbox splice?\n *\n * An exact \"last event is spliced\" check silently breaks the moment any other\n * plugin writes a session event between the splice and this hook. Instead,\n * scan backwards for the last `agent/inbox/spliced` vs the last `turn/end`:\n * the turn is inbox-driven iff a splice happened after the previous turn\n * finished. This is stable against arbitrary interleaving events. Known\n * semantic: our own delivery followups also splice, so a delivery turn counts\n * as inbox-driven — acceptable (throttled like any other; the alternative,\n * inspecting the spliced messages' sources, is deferred until it matters).\n * Cost: bounded by one turn length, and only paid at step === 1. */\nexport function turnOriginIsInboxSplice(session: HostSession): boolean {\n const events = sessionEvents(session);\n let splicedIdx = -1;\n let turnEndIdx = -1;\n for (let i = events.length - 1; i >= 0 && (splicedIdx < 0 || turnEndIdx < 0); i--) {\n const t = events[i]!.type;\n if (t === 'agent/inbox/spliced' && splicedIdx < 0) splicedIdx = i;\n else if (t === 'turn/end' && turnEndIdx < 0) turnEndIdx = i;\n }\n if (splicedIdx < 0) return false;\n return splicedIdx > turnEndIdx; // no turn/end at all (-1) → splice wins\n}\n\nfunction formatElapsed(ms: number): string {\n const minutes = Math.max(1, Math.round(ms / 60_000));\n if (minutes < 60) return `${minutes} 分钟`;\n const hours = Math.floor(minutes / 60);\n const rest = minutes % 60;\n return rest === 0 ? `${hours} 小时` : `${hours} 小时 ${rest} 分钟`;\n}\n\nfunction localFormatter(timeZone: string | undefined): Intl.DateTimeFormat {\n const options: Intl.DateTimeFormatOptions = {\n year: 'numeric', month: '2-digit', day: '2-digit',\n hour: '2-digit', minute: '2-digit', hour12: false,\n timeZoneName: 'shortOffset',\n };\n if (timeZone !== undefined) return new Intl.DateTimeFormat('zh-CN', { ...options, timeZone });\n return new Intl.DateTimeFormat('zh-CN', options);\n}\n\n/** Render the injected text (§17.6): precise local time + elapsed. Timezone\n * resolution failures fall back to the system zone (never throw to the hook). */\nexport function renderTimeText(input: {\n now: number;\n timeZone?: string;\n /** Timestamp (`event.time`) of the session's last message event. */\n lastMessageTime?: number;\n}): string {\n let timeLine: string;\n try {\n const parts = localFormatter(input.timeZone).formatToParts(new Date(input.now));\n const get = (type: string): string => parts.find((p) => p.type === type)?.value ?? '';\n timeLine = `当前本地时间:${get('year')}-${get('month')}-${get('day')} ${get('hour')}:${get('minute')}(${parts.find((p) => p.type === 'timeZoneName')?.value ?? ''})。`;\n } catch {\n timeLine = `当前本地时间:${new Date(input.now).toISOString()}。`;\n }\n const elapsedLine = input.lastMessageTime === undefined\n ? ''\n : `\\n距本会话上一条消息已过去 ${formatElapsed(input.now - input.lastMessageTime)}。`;\n return timeLine + elapsedLine;\n}\n\n/** Timestamp of the session's last user/assistant/tool message event. */\nexport function lastMessageTime(session: HostSession): number | undefined {\n const events = sessionEvents(session);\n for (let i = events.length - 1; i >= 0; i--) {\n const e = events[i]!;\n const t = (e as { time?: number }).time;\n if (typeof t === 'number' && /user\\/message|assistant\\/message|tool\\/result/.test(e.type)) return t;\n }\n return undefined;\n}\n\n// ── per-session throttle state (survives restarts, like cursors.json) ───\n\nexport interface TimeInjectState {\n [sessionId: string]: number;\n}\n\nexport function timeInjectStatePath(dataDir: string): string {\n return path.join(dataDir, 'time-inject-state.json');\n}\n\nexport function loadTimeInjectState(guard: PathGuard, dataDir: string): TimeInjectState {\n try {\n const parsed = JSON.parse(fs.readFileSync(guard.assert(timeInjectStatePath(dataDir)), 'utf8')) as TimeInjectState;\n return parsed && typeof parsed === 'object' ? parsed : {};\n } catch {\n return {};\n }\n}\n\nexport function saveTimeInjectState(guard: PathGuard, dataDir: string, state: TimeInjectState): void {\n atomicWriteJsonSync(guard.assert(timeInjectStatePath(dataDir)), state);\n}\n\n// ── registration ─────────────────────────────────────────────────────────\n\nexport interface TimeInjectionOptions {\n /** Live-read on every gate check (UI-settable in M7d). */\n getTimeInjectMin(): number;\n timeZone?: string;\n paths: WorkspacePaths;\n logger: { info(msg: string, ...a: unknown[]): void; warn(msg: string, ...a: unknown[]): void };\n onError(error: unknown): void;\n /** Track B status line (§17.5): '' when the statusbar is off or the session\n * rides Track A. Receives the TURN-PINNED track (review #5) so the status\n * line and the system-prompt section can never split one turn. */\n getStatusLine?(session: HostSession, track: 'system-prompt' | 'pre-step'): string;\n /** Pin this turn's track at step===1 (before throttle logic) — every turn\n * start re-pins, so mid-turn capability flips land at the next boundary. */\n pinTrack(sessionId: string, session: HostSession): 'system-prompt' | 'pre-step';\n}\n\ninterface PreStepPayload {\n agent: { session: HostSession };\n step: number;\n signal?: { aborted?: boolean };\n}\n\ninterface EnterDecision {\n kind: string;\n messages: unknown[];\n}\n\n/**\n * Register the gated time injector on `ctx` (all agents, like the official\n * plugin it replaces). Returns the disposer conceptually owned by the caller's\n * fiber via `ctx.effect`.\n */\nexport function registerTimeInjection(\n ctx: {\n on(event: string, listener: (payload: PreStepPayload, next: () => Promise<unknown>) => Promise<unknown>, opts?: { prepend?: boolean }): unknown;\n },\n guard: PathGuard,\n dataDir: string,\n opts: TimeInjectionOptions,\n): void {\n const state = loadTimeInjectState(guard, dataDir);\n ctx.on('agent/pre-step', async (payload, next) => {\n const decision = await next() as EnterDecision;\n if (decision.kind === 'reject' || payload.signal?.aborted) return decision;\n const sessionId = payload.agent.session.id;\n const now = Date.now();\n // Turn-start track pin (review #5): re-pinned at EVERY step===1, before\n // any throttle logic, so the pin never goes stale across turns.\n const track = payload.step === 1 ? opts.pinTrack(sessionId, payload.agent.session) : undefined;\n const intervalMs = Math.max(0, opts.getTimeInjectMin()) * 60_000;\n if (!shouldInjectTime({\n step: payload.step,\n originIsInboxSplice: payload.step === 1 ? turnOriginIsInboxSplice(payload.agent.session) : false,\n lastInjectAt: state[sessionId] ?? 0,\n now,\n intervalMs,\n })) return decision;\n try {\n const { createUserMessage } = await import('@deepseek-ai/dsh-llm');\n let text = renderTimeText({\n now,\n timeZone: opts.timeZone,\n lastMessageTime: lastMessageTime(payload.agent.session),\n });\n // §17.5: Track B rides the same message with a trailing status line\n // (D21: status text itself never carries time words).\n if (opts.getStatusLine && track) {\n const statusLine = opts.getStatusLine(payload.agent.session, track);\n if (statusLine) text += `\\n${statusLine}`;\n }\n const message = createUserMessage({\n content: [{ type: 'text', text }],\n // 0.1.7 V4: producer-owned kind (retired generic 'plugin' is refused).\n source: { kind: 'heartbeat', plugin: 'heartbeat', form: 'snapshot', sections: [{ name: 'heartbeat-time', text }] },\n });\n state[sessionId] = now;\n saveTimeInjectState(guard, dataDir, state);\n appendAuditLine(opts.paths.logsDir + '/heartbeat.jsonl', {\n event: 'time_injected', sessionId, intervalMin: opts.getTimeInjectMin(),\n });\n return { ...decision, messages: [...decision.messages, message] };\n } catch (e) {\n opts.onError(e);\n return decision;\n }\n }, { prepend: true });\n}\n","// M7c: statusbar tracks (design doc §17.4–17.5, §17.7, D19/D21).\n//\n// One status store, two transports, picked per agent by model capability:\n// Track A — in-history-capable models: a dynamic system-prompt section\n// (`heartbeat:status`). The host projection layer dedupes (text\n// unchanged → zero commit) and appends changed prompts after the\n// cached history (KV-safe). Incapable/disabled → the text function\n// returns '' and the section drops out of the render entirely.\n// Track B — every other model: the pre-step time-injection message gains a\n// trailing status line (see time-inject.ts `getStatusLine`).\n// Track evidence: the session log's latest `request/context` event carries the\n// route's `systemPromptUpdate` mode. No evidence yet (fresh session) → Track B\n// (§17.7 default). Red line D21: status text NEVER contains time words.\n\nimport { appendAuditLine } from '../core/audit-log.js';\nimport { sessionEventCount, sessionEvents } from '../core/orchestrator.js';\nimport type { HostSession } from '../core/orchestrator.js';\nimport type { PathGuard } from '../core/path-guard.js';\nimport type { WorkspacePaths } from '../core/paths.js';\nimport { StatusReader } from './store.js';\nimport type { StatusState } from './store.js';\n\n// ── capability probe (review 2026-09-13 #1: incremental tail scan) ───\n// Cache keyed by \"how far we've scanned\", NOT by log length: the length grows\n// every step, so a length key would miss (and rescan the whole log backwards)\n// on every assembly. We remember the scan watermark and, on new events, read\n// only the tail (snapshotEvents(fromSeq) range) for NEW request/context rows.\ninterface CapabilityCache {\n /** Event count at the time of the last scan. */\n scannedUpTo: number;\n supported: boolean;\n}\nconst capabilityCache = new Map<string, CapabilityCache>();\n\nexport function supportsInHistory(session: HostSession): boolean {\n const key = session.id;\n const len = sessionEventCount(session);\n const hit = capabilityCache.get(key);\n if (hit && hit.scannedUpTo === len) return hit.supported;\n // Log shrank (session reset under the same id) → rescan from zero.\n const from = hit && len >= hit.scannedUpTo ? hit.scannedUpTo : 0;\n let supported = false;\n if (from !== 0 && hit) supported = hit.supported;\n const readTail = (fromSeq: number): { type: string; data?: unknown }[] => {\n if (typeof session.snapshotEvents === 'function') {\n try {\n const slice = session.snapshotEvents(fromSeq);\n if (Array.isArray(slice)) return slice;\n } catch { /* fall through to the legacy full read */ }\n }\n return sessionEvents(session).slice(fromSeq);\n };\n for (const e of readTail(from)) {\n if (e.type === 'request/context') {\n supported = (e.data as { systemPromptUpdate?: string } | undefined)?.systemPromptUpdate === 'in-history';\n }\n }\n capabilityCache.set(key, { scannedUpTo: len, supported });\n return supported;\n}\n\n/** Forget cached capability (test helper; also bounds memory across deletes). */\nexport function resetCapabilityCache(): void {\n capabilityCache.clear();\n}\n\nconst SCENE_LABELS: Record<StatusState['scene'], string> = {\n 'quiet-hours': '静默时段,世界睡了',\n 'just-spoke': '刚去和你说过话',\n wandering: '正在闲逛看新东西',\n busy: '看到你在忙,不去打扰',\n present: '在场待着',\n away: '你不在,自己待着',\n};\n\n/** Render the one-line status text (D21 red line: zero time words).\n *\n * RENDER PURITY RED LINE (2026-09-13 review): this MUST stay a pure function\n * of the status state — no clock reads, no counters, no per-call variability.\n * The host projection already refuses to commit identical text (project()\n * emits no updates when the rendered prompt is byte-identical), so purity here\n * is what keeps the in-history append cadence at \"per scene change\", not \"per\n * step\". Any field varying faster than the scene belongs in the time\n * injection, never here.\n *\n * NOTE POLICY (review 2026-09-13 #3): `withNote: false` for the Track A\n * section — the scene label is a constant-table mapping (maximally stable),\n * while the note is engine-room free text that can differ every beat and\n * would defeat the host's byte-dedupe. The note is for the UI and the Track B\n * pre-step line (where each message is small and already event-shaped). */\nexport function renderStatusText(\n status: StatusState | null,\n opts?: { withNote?: boolean },\n): string {\n if (!status) return '';\n const label = SCENE_LABELS[status.scene] ?? '在场';\n const note = opts?.withNote === false ? '' : status.note ? `——${status.note}` : '';\n return `心跳此刻:${label}${note}。`;\n}\n\n// ── turn-pinned track decision (2026-09-13 review #5) ────────────────────\n// The track must be decided ONCE per turn, at its start (step===1 in the\n// pre-step listener), and both transports read that pin. Otherwise a\n// capability flip mid-turn (e.g. the very first request of a fresh capable\n// session lands `request/context` after step 1) splits the turn: the pre-step\n// status line already in history AND the section activating from the next\n// step. A pin updates only at turn starts, so a flip always lands cleanly at\n// the next turn boundary.\nconst pinnedTrack = new Map<string, 'system-prompt' | 'pre-step'>();\n\n/** Pin and return this turn's track. Call from the pre-step listener at\n * step===1 (before any throttle logic) — every turn start re-pins. */\nexport function pinTrack(sessionId: string, session: HostSession): 'system-prompt' | 'pre-step' {\n const track = trackFor(session);\n pinnedTrack.set(sessionId, track);\n return track;\n}\n\n/** The pinned track when one exists for this session, else the live probe\n * (fallback for assemblies that somehow precede any turn-start pin). */\nexport function pinnedTrackFor(sessionId: string, session: HostSession): 'system-prompt' | 'pre-step' {\n return pinnedTrack.get(sessionId) ?? trackFor(session);\n}\n\nexport function resetPins(): void {\n pinnedTrack.clear();\n}\n\n/** Track-change auditor: emits `statusbar_track` only when an agent's track\n * actually flips (bounded spam; called from the two render paths). */\nconst lastTrack = new Map<string, string>();\n\nexport function noteTrack(auditFile: string, sessionId: string, track: 'system-prompt' | 'pre-step' | 'off'): void {\n if (lastTrack.get(sessionId) === track) return;\n lastTrack.set(sessionId, track);\n try {\n appendAuditLine(auditFile, { event: 'statusbar_track', sessionId, track });\n } catch { /* audit failure must not break rendering */ }\n}\n\n/** Forget a session's track memo (test helper). */\nexport function resetTrackMemo(): void {\n lastTrack.clear();\n}\n\n/** Which transport serves this session right now (§17.7: no evidence yet →\n * Track B; the section flip happens once a request/context event lands). */\nexport function trackFor(session: HostSession): 'system-prompt' | 'pre-step' {\n return supportsInHistory(session) ? 'system-prompt' : 'pre-step';\n}\n\n/** Register the Track A section on the host systemPrompt service. The text\n * provider returns '' (section drops from the render) when the statusbar is\n * off, the agent is unknown, or the session rides Track B. */\nexport function registerStatusbarSection(\n ctx: {\n inject(services: string[], callback: (scoped: unknown) => void): void;\n },\n guard: PathGuard,\n paths: WorkspacePaths,\n opts: { enabled(): boolean; reader: StatusReader },\n): void {\n ctx.inject(['systemPrompt'], (scoped) => {\n const spCtx = scoped as {\n systemPrompt?: {\n section(def: { name: string; order: number; text: string | ((context: unknown) => string) }): unknown;\n };\n effect(fn: () => unknown, label?: string): () => void;\n logger?: { warn(msg: string, ...a: unknown[]): void };\n };\n const section = spCtx.systemPrompt?.section;\n if (typeof section !== 'function') {\n spCtx.logger?.warn('heartbeat: systemPrompt service has no section API, statusbar Track A unavailable');\n return;\n }\n spCtx.effect(() => section.call(spCtx.systemPrompt, {\n name: 'heartbeat:status',\n order: 5000, // between the persona prefix (0) and the harness block (10000)\n text: (context: unknown) => {\n if (!opts.enabled()) {\n noteTrack(paths.logsDir + '/heartbeat.jsonl', (context as { agent?: { session: HostSession } }).agent?.session.id ?? '(none)', 'off');\n return '';\n }\n const agent = (context as { agent?: { session?: HostSession } }).agent;\n if (!agent?.session) return '';\n // Read the TURN-PINNED track (2026-09-13 review #5): a mid-turn\n // capability flip must not activate the section inside the same turn\n // whose pre-step status line already went out on Track B.\n const track = pinnedTrackFor(agent.session.id, agent.session);\n noteTrack(paths.logsDir + '/heartbeat.jsonl', agent.session.id, track);\n if (track !== 'system-prompt') return '';\n return renderStatusText(opts.reader.read(guard, paths), { withNote: false });\n },\n }), 'heartbeat: statusbar section');\n });\n}\n","// The heartbeat agent preset, as a runtime registration (issue #2, 2026-10-10).\n//\n// 0.1.7+ mounts presets from the profile COMPOSITION: a row named\n// `@deepseek-ai/dsh-agent-preset` whose `config` is the definition. That row\n// makes the PROFILE resolve the package — and `@deepseek-ai/dsh-agent-preset`\n// is thin (it only forwards its config to `agentPresets.register`), but its\n// peer closure contains `cordis-plugin-loader` / `cordis-plugin-include` /\n// `cordis-plugin-group`, i.e. the loading machinery itself. So a profile that\n// cannot resolve it fails the WHOLE plugin tree (\"plugin tree failed to load\"\n// on 0.1.5), and one that satisfies it by hand double-instances the machinery\n// (\"prompt section deployment:persona-prefix is already registered\", every\n// session then refuses to resume). Both were reported with reproductions.\n//\n// The registry exposes `register(definition)` for exactly this case — its\n// docstring: \"Parsed configuration supplied by the declaring plugin\" — so the\n// plugin now registers its own preset at runtime and the bundle patch carries\n// no host-package reference at all. The definition below is the same content\n// the composition used to hold (and the same as\n// `assets/presets/heartbeat/agent.cordis.yml`, which older hosts still read\n// off the filesystem).\n//\n// Deliberately NO persona row: the deployment persona (soul card) plus the\n// heartbeat prompt already cover it, and a \"You are a coding agent\" line would\n// overwrite the persona.\n\n/** One child row of the preset, in Cordis entry-list shape. */\nexport interface PresetEntry {\n readonly id?: string;\n readonly name?: string;\n /** `cordis:group` marker: this row nests `config` as child entries. */\n readonly group?: boolean;\n /** Isolation flags a group row may carry (kept verbatim). */\n readonly isolate?: Record<string, unknown>;\n readonly config?: unknown;\n}\n\n/** Identity, display fields and child plugins of one preset. */\nexport interface HeartbeatPresetDefinition {\n readonly id: string;\n readonly name: string;\n readonly description: string;\n readonly order: number;\n readonly plugins: readonly PresetEntry[];\n}\n\n/**\n * The bundled preset definition for `id`.\n *\n * Content = `assets/presets/heartbeat/agent.cordis.yml`: a compaction group\n * (basic + command-compact + tool-result-pruner) plus the single model-facing\n * tool `tool-web` with `fetch: false` (web_search only — no page fetching,\n * no shell, no filesystem, no subagents).\n */\nexport function heartbeatPresetDefinition(id: string = 'heartbeat'): HeartbeatPresetDefinition {\n return {\n id,\n name: '心跳模式',\n description: '心跳 agent 专用:仅 web_search + 上下文折叠;无 shell、无文件、无子代理。',\n order: 20,\n plugins: [\n {\n id: 'compaction',\n name: 'cordis:group',\n group: true,\n isolate: { compaction: true, toolResultPruner: true },\n config: [\n { id: 'compaction-basic', name: '@deepseek-ai/dsh-compaction-basic' },\n { id: 'command-compact', name: '@deepseek-ai/dsh-command-compact' },\n {\n id: 'tool-result-pruner',\n name: '@deepseek-ai/dsh-compaction-tool-result-pruner',\n config: { thresholdChars: 8192, headChars: 4096, tailChars: 1024 },\n },\n ],\n },\n { id: 'tool-web', name: '@deepseek-ai/dsh-tool-web', config: { fetch: false, searchTimeoutMs: 60000 } },\n ],\n };\n}\n\n/** Registration result, for the audit line and the log. */\nexport type PresetRegisterAction = 'registered' | 'skipped-disabled' | 'skipped-no-api' | 'error';\n\nexport interface PresetRegisterResult {\n action: PresetRegisterAction;\n id: string;\n detail?: string;\n /**\n * HB-17 (2026-10-17): undo hook returned by the registry. The caller must\n * run it on dispose — otherwise a plugin reload leaves the preset behind\n * (and the next registration double-mounts it).\n */\n disposer?: () => Promise<void>;\n}\n\n/** Minimal shape of the registry we call (`AgentPresetRegistry.register`). */\ninterface RegistrarLike {\n register?(definition: unknown): Promise<() => Promise<void>> | (() => Promise<void>);\n}\n\n/**\n * Register the bundled preset at runtime, tolerating every missing-API case.\n *\n * A host whose registry has no `register` (0.1.7-alpha.1 and other partial\n * builds) or no `agentPresets` service at all (pre-0.1.7) must NOT take the\n * host down: the heartbeat simply runs without its preset — degraded (no\n * `web_search`), which the acquire path already audits as `preset=no-api`.\n *\n * @param service The resolved `agentPresets` service, if any.\n * @param id Preset identity to register.\n * @param enabled False when the operator manages the preset themselves.\n * @returns What happened, for the audit line.\n */\nexport async function registerHeartbeatPreset(\n service: unknown,\n id: string = 'heartbeat',\n enabled: boolean = true,\n): Promise<PresetRegisterResult> {\n if (!enabled) return { action: 'skipped-disabled', id };\n const registrar = service as RegistrarLike | undefined;\n if (registrar === undefined || registrar === null || typeof registrar.register !== 'function') {\n return { action: 'skipped-no-api', id };\n }\n try {\n const disposer = await registrar.register(heartbeatPresetDefinition(id));\n return typeof disposer === 'function'\n ? { action: 'registered', id, disposer }\n : { action: 'registered', id };\n } catch (e) {\n return { action: 'error', id, detail: String(e).slice(0, 200) };\n }\n}\n","// Ledger as a MODEL TOOL (v1.8.0): the chat agents can record / list / check\n// off ledger items themselves, so a todo mentioned in conversation lands in\n// the shared ledger without the user commanding anyone to \"write it down\".\n//\n// Registration is host-side (`ToolRuntime.register`, 0.2.0-rc.2 verified):\n// the definition is built as a PLAIN OBJECT here — `parameters` is a raw JSON\n// Schema per ToolSchema (dsh-llm), so we do not import `defineTool` and the\n// module carries zero new runtime dependencies. `ToolRuntime.register` is the\n// only host entry point (looked up dynamically by the caller); on a host\n// without it the caller audits and moves on, nothing else is affected.\n//\n// Scope: registration happens through the plugin's ROOT context, which lands\n// the tool in the GLOBAL layer — every agent sees it. The engine room is\n// unaffected: its preset restrict({allow:['web_search']}) masks global tools,\n// so the heartbeat's own turns cannot touch the ledger.\n\nimport {\n appendEntry,\n markDone,\n readLedger,\n scanPending,\n type LedgerEntry,\n} from './ledger.js';\nimport type { PathGuard } from '../core/path-guard.js';\n\n/** Minimal structural typing of the host shape — we deliberately do not\n * depend on @deepseek-ai/dsh-tools at runtime. */\nexport interface RegisterableToolRuntime {\n register(definition: unknown): () => void;\n}\n\ninterface LedgerToolArgs {\n action?: unknown;\n text?: unknown;\n key?: unknown;\n}\n\nconst MAX_TEXT = 120;\n\nfunction clean(v: unknown): string {\n return String(v ?? '').replace(/\\s+/g, ' ').trim().slice(0, MAX_TEXT);\n}\n\nfunction fmtEntry(e: LedgerEntry): string {\n return `#${e.id} [${e.status}] ${e.date} ${e.text}`;\n}\n\nexport function buildLedgerTool(guard: PathGuard, file: string): unknown {\n return {\n name: 'ledger',\n description:\n '共享账本工具(心跳插件的待办与事项记录)。当用户提到计划、待办、承诺、想做的事,' +\n '或者某件事已经完成时,主动调用本工具登记或勾掉——不需要等用户明确说\"记一下\"。' +\n 'action=add 登记新事项(text 必填);action=list 查看当前未完成事项;action=done 勾掉一条(key 为 #id 或文本子串)。',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['add', 'list', 'done'], description: 'add=登记,list=查未完成,done=勾掉' },\n text: { type: 'string', description: 'action=add 时必填:事项内容(一句话)' },\n key: { type: 'string', description: 'action=done 时必填:#id 或事项文本的唯一子串' },\n },\n required: ['action'],\n additionalProperties: false,\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n ok: { type: 'boolean' },\n message: { type: 'string' },\n },\n required: ['ok', 'message'],\n additionalProperties: false,\n },\n render: (_args: unknown, value: unknown) => {\n const v = value as { message?: string };\n return [{ type: 'text', text: String(v.message ?? '') }];\n },\n },\n timeoutMs: 5000,\n // Ledger writes go through read-modify-write on one file; never parallel.\n isConcurrencySafe: () => false,\n async execute(args: unknown): Promise<unknown> {\n const a = (args ?? {}) as LedgerToolArgs;\n const action = String(a.action ?? '');\n if (action === 'add') {\n const text = clean(a.text);\n if (!text) return { ok: false, message: 'add 需要非空 text' };\n const e = appendEntry(guard, file, text);\n return { ok: true, message: `已登记 ${fmtEntry(e)}` };\n }\n if (action === 'done') {\n const key = clean(a.key);\n if (!key) return { ok: false, message: 'done 需要 key(#id 或文本子串)' };\n const e = markDone(guard, file, key);\n if (!e) return { ok: false, message: `没有找到匹配「${key}」的未完成事项(先用 list 查)` };\n return { ok: true, message: `已完成 ${fmtEntry(e)}` };\n }\n if (action === 'list') {\n const items = scanPending(guard, file).map(fmtEntry);\n return { ok: true, message: items.length > 0 ? `当前未完成 ${items.length} 项:\\n${items.join('\\n')}` : '账本里没有未完成事项' };\n }\n // Unsupported action shapes should be rare (schema-enforced); stay total.\n const total = readLedger(guard, file).entries.length;\n return { ok: false, message: `未知 action,账本共 ${total} 条` };\n },\n };\n}\n","// 心事匣 as a MODEL TOOL (v2.0): the chat agents can leave ONE note for the\n// next heartbeat, look at it, or let it go — the same host-side pattern as the\n// ledger tool (see ledger/tool.ts:1-15): the definition is a PLAIN OBJECT built\n// here, `parameters` is a raw JSON Schema, and nothing imports\n// @deepseek-ai/dsh-tools, so this module keeps zero new runtime dependencies.\n//\n// Registration goes through the plugin's ROOT context, which lands the tool in\n// the GLOBAL layer — every chat agent sees it. The engine room never does: its\n// preset restrict({allow:['web_search']}) masks global tools, and it must stay\n// that way. The note is the persona's own private line; the engine room only\n// ever sees it indirectly, as text inside the delivery package it never builds.\n//\n// Scope note: the note is one slot, not a queue. `write` replaces — and that\n// replacement is the whole mechanism by which the previous note is let go, so\n// the tool deliberately has no \"append\".\n\nimport type { PathGuard } from '../core/path-guard.js';\nimport { clearNote, notepadView, readNotepad, writeNote, type NotepadView } from './store.js';\n\ninterface NotepadToolArgs {\n action?: unknown;\n text?: unknown;\n}\n\n/** One line, deliberately: this is a HOOK for the next self to re-expand, not a\n * record. 120 (the ledger's per-item cap) is the convention here; the little\n * extra room is because a note is a whole thought, where a ledger item is a\n * task title. */\nconst MAX_NOTE_CHARS = 160;\n\nfunction clean(v: unknown): string {\n return String(v ?? '').replace(/\\s+/g, ' ').trim().slice(0, MAX_NOTE_CHARS);\n}\n\nfunction fmtMinutes(m: number): string {\n if (m < 1) return '不到 1 分钟';\n if (m < 60) return `${m} 分钟`;\n const h = Math.floor(m / 60);\n const rest = m % 60;\n return rest > 0 ? `${h} 小时 ${rest} 分` : `${h} 小时`;\n}\n\n/** Same phrasing the delivery package uses (material.ts notepadLines) so the\n * note reads the same wherever she meets it. */\nfunction fmtView(v: NotepadView): string {\n const beats = v.beatsAgo === 0 ? '本跳' : `${v.beatsAgo} 跳前`;\n const wakes = v.wakesAgo === 0 ? '还没被叫醒过' : `期间被叫醒过 ${v.wakesAgo} 次`;\n return `心事匣里现在有:${v.text}\\n(留于${beats},已搁 ${fmtMinutes(v.sinceMinutes)},${wakes})`;\n}\n\nexport function buildNotepadTool(guard: PathGuard, file: string): unknown {\n return {\n name: 'notepad',\n description:\n '心事匣(心跳插件的\"留给下一跳的自己\"便签)。只有一格:写下新的就盖掉旧的。' +\n '当你有话想留到下次心跳再说、或者有一件放不下的事时,用 action=write 留下一句引子——' +\n '不要写整段,下次跳由那时的你重新展开。想留住原来的就照原样再写一遍(字样一致算保留,' +\n '它的年龄不会重算);写别的就是换掉它。action=read 看现在格子里是什么;action=clear 主动放掉。' +\n '投递包读过之后,什么都不做它就下一跳没了。留不留都行,没话就空着。',\n parameters: {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['write', 'read', 'clear'],\n description: 'write=留一句(盖掉旧的),read=看现在是什么,clear=主动放掉',\n },\n text: {\n type: 'string',\n description: 'action=write 时必填:一句引子(不是整段心事,下次跳你自己重新展开)',\n },\n },\n required: ['action'],\n additionalProperties: false,\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n ok: { type: 'boolean' },\n message: { type: 'string' },\n },\n required: ['ok', 'message'],\n additionalProperties: false,\n },\n render: (_args: unknown, value: unknown) => {\n const v = value as { message?: string };\n return [{ type: 'text', text: String(v.message ?? '') }];\n },\n },\n timeoutMs: 5000,\n // Read-modify-write on one file, and the note's lifecycle depends on it.\n isConcurrencySafe: () => false,\n async execute(args: unknown): Promise<unknown> {\n const a = (args ?? {}) as NotepadToolArgs;\n const action = String(a.action ?? '');\n try {\n if (action === 'write') {\n const text = clean(a.text);\n if (!text) return { ok: false, message: 'write 需要非空 text(一句引子)' };\n const { note, kept } = writeNote(guard, file, text);\n return {\n ok: true,\n message: kept ? `还惦记着:${note.text}(年龄不变)` : `已留下心事:${note.text}`,\n };\n }\n if (action === 'read') {\n const v = notepadView(readNotepad(guard, file));\n return { ok: true, message: v ? fmtView(v) : '心事匣是空的' };\n }\n if (action === 'clear') {\n const prev = clearNote(guard, file);\n return prev\n ? { ok: true, message: `已放掉:${prev.text}` }\n : { ok: true, message: '心事匣本来就是空的' };\n }\n // Unsupported action shapes should be rare (schema-enforced); stay total.\n return { ok: false, message: `未知 action(${action || '空'}),只认 write / read / clear` };\n } catch (e) {\n // A damaged container throws on read (store.ts header). Never let that\n // surface as a tool crash; the host would show it as a tool failure.\n return { ok: false, message: `心事匣读写失败:${String(e).slice(0, 120)}` };\n }\n },\n };\n}\n","// Excerpt book as a MODEL TOOL (v2.0.0): the agent can keep a line the moment it\n// lands, instead of losing it because there is nowhere to put it.\n//\n// Same registration shape as the ledger tool: a PLAIN OBJECT, no import of\n// @deepseek-ai/dsh-tools, registered through the plugin's ROOT context so it\n// lands in the GLOBAL layer every chat agent sees. The engine room cannot\n// reach it (its preset restrict({allow:['web_search']}) masks global tools).\n\nimport { appendExcerpt, readExcerpts, recentExcerpts, removeExcerpt, type ExcerptEntry } from './excerpt.js';\nimport type { PathGuard } from '../core/path-guard.js';\n\ninterface ExcerptToolArgs {\n action?: unknown;\n text?: unknown;\n key?: unknown;\n}\n\nconst MAX_TEXT = 300;\nconst LIST_LIMIT = 10;\n\nfunction clean(v: unknown): string {\n return String(v ?? '').replace(/\\s+/g, ' ').trim();\n}\n\nfunction fmtEntry(e: ExcerptEntry): string {\n return `#${e.id} ${e.date} ${e.time} ${e.text}`;\n}\n\nexport function buildExcerptTool(guard: PathGuard, file: string): unknown {\n return {\n name: 'excerpt',\n description:\n '你自己的摘抄本:留句子和小事的地方。想说\"这句我要记下来\"的时候用——他说过的话、看到的句子、' +\n '心里过了一下的小事。它和账本、心事匣都不一样:账本记的是待办和承诺(会勾掉),心事匣是留给下一跳的一句引子(只有一格、会被盖掉),' +\n '摘抄本只增不减,除非你主动 remove。写的时候把话原样留下,不用解释。' +\n 'action=add 抄一条(text 必填);action=list 翻最近十条;action=remove 抹掉一条(key 为 #id 或正文里的唯一子串)。',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['add', 'list', 'remove'], description: 'add=抄一条,list=翻最近十条,remove=抹掉一条' },\n text: { type: 'string', description: 'action=add 时必填:要留下的那句话或那件小事' },\n key: { type: 'string', description: 'action=remove 时必填:#id 或正文里的唯一子串' },\n },\n required: ['action'],\n additionalProperties: false,\n },\n output: {\n schema: {\n type: 'object',\n properties: {\n ok: { type: 'boolean' },\n message: { type: 'string' },\n },\n required: ['ok', 'message'],\n additionalProperties: false,\n },\n render: (_args: unknown, value: unknown) => {\n const v = value as { message?: string };\n return [{ type: 'text', text: String(v.message ?? '') }];\n },\n },\n timeoutMs: 5000,\n // Read-modify-write on one file; never parallel.\n isConcurrencySafe: () => false,\n async execute(args: unknown): Promise<unknown> {\n const a = (args ?? {}) as ExcerptToolArgs;\n const action = String(a.action ?? '');\n if (action === 'add') {\n const text = clean(a.text).slice(0, MAX_TEXT);\n if (!text) return { ok: false, message: 'add 需要非空 text' };\n const e = appendExcerpt(guard, file, text);\n return { ok: true, message: `已抄下 ${fmtEntry(e)}` };\n }\n if (action === 'remove') {\n const key = clean(a.key);\n if (!key) return { ok: false, message: 'remove 需要 key(#id 或正文里的唯一子串)' };\n const e = removeExcerpt(guard, file, key);\n if (!e) return { ok: false, message: `摘抄本里没有匹配「${key}」的一条(先用 list 翻)` };\n return { ok: true, message: `已抹掉 ${fmtEntry(e)}` };\n }\n if (action === 'list') {\n const total = readExcerpts(guard, file).entries.length;\n if (total === 0) return { ok: true, message: '摘抄本还是空的' };\n const items = recentExcerpts(guard, file, LIST_LIMIT).map(fmtEntry);\n return { ok: true, message: `摘抄本共 ${total} 条,最近 ${items.length} 条:\\n${items.join('\\n')}` };\n }\n // Unsupported action shapes should be rare (schema-enforced); stay total.\n const total = readExcerpts(guard, file).entries.length;\n return { ok: false, message: `未知 action,摘抄本共 ${total} 条` };\n },\n };\n}\n"],"mappings":"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","names":["fs","path","fs","path","fs","path","path","fs","fs","path","getRuntime","clean","MAX_TEXT","clean","fmtEntry","total","result","name"]}
|