@klarkxy/dsh-deep-view 0.1.0 → 0.2.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/lib/answer-text.d.ts +15 -0
- package/lib/answer-text.js +110 -0
- package/lib/answer-text.js.map +1 -0
- package/lib/answers.d.ts +49 -0
- package/lib/answers.js +60 -0
- package/lib/answers.js.map +1 -0
- package/lib/client.inner.cjs +362 -12
- package/lib/client.inner.cjs.map +1 -1
- package/lib/client.js +362 -12
- package/lib/contracts.d.ts +2 -98
- package/lib/contracts.js +2 -1
- package/lib/contracts.js.map +1 -1
- package/lib/contracts2.d.ts +103 -0
- package/lib/copy.d.ts +37 -0
- package/lib/copy.js +69 -0
- package/lib/copy.js.map +1 -0
- package/lib/core.d.ts +57 -0
- package/lib/core.js +2 -0
- package/lib/core2.js +1079 -0
- package/lib/core2.js.map +1 -0
- package/lib/index.d.ts +35 -4
- package/lib/index.js +847 -1130
- package/lib/index.js.map +1 -1
- package/lib/widget.d.ts +71 -0
- package/lib/widget.js +1365 -0
- package/lib/widget.js.map +1 -0
- package/package.json +28 -3
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["fail","isRecord","isRecord"],"sources":["../../dsh-plugin-kit/src/host-rpc.ts","../src/core/formula.js","../src/core/views.js","../src/answer-text.ts","../src/index.ts"],"sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { RpcResult } from './contracts.ts'\n\nexport interface HostRpcContext {\n webServer: { register(route: { kind: 'prefix'; path: string; handler(req: IncomingMessage, res: ServerResponse): void | Promise<void> }): () => void }\n connection: { requestRejection?: (request: IncomingMessage) => number | undefined }\n}\n\ntype Rejection = { status: number; body?: string }\n\nexport interface HostRpcTransportOptions {\n maxBodyBytes?: number\n isEndpoint?: (endpoint: string) => boolean\n caseInsensitiveContentType?: boolean\n emptyBodyAsNull?: boolean\n beforeBody?: (request: IncomingMessage, endpoint: string) => Rejection | undefined\n errorBody?: (status: number, error?: unknown) => string | undefined\n}\n\nexport interface HostRpcOptions extends HostRpcTransportOptions {\n requirePayload?: boolean\n}\n\n/** The shared authenticated HTTP boundary. Each plugin still owns its RPC envelope semantics. */\nexport function registerHostRpcTransport(\n ctx: HostRpcContext,\n channel: string,\n dispatch: (endpoint: string, body: unknown, signal: AbortSignal, response: ServerResponse) => void | Promise<void>,\n options: HostRpcTransportOptions = {},\n): () => void {\n const bodyLimit = options.maxBodyBytes ?? 64 * 1024\n if (!Number.isSafeInteger(bodyLimit) || bodyLimit <= 0) throw new Error('Invalid RPC body limit')\n const isEndpoint = options.isEndpoint ?? ((endpoint: string) => /^[a-z.]+$/.test(endpoint))\n return ctx.webServer.register({ kind: 'prefix', path: channel, handler: async (req, res) => {\n const reject = (status: number, error?: unknown, override?: string) => {\n if (res.destroyed) return\n if (status === 413) res.writeHead(status, { connection: 'close' })\n else res.writeHead(status)\n res.end(override ?? options.errorBody?.(status, error) ?? (status === 500 ? 'rpc request failed' : ''))\n }\n try {\n // Host admission always runs before plugin-specific checks or body reads.\n if (typeof ctx.connection.requestRejection !== 'function') { reject(503); return }\n const rejection = ctx.connection.requestRejection(req)\n if (rejection !== undefined) { reject(rejection); return }\n const pathname = new URL(req.url ?? '/', 'http://dsh.internal').pathname\n const endpoint = pathname.startsWith(`${channel}/`) ? pathname.slice(channel.length + 1) : ''\n if (req.method !== 'POST' || !isEndpoint(endpoint)) { reject(404); return }\n const contentType = String(req.headers['content-type'] ?? '').split(';', 1)[0]?.trim()\n if ((options.caseInsensitiveContentType ? contentType.toLowerCase() : contentType) !== 'application/json') {\n reject(415); return\n }\n const guarded = options.beforeBody?.(req, endpoint)\n if (guarded) { reject(guarded.status, undefined, guarded.body); return }\n\n const controller = new AbortController()\n res.on('close', () => { if (!res.writableEnded) controller.abort() })\n const chunks: Buffer[] = []\n let size = 0\n for await (const chunk of req) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n size += buffer.length\n if (size > bodyLimit) { reject(413); req.destroy(); return }\n chunks.push(buffer)\n }\n let body: unknown\n try { body = JSON.parse(Buffer.concat(chunks).toString('utf8') || (options.emptyBodyAsNull ? 'null' : '')) }\n catch { reject(400); return }\n await dispatch(endpoint, body, controller.signal, res)\n } catch (error) {\n reject(500, error)\n }\n } })\n}\n\n/** Write the native Connection response envelope after a plugin has handled a request. */\nexport function sendHostRpcResponse(response: ServerResponse, rpcId: string, result: unknown, noStore = true): void {\n if (response.destroyed) return\n response.writeHead(200, { 'content-type': 'application/json', ...(noStore ? { 'cache-control': 'no-store' } : {}) })\n response.end(JSON.stringify({ type: 'server-response', rpcId, result }))\n}\n\n/** Safe host RPC registration. Missing requestRejection fails closed. */\nexport function registerHostRpc<R extends RpcResult = RpcResult>(\n ctx: HostRpcContext,\n channel: string,\n call: (endpoint: string, payload: unknown, signal: AbortSignal) => Promise<R>,\n options: HostRpcOptions = {},\n): () => void {\n return registerHostRpcTransport(ctx, channel, async (endpoint, body, signal, res) => {\n if (!body || typeof body !== 'object' || Array.isArray(body)) { res.writeHead(400); res.end(); return }\n const request = body as Record<string, unknown>\n if (request.type !== 'client-request' || request.method !== endpoint || typeof request.rpcId !== 'string'\n || (options.requirePayload && !Object.hasOwn(request, 'payload'))) {\n res.writeHead(400); res.end(); return\n }\n const raw = await call(endpoint, request.payload, signal)\n const result = raw.ok ? raw : { ...raw, error: { details: {}, ...raw.error } }\n sendHostRpcResponse(res, request.rpcId, result)\n }, options)\n}\n","// Adapted from deep-view/src/core/formula.js (deep-view 0.1.0, Apache-2.0).\n// Kept as the same bounded expression interpreter: no eval, property access,\n// assignment or loops. The DSH migration preserves its grammar and error model.\n// It reads names and calls a fixed set of functions without reaching the page.\n\nconst FUNCTIONS = {\n min: { args: [1, Infinity], run: (...values) => Math.min(...values.map(num)) },\n max: { args: [1, Infinity], run: (...values) => Math.max(...values.map(num)) },\n abs: { args: [1, 1], run: value => Math.abs(num(value)) },\n floor: { args: [1, 1], run: value => Math.floor(num(value)) },\n ceil: { args: [1, 1], run: value => Math.ceil(num(value)) },\n sqrt: { args: [1, 1], run: value => Math.sqrt(num(value)) },\n pow: { args: [2, 2], run: (base, power) => num(base) ** num(power) },\n round: { args: [1, 2], run: (value, digits = 0) => roundTo(num(value), digitsOf(digits)) },\n clamp: { args: [3, 3], run: (value, low, high) => Math.min(Math.max(num(value), num(low)), num(high)) },\n fixed: { args: [1, 2], run: (value, digits = 0) => roundTo(num(value), digitsOf(digits)).toFixed(digitsOf(digits)) },\n format: { args: [1, 2], run: (value, digits = 0) => grouped(num(value), digitsOf(digits)) },\n percent: { args: [1, 2], run: (value, digits = 0) => `${grouped(num(value) * 100, digitsOf(digits))}%` },\n}\nexport const FORMULA_FUNCTIONS = Object.keys(FUNCTIONS)\nconst CONSTANTS = new Map([['true', true], ['false', false]])\n// Nesting deeper than this is no calculation a view needs; the parser recurses per level.\nconst MAX_NESTING = 64\n\nclass FormulaError extends Error {}\nconst fail = (message) => { throw new FormulaError(message) }\n\nfunction num(value) {\n if (typeof value === 'number') return value\n if (typeof value === 'boolean') return value ? 1 : 0\n const parsed = Number(value)\n if (typeof value === 'string' && value.trim() !== '' && !Number.isNaN(parsed)) return parsed\n return fail(`${JSON.stringify(value)} is not a number`)\n}\nconst digitsOf = (digits) => {\n const value = num(digits)\n if (!Number.isInteger(value) || value < 0 || value > 10) fail('digits must be a whole number from 0 to 10')\n return value\n}\nconst roundTo = (value, digits) => {\n const scale = 10 ** digits\n return Math.round(value * scale) / scale\n}\nfunction grouped(value, digits) {\n if (!Number.isFinite(value)) return String(value)\n const [whole, part] = Math.abs(roundTo(value, digits)).toFixed(digits).split('.')\n const sign = value < 0 && Number(whole + (part ?? '')) !== 0 ? '-' : ''\n return `${sign}${whole.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')}${part ? `.${part}` : ''}`\n}\n\n// -------------------------------------------------------------------------\n// Tokens and parsing\n\nconst IDENT = /^[A-Za-z_][A-Za-z0-9_]*$/\nexport const isName = value => typeof value === 'string' && IDENT.test(value)\nconst OPERATORS = ['==', '!=', '<=', '>=', '&&', '||', '+', '-', '*', '/', '%', '<', '>', '!', '?', ':', '(', ')', ',']\n\nfunction tokenize(source) {\n const tokens = []\n let at = 0\n while (at < source.length) {\n const char = source[at]\n if (/\\s/.test(char)) { at += 1; continue }\n const number = /^(?:\\d+\\.?\\d*|\\.\\d+)(?:[eE][+-]?\\d+)?/.exec(source.slice(at))\n if (number) { tokens.push({ kind: 'number', value: Number(number[0]), at }); at += number[0].length; continue }\n const name = /^[A-Za-z_][A-Za-z0-9_]*/.exec(source.slice(at))\n if (name) { tokens.push({ kind: 'name', value: name[0], at }); at += name[0].length; continue }\n if (char === '\"' || char === '\\'') {\n let end = at + 1\n let text = ''\n while (end < source.length && source[end] !== char) {\n if (source[end] === '\\\\' && end + 1 < source.length) { text += source[end + 1]; end += 2; continue }\n text += source[end]\n end += 1\n }\n if (end >= source.length) fail(`unclosed string at ${at + 1}`)\n tokens.push({ kind: 'string', value: text, at })\n at = end + 1\n continue\n }\n const operator = OPERATORS.find(op => source.startsWith(op, at))\n if (operator === undefined) fail(`unexpected ${JSON.stringify(char)} at ${at + 1}`)\n tokens.push({ kind: 'op', value: operator, at })\n at += operator.length\n }\n return tokens\n}\n\nconst BINARY = [['||'], ['&&'], ['==', '!='], ['<', '<=', '>', '>='], ['+', '-'], ['*', '/', '%']]\n\nfunction parse(source) {\n const tokens = tokenize(source)\n let index = 0\n let depth = 0\n const peek = () => tokens[index]\n const isOp = value => peek()?.kind === 'op' && peek().value === value\n const expect = (value) => {\n if (!isOp(value)) fail(peek() ? `expected \"${value}\" at ${peek().at + 1}` : `expected \"${value}\" at the end`)\n index += 1\n }\n const nest = (read) => {\n depth += 1\n if (depth > MAX_NESTING) fail(`nested more than ${MAX_NESTING} levels`)\n const node = read()\n depth -= 1\n return node\n }\n const ternary = () => nest(() => {\n const test = binary(0)\n if (!isOp('?')) return test\n index += 1\n const yes = ternary()\n expect(':')\n return { type: 'if', test, yes, no: ternary() }\n })\n const binary = (level) => {\n if (level === BINARY.length) return unary()\n let left = binary(level + 1)\n while (peek()?.kind === 'op' && BINARY[level].includes(peek().value)) {\n const op = peek().value\n index += 1\n left = { type: 'binary', op, left, right: binary(level + 1) }\n }\n return left\n }\n const unary = () => {\n if (isOp('-') || isOp('!') || isOp('+')) {\n const op = peek().value\n index += 1\n return nest(() => ({ type: 'unary', op, value: unary() }))\n }\n return primary()\n }\n const primary = () => {\n const token = peek()\n if (token === undefined) fail('the formula ends too early')\n index += 1\n if (token.kind === 'number' || token.kind === 'string') return { type: 'value', value: token.value }\n if (token.kind === 'op' && token.value === '(') {\n const inner = ternary()\n expect(')')\n return inner\n }\n if (token.kind !== 'name') fail(`unexpected \"${token.value}\" at ${token.at + 1}`)\n if (!isOp('(')) return CONSTANTS.has(token.value) ? { type: 'value', value: CONSTANTS.get(token.value) } : { type: 'name', name: token.value }\n const fn = Object.hasOwn(FUNCTIONS, token.value) ? FUNCTIONS[token.value] : undefined\n if (fn === undefined) fail(`unknown function \"${token.value}\"; allowed: ${FORMULA_FUNCTIONS.join(', ')}`)\n index += 1\n const args = []\n if (!isOp(')')) {\n args.push(ternary())\n while (isOp(',')) { index += 1; args.push(ternary()) }\n }\n expect(')')\n if (args.length < fn.args[0] || args.length > fn.args[1]) {\n fail(`${token.value}() takes ${fn.args[0] === fn.args[1] ? fn.args[0] : fn.args[1] === Infinity ? `at least ${fn.args[0]}` : `${fn.args[0]} or ${fn.args[1]}`} argument${fn.args[1] === 1 ? '' : 's'}; got ${args.length}`)\n }\n return { type: 'call', name: token.value, args }\n }\n if (tokens.length === 0) fail('the formula is empty')\n const tree = ternary()\n if (index < tokens.length) fail(`unexpected \"${peek().value}\" at ${peek().at + 1}`)\n return tree\n}\n\nfunction namesIn(node, found = new Set()) {\n if (node.type === 'name') found.add(node.name)\n else if (node.type === 'unary') namesIn(node.value, found)\n else if (node.type === 'binary') { namesIn(node.left, found); namesIn(node.right, found) }\n else if (node.type === 'if') { namesIn(node.test, found); namesIn(node.yes, found); namesIn(node.no, found) }\n else if (node.type === 'call') for (const arg of node.args) namesIn(arg, found)\n return found\n}\n\n// { tree, names } or { error }. `names` are the names the formula reads.\nexport function compileFormula(source) {\n if (typeof source !== 'string') return { error: 'expected a formula string' }\n try {\n const tree = parse(source)\n return { tree, names: [...namesIn(tree)] }\n } catch (error) {\n if (error instanceof FormulaError) return { error: error.message }\n throw error\n }\n}\n\n// -------------------------------------------------------------------------\n// Evaluation. `lookup(name)` returns a name's value or throws.\n\nfunction run(node, lookup) {\n switch (node.type) {\n case 'value': return node.value\n case 'name': return lookup(node.name)\n case 'unary': {\n const value = run(node.value, lookup)\n if (node.op === '!') return !truthy(value)\n return node.op === '-' ? -num(value) : num(value)\n }\n case 'if': return truthy(run(node.test, lookup)) ? run(node.yes, lookup) : run(node.no, lookup)\n case 'call': return FUNCTIONS[node.name].run(...node.args.map(arg => run(arg, lookup)))\n default: return binary(node, lookup)\n }\n}\nconst truthy = value => (typeof value === 'string' ? value !== '' : Boolean(value))\n\nfunction binary(node, lookup) {\n if (node.op === '&&') return truthy(run(node.left, lookup)) ? run(node.right, lookup) : false\n if (node.op === '||') { const left = run(node.left, lookup); return truthy(left) ? left : run(node.right, lookup) }\n const left = run(node.left, lookup)\n const right = run(node.right, lookup)\n switch (node.op) {\n case '+': return typeof left === 'string' || typeof right === 'string' ? `${show(left)}${show(right)}` : num(left) + num(right)\n case '-': return num(left) - num(right)\n case '*': return num(left) * num(right)\n case '/': return num(left) / num(right)\n case '%': return num(left) % num(right)\n case '==': return left === right\n case '!=': return left !== right\n case '<': return num(left) < num(right)\n case '<=': return num(left) <= num(right)\n case '>': return num(left) > num(right)\n default: return num(left) >= num(right)\n }\n}\n\n// A value as text: numbers lose float noise (0.1 + 0.2 shows 0.3).\nexport function show(value) {\n if (typeof value === 'number') return Number.isFinite(value) ? String(Number(value.toPrecision(12))) : String(value)\n return String(value)\n}\n\n// A scope for one view: input values, plus `let` names worked out on demand. A cycle\n// or a missing name fails the formula that reads it.\nexport function createScope(inputs, lets) {\n const done = new Map()\n const busy = new Set()\n const lookup = (name) => {\n if (inputs.has(name)) return inputs.get(name)\n if (done.has(name)) return done.get(name)\n const tree = lets.get(name)\n if (tree === undefined) fail(`unknown name \"${name}\"`)\n if (busy.has(name)) fail(`\"${name}\" refers to itself`)\n busy.add(name)\n try {\n const value = run(tree, lookup)\n done.set(name, value)\n return value\n } finally { busy.delete(name) }\n }\n return lookup\n}\n\n// { value } or { error }.\nexport function evaluate(tree, lookup) {\n try {\n return { value: run(tree, lookup) }\n } catch (error) {\n if (error instanceof FormulaError) return { error: error.message }\n if (error instanceof RangeError) return { error: 'the formula is too deep to work out' }\n throw error\n }\n}\n","// Adapted from deep-view/src/core/views.js (deep-view 0.1.0, Apache-2.0).\n// DSH migration: html is deliberately rejected rather than migrating its frame;\n// validation, formulas and answers retain the original bounded JSON semantics.\n// Pure validation and evaluation of a declarative card, on Host and Client.\n// Formulas use formula.js; model-authored code never enters the DOM.\n\nimport { compileFormula, createScope, evaluate, isName, show } from './formula.js'\n\nconst LAYOUT = ['stack', 'row']\nconst DISPLAY = ['text', 'metric', 'table', 'chart', 'progress', 'callout', 'sources']\nconst INPUT_TYPES = ['slider', 'choice', 'toggle', 'number']\nconst ANSWERS = ['options', 'confirm', 'form', 'submit']\nconst COMPONENTS = [...LAYOUT, ...DISPLAY, ...INPUT_TYPES, ...ANSWERS]\nconst TONES = ['good', 'warn', 'bad']\nconst TEXT_TONES = ['muted']\nconst CALLOUT_TONES = ['info', 'good', 'warn', 'bad']\nexport const CHART_KINDS = ['bar', 'hbar', 'line', 'area', 'donut']\nconst INTERACTIVE = new Set(ANSWERS)\nconst INPUTS = new Set(INPUT_TYPES)\nconst PROPS = {\n stack: ['children', 'let'],\n row: ['children', 'let'],\n text: ['text', 'tone'],\n metric: ['label', 'value', 'tone', 'caption'],\n table: ['columns', 'rows'],\n chart: ['kind', 'categories', 'series', 'unit', 'caption'],\n progress: ['label', 'percent', 'value', 'max', 'valueLabel', 'tone'],\n callout: ['text', 'tone'],\n sources: ['items'],\n slider: ['id', 'label', 'min', 'max', 'step', 'value', 'unit'],\n choice: ['id', 'label', 'options', 'value'],\n toggle: ['id', 'label', 'value'],\n number: ['id', 'label', 'min', 'max', 'step', 'value', 'unit'],\n options: ['id', 'options', 'multi'],\n confirm: ['id', 'confirmLabel', 'cancelLabel'],\n form: ['id', 'fields', 'submitLabel'],\n submit: ['id', 'label'],\n}\nconst MAX_DEPTH = 8\nconst MAX_NODES = 64\nconst MAX_CHILDREN = 16\nconst MAX_TEXT = 2000\nconst MAX_CELL = 200\nconst MAX_COLUMNS = 8\nconst MAX_ROWS = 50\nconst MAX_OPTIONS = 8\nconst MAX_FIELDS = 6\nconst SUMMARY_PART = 40\nconst SUMMARY_COUNT = 8\nconst RESERVED = new Set(['true', 'false'])\n// UTF-8 bytes of the blueprint JSON plus the title. Not a wrapped document:\n// the tool rejects a show_view whose viewBytes() is over this before it\n// normalizes or validates, so the number has to be the bytes the model sent.\nexport const VIEW_BYTE_LIMIT = 8192\n\nconst isRecord = value => value !== null && typeof value === 'object' && !Array.isArray(value)\nconst quoted = value => JSON.stringify(value)\nconst allowed = list => list.join(', ')\nconst isNumber = value => typeof value === 'number' && Number.isFinite(value)\nconst isScalar = value => typeof value === 'string' || typeof value === 'boolean' || isNumber(value)\n\n// `{ \"=\": \"a * b\" }`: a value worked out from the view's inputs.\nexport const isFormula = value => isRecord(value) && Object.keys(value).length === 1 && Object.hasOwn(value, '=')\n\nexport function viewBytes(title, view) {\n return new TextEncoder().encode(`${JSON.stringify(view) ?? ''}${title ?? ''}`).length\n}\n\nconst NUMERIC = ['value', 'percent', 'min', 'max', 'step', 'height']\nconst numeric = value => (typeof value === 'string' && value.trim() !== '' && !Number.isNaN(Number(value)) ? Number(value) : value)\n\n// Some providers serialize nested arrays as `{ item: [...] }` (XML-style) and\n// numbers as strings. Normalize the blueprint before validation so a model is\n// not asked to retry a call whose only fault is the provider's encoding.\n// Arrays are unwrapped; numeric fields and chart values accept a numeric string.\n// Returns a new object; the input is not mutated.\nexport function normalizeView(value) {\n if (Array.isArray(value)) return value.map(normalizeView)\n if (!isRecord(value)) return value\n const keys = Object.keys(value)\n // Unwrap recursively: a provider may nest the wrapper, as { item: { item: [...] } }.\n if (keys.length === 1 && keys[0] === 'item') {\n const inner = normalizeView(value.item)\n if (Array.isArray(inner)) return inner\n }\n // Define own properties: an incoming \"__proto__\" key must become data the\n // validator can reject, not hit the prototype setter and vanish from the JSON.\n const out = {}\n for (const key of keys) Object.defineProperty(out, key, { value: normalizeView(value[key]), writable: true, enumerable: true, configurable: true })\n for (const field of NUMERIC) if (Object.hasOwn(out, field)) out[field] = numeric(out[field])\n if (Array.isArray(out.values)) out.values = out.values.map(numeric)\n return out\n}\n\nexport function validateView(view) {\n const ctx = { ids: new Set(), nodes: 0, interactive: false, inputs: new Map(), lets: new Map(), formulas: [] }\n const error = checkNode(view, 'view', 1, ctx) ?? checkFormulas(ctx)\n return error === undefined ? { ok: true, interactive: ctx.interactive } : { ok: false, error }\n}\n\n// What show_view checks before it shows a view: the same answer on the host and\n// in the client. The bytes are measured as sent, before normalizeView unwraps the\n// provider's encoding, or a wrapped view could shrink under the byte limit. The\n// normalized view and the trimmed title come back; the title may be empty.\nexport function checkShownView(title, sent) {\n let bytes\n try { bytes = viewBytes(title, sent) } catch { return { error: 'The view is not JSON data.' } }\n if (bytes > VIEW_BYTE_LIMIT) return { error: `The view is ${bytes} bytes; the limit is ${VIEW_BYTE_LIMIT}.` }\n if (title !== undefined && title !== null && typeof title !== 'string') return { error: 'title: expected a string' }\n const named = String(title ?? '').trim()\n const view = normalizeView(sent)\n const checked = validateView(view)\n if (!checked.ok) return { error: checked.error }\n return { title: named, view, interactive: checked.interactive }\n}\n\nfunction checkNode(node, path, depth, ctx) {\n if (!isRecord(node)) return `${path}: expected a component object`\n if (depth > MAX_DEPTH) return `${path}: ${depth} levels exceeds the limit of ${MAX_DEPTH}`\n ctx.nodes += 1\n if (ctx.nodes > MAX_NODES) return `${path}: ${ctx.nodes} components exceeds the limit of ${MAX_NODES}`\n const type = node.type\n if (!COMPONENTS.includes(type)) return `${path}.type: unknown component ${quoted(type)}; allowed: ${allowed(COMPONENTS)}`\n const props = PROPS[type]\n for (const key of Object.keys(node)) {\n if (key === 'type' || props.includes(key)) continue\n return `${path}.${key}: unknown property ${quoted(key)}; allowed: ${allowed(props)}`\n }\n if (INTERACTIVE.has(type)) ctx.interactive = true\n switch (type) {\n case 'stack': case 'row': return checkLayout(node, path, depth, ctx)\n case 'text': return checkText(node, path, ctx)\n case 'metric': return checkMetric(node, path, ctx)\n case 'table': return checkTable(node, path, ctx)\n case 'chart': return checkChart(node, path, ctx)\n case 'progress': return checkProgress(node, path, ctx)\n case 'callout': return checkCallout(node, path, ctx)\n case 'sources': return checkSources(node, path)\n case 'slider': case 'number': return checkNumberInput(node, path, ctx)\n case 'choice': return checkChoice(node, path, ctx)\n case 'toggle': return checkToggle(node, path, ctx)\n case 'options': return checkOptions(node, path, ctx)\n case 'confirm': return checkConfirm(node, path, ctx)\n case 'form': return checkForm(node, path, ctx)\n default: return checkSubmit(node, path, ctx)\n }\n}\n\nfunction checkLayout(node, path, depth, ctx) {\n if (node.let !== undefined) {\n if (depth !== 1) return `${path}.let: only the outermost component can define names`\n if (!isRecord(node.let)) return `${path}.let: expected an object of names to formulas`\n for (const [name, source] of Object.entries(node.let)) {\n if (!isName(name) || RESERVED.has(name)) return `${path}.let.${name}: a name is letters, digits and _, and starts with a letter or _`\n if (typeof source !== 'string') return `${path}.let.${name}: expected a formula string`\n ctx.lets.set(name, { source, path: `${path}.let.${name}` })\n }\n }\n if (!Array.isArray(node.children)) return `${path}.children: expected an array of 1 to ${MAX_CHILDREN} components`\n if (node.children.length < 1 || node.children.length > MAX_CHILDREN) return `${path}.children: expected 1 to ${MAX_CHILDREN} children; got ${node.children.length}`\n for (let index = 0; index < node.children.length; index += 1) {\n const error = checkNode(node.children[index], `${path}.children[${index}]`, depth + 1, ctx)\n if (error !== undefined) return error\n }\n return undefined\n}\n\n// A property that may be a literal of `kind` or a formula giving one. Formulas are\n// checked once the whole tree, with every input and name, is known.\nfunction checkValue(node, key, path, ctx, kind, { required = false, max = MAX_TEXT } = {}) {\n const value = node[key]\n const at = `${path}.${key}`\n if (value === undefined) return required ? `${at}: ${expected(kind)}` : undefined\n if (isFormula(value)) {\n ctx.formulas.push({ source: value['='], path: at, kind })\n return undefined\n }\n if (kind === 'number') return isNumber(value) ? undefined : `${at}: ${expected(kind)}`\n if (Array.isArray(kind)) return kind.includes(value) ? undefined : `${at}: unknown tone ${quoted(value)}; allowed: ${allowed(kind)}`\n if (kind === 'string') {\n if (typeof value !== 'string') return `${at}: ${expected(kind)}`\n return value.length > max ? `${at}: ${value.length} characters exceeds the limit of ${max}` : undefined\n }\n if (!isScalar(value)) return `${at}: ${expected(kind)}`\n return undefined\n}\nconst expected = kind => (kind === 'number' ? 'expected a number' : kind === 'string' ? 'expected a string' : Array.isArray(kind) ? `expected one of ${allowed(kind)}` : 'expected a string or a number')\n\nfunction checkText(node, path, ctx) {\n return checkValue(node, 'text', path, ctx, 'string', { required: true })\n ?? checkValue(node, 'tone', path, ctx, TEXT_TONES)\n}\n\nfunction checkMetric(node, path, ctx) {\n if (typeof node.label !== 'string') return `${path}.label: expected a string`\n if (node.value === undefined) return `${path}.value: expected a string or a number`\n if (typeof node.value === 'number' && !Number.isFinite(node.value)) return `${path}.value: expected a finite number`\n return checkValue(node, 'value', path, ctx, 'scalar')\n ?? checkValue(node, 'tone', path, ctx, TONES)\n ?? checkValue(node, 'caption', path, ctx, 'string')\n}\n\nfunction checkTable(node, path, ctx) {\n if (!Array.isArray(node.columns)) return `${path}.columns: expected an array of at most ${MAX_COLUMNS} columns`\n if (node.columns.length > MAX_COLUMNS) return `${path}.columns: ${node.columns.length} columns exceeds the limit of ${MAX_COLUMNS}`\n for (let index = 0; index < node.columns.length; index += 1) {\n const column = node.columns[index]\n const at = `${path}.columns[${index}]`\n if (!isRecord(column)) return `${at}: expected a column object`\n for (const key of Object.keys(column)) {\n if (key !== 'key' && key !== 'label') return `${at}.${key}: unknown property ${quoted(key)}; allowed: key, label`\n }\n if (typeof column.key !== 'string' || column.key === '') return `${at}.key: expected a non-empty string`\n if (typeof column.label !== 'string') return `${at}.label: expected a string`\n }\n if (!Array.isArray(node.rows)) return `${path}.rows: expected an array of at most ${MAX_ROWS} rows`\n if (node.rows.length > MAX_ROWS) return `${path}.rows: ${node.rows.length} rows exceeds the limit of ${MAX_ROWS}`\n for (let row = 0; row < node.rows.length; row += 1) {\n const cells = node.rows[row]\n if (!Array.isArray(cells)) return `${path}.rows[${row}]: expected an array of cells`\n for (let column = 0; column < cells.length; column += 1) {\n const at = `${path}.rows[${row}][${column}]`\n if (isFormula(cells[column])) { ctx.formulas.push({ source: cells[column]['='], path: at, kind: 'scalar' }); continue }\n const text = cellText(cells[column])\n if (text.length > MAX_CELL) return `${at}: ${text.length} characters exceeds the limit of ${MAX_CELL}`\n }\n }\n return undefined\n}\n\nfunction checkChart(node, path, ctx) {\n if (node.kind !== undefined && !CHART_KINDS.includes(node.kind)) return `${path}.kind: unknown chart ${quoted(node.kind)}; allowed: ${allowed(CHART_KINDS)}`\n if (!Array.isArray(node.categories) || node.categories.length === 0) return `${path}.categories: expected a non-empty array of labels`\n for (let index = 0; index < node.categories.length; index += 1) {\n const label = node.categories[index]\n if (typeof label !== 'string' && !isNumber(label)) return `${path}.categories[${index}]: expected a string`\n }\n if (!Array.isArray(node.series) || node.series.length === 0) return `${path}.series: expected a non-empty array of { name?, values }`\n if (node.kind === 'donut' && node.series.length > 1) return `${path}.series: a donut takes one series; got ${node.series.length}`\n for (let index = 0; index < node.series.length; index += 1) {\n const series = node.series[index]\n const at = `${path}.series[${index}]`\n if (!isRecord(series)) return `${at}: expected a series object`\n for (const key of Object.keys(series)) {\n if (key !== 'name' && key !== 'values') return `${at}.${key}: unknown property ${quoted(key)}; allowed: name, values`\n }\n if (series.name !== undefined && typeof series.name !== 'string') return `${at}.name: expected a string`\n if (!Array.isArray(series.values)) return `${at}.values: expected an array of numbers`\n if (series.values.length !== node.categories.length) return `${at}.values: ${series.values.length} values for ${node.categories.length} categories`\n for (let item = 0; item < series.values.length; item += 1) {\n const value = series.values[item]\n if (isFormula(value)) ctx.formulas.push({ source: value['='], path: `${at}.values[${item}]`, kind: 'number' })\n else if (!isNumber(value)) return `${at}.values[${item}]: expected a number`\n }\n }\n if (node.unit !== undefined && typeof node.unit !== 'string') return `${path}.unit: expected a string`\n if (node.caption !== undefined && typeof node.caption !== 'string') return `${path}.caption: expected a string`\n return undefined\n}\n\nfunction checkProgress(node, path, ctx) {\n if (node.label !== undefined && typeof node.label !== 'string') return `${path}.label: expected a string`\n if ((node.percent === undefined) === (node.value === undefined)) return `${path}: give percent (0 to 100), or value with max`\n if (node.percent !== undefined && !isFormula(node.percent)) {\n if (typeof node.percent !== 'number' || !Number.isFinite(node.percent) || node.percent < 0 || node.percent > 100) return `${path}.percent: expected a number from 0 to 100`\n }\n if (node.value !== undefined && node.max === undefined) return `${path}.max: expected a number with value`\n if (node.value === undefined && node.max !== undefined) return `${path}.value: expected a number with max`\n return checkValue(node, 'percent', path, ctx, 'number')\n ?? checkValue(node, 'value', path, ctx, 'number')\n ?? checkValue(node, 'max', path, ctx, 'number')\n ?? checkValue(node, 'valueLabel', path, ctx, 'scalar')\n ?? checkValue(node, 'tone', path, ctx, TONES)\n}\n\nfunction checkCallout(node, path, ctx) {\n return checkValue(node, 'text', path, ctx, 'string', { required: true })\n ?? checkValue(node, 'tone', path, ctx, CALLOUT_TONES)\n}\n\nfunction checkSources(node, path) {\n if (!Array.isArray(node.items) || node.items.length === 0) return `${path}.items: expected a non-empty array of { label, url }`\n for (let index = 0; index < node.items.length; index += 1) {\n const item = node.items[index]\n const at = `${path}.items[${index}]`\n if (!isRecord(item)) return `${at}: expected a { label, url } object`\n for (const key of Object.keys(item)) {\n if (key !== 'label' && key !== 'url') return `${at}.${key}: unknown property ${quoted(key)}; allowed: label, url`\n }\n if (typeof item.label !== 'string' || item.label.trim() === '') return `${at}.label: expected a non-empty string`\n if (typeof item.url !== 'string' || !/^https?:\\/\\/[^\\s]+$/i.test(item.url)) return `${at}.url: expected an http(s) address`\n }\n return undefined\n}\n\nfunction checkInputId(node, path, ctx) {\n if (!isName(node.id) || RESERVED.has(node.id)) return `${path}.id: an input id is letters, digits and _, and starts with a letter or _, so formulas can use it`\n if (ctx.ids.has(node.id)) return `${path}.id: duplicate id ${quoted(node.id)}`\n ctx.ids.add(node.id)\n if (typeof node.label !== 'string') return `${path}.label: expected a string`\n return undefined\n}\n\nfunction checkNumberInput(node, path, ctx) {\n const idError = checkInputId(node, path, ctx)\n if (idError !== undefined) return idError\n for (const key of ['min', 'max', 'step']) {\n if (node[key] !== undefined && !isNumber(node[key])) return `${path}.${key}: expected a number`\n }\n if (node.type === 'slider' && (node.min === undefined || node.max === undefined)) return `${path}: a slider needs min and max`\n if (node.min !== undefined && node.max !== undefined && node.max <= node.min) return `${path}.max: expected more than min (${node.min})`\n if (node.step !== undefined && node.step <= 0) return `${path}.step: expected more than 0`\n if (!isNumber(node.value)) return `${path}.value: expected a number`\n if ((node.min !== undefined && node.value < node.min) || (node.max !== undefined && node.value > node.max)) return `${path}.value: expected a number from ${node.min ?? '-∞'} to ${node.max ?? '∞'}`\n if (node.unit !== undefined && typeof node.unit !== 'string') return `${path}.unit: expected a string`\n ctx.inputs.set(node.id, node.value)\n return undefined\n}\n\nfunction checkChoice(node, path, ctx) {\n const idError = checkInputId(node, path, ctx)\n if (idError !== undefined) return idError\n if (!Array.isArray(node.options) || node.options.length === 0) return `${path}.options: expected a non-empty array of { label, value }`\n const labels = new Set()\n const values = new Set()\n for (let index = 0; index < node.options.length; index += 1) {\n const option = node.options[index]\n const at = `${path}.options[${index}]`\n if (!isRecord(option)) return `${at}: expected a { label, value } object`\n for (const key of Object.keys(option)) {\n if (key !== 'label' && key !== 'value') return `${at}.${key}: unknown property ${quoted(key)}; allowed: label, value`\n }\n if (typeof option.label !== 'string' || option.label.trim() === '') return `${at}.label: expected a non-empty string`\n if (labels.has(option.label)) return `${at}.label: duplicate label ${quoted(option.label)}`\n labels.add(option.label)\n const value = option.value ?? option.label\n if (!isScalar(value)) return `${at}.value: expected a string, a number or true/false`\n if (values.has(value)) return `${at}.value: duplicate value ${quoted(value)}`\n values.add(value)\n }\n const chosen = node.value ?? choiceValue(node.options[0])\n if (!values.has(chosen)) return `${path}.value: expected one of the options' values`\n ctx.inputs.set(node.id, chosen)\n return undefined\n}\n\nfunction checkToggle(node, path, ctx) {\n const idError = checkInputId(node, path, ctx)\n if (idError !== undefined) return idError\n if (node.value !== undefined && typeof node.value !== 'boolean') return `${path}.value: expected true or false`\n ctx.inputs.set(node.id, node.value === true)\n return undefined\n}\n\nfunction checkOptions(node, path, ctx) {\n const idError = checkId(node, path, ctx)\n if (idError !== undefined) return idError\n if (node.multi !== undefined && typeof node.multi !== 'boolean') return `${path}.multi: expected a boolean`\n if (!Array.isArray(node.options)) return `${path}.options: expected an array of 1 to ${MAX_OPTIONS} options`\n if (node.options.length < 1 || node.options.length > MAX_OPTIONS) return `${path}.options: expected 1 to ${MAX_OPTIONS} options; got ${node.options.length}`\n const labels = new Set()\n for (let index = 0; index < node.options.length; index += 1) {\n const option = node.options[index]\n const at = `${path}.options[${index}]`\n if (!isRecord(option)) return `${at}: expected an option object`\n for (const key of Object.keys(option)) {\n if (key !== 'label' && key !== 'description') return `${at}.${key}: unknown property ${quoted(key)}; allowed: label, description`\n }\n if (typeof option.label !== 'string' || option.label.trim() === '') return `${at}.label: expected a non-empty string`\n if (labels.has(option.label)) return `${at}.label: duplicate label ${quoted(option.label)}`\n labels.add(option.label)\n if (option.description !== undefined && typeof option.description !== 'string') return `${at}.description: expected a string`\n }\n return undefined\n}\n\nfunction checkConfirm(node, path, ctx) {\n const idError = checkId(node, path, ctx)\n if (idError !== undefined) return idError\n if (node.confirmLabel !== undefined && typeof node.confirmLabel !== 'string') return `${path}.confirmLabel: expected a string`\n if (node.cancelLabel !== undefined && typeof node.cancelLabel !== 'string') return `${path}.cancelLabel: expected a string`\n return undefined\n}\n\nfunction checkForm(node, path, ctx) {\n const idError = checkId(node, path, ctx)\n if (idError !== undefined) return idError\n if (node.submitLabel !== undefined && typeof node.submitLabel !== 'string') return `${path}.submitLabel: expected a string`\n if (!Array.isArray(node.fields)) return `${path}.fields: expected an array of at most ${MAX_FIELDS} fields`\n if (node.fields.length > MAX_FIELDS) return `${path}.fields: ${node.fields.length} fields exceeds the limit of ${MAX_FIELDS}`\n const seen = new Set()\n for (let index = 0; index < node.fields.length; index += 1) {\n const field = node.fields[index]\n const at = `${path}.fields[${index}]`\n if (!isRecord(field)) return `${at}: expected a field object`\n for (const key of Object.keys(field)) {\n if (key !== 'id' && key !== 'label' && key !== 'placeholder') return `${at}.${key}: unknown property ${quoted(key)}; allowed: id, label, placeholder`\n }\n if (typeof field.id !== 'string' || field.id === '') return `${at}.id: expected a non-empty string`\n if (field.id === '__proto__') return `${at}.id: \"__proto__\" cannot be an id`\n if (seen.has(field.id)) return `${at}.id: duplicate field id ${quoted(field.id)}`\n seen.add(field.id)\n if (typeof field.label !== 'string') return `${at}.label: expected a string`\n if (field.placeholder !== undefined && typeof field.placeholder !== 'string') return `${at}.placeholder: expected a string`\n }\n return undefined\n}\n\nfunction checkSubmit(node, path, ctx) {\n const idError = checkId(node, path, ctx)\n if (idError !== undefined) return idError\n if (node.label !== undefined && typeof node.label !== 'string') return `${path}.label: expected a string`\n return undefined\n}\n\nfunction checkId(node, path, ctx) {\n if (typeof node.id !== 'string' || node.id === '') return `${path}.id: expected a non-empty string`\n // A `__proto__` id would write through to a plain object's prototype where the\n // answer is kept, losing it silently.\n if (node.id === '__proto__') return `${path}.id: \"__proto__\" cannot be an id`\n if (ctx.ids.has(node.id)) return `${path}.id: duplicate id ${quoted(node.id)}`\n ctx.ids.add(node.id)\n return undefined\n}\n\n// Every formula parses, reads only inputs and names the view defines, and gives the\n// right kind of value with the inputs as the Bot set them.\nfunction checkFormulas(ctx) {\n const known = new Set([...ctx.inputs.keys(), ...ctx.lets.keys()])\n const lets = new Map()\n for (const [name, entry] of ctx.lets) {\n if (ctx.inputs.has(name)) return `${entry.path}: ${quoted(name)} is already an input id`\n const compiled = compileFormula(entry.source)\n if (compiled.error !== undefined) return `${entry.path}: ${compiled.error}`\n const unknown = compiled.names.find(item => !known.has(item))\n if (unknown !== undefined) return `${entry.path}: unknown name ${quoted(unknown)}; known: ${allowed([...known]) || '(none)'}`\n lets.set(name, compiled.tree)\n }\n const lookup = createScope(ctx.inputs, lets)\n for (const [name, entry] of ctx.lets) {\n const result = evaluate(lets.get(name), lookup)\n if (result.error !== undefined) return `${entry.path}: ${result.error}`\n }\n for (const formula of ctx.formulas) {\n const compiled = compileFormula(formula.source)\n if (compiled.error !== undefined) return `${formula.path}: ${compiled.error}`\n const unknown = compiled.names.find(item => !known.has(item))\n if (unknown !== undefined) return `${formula.path}: unknown name ${quoted(unknown)}; known: ${allowed([...known]) || '(none)'}`\n const result = evaluate(compiled.tree, lookup)\n if (result.error !== undefined) return `${formula.path}: ${result.error}`\n const problem = kindProblem(result.value, formula.kind)\n if (problem !== undefined) return `${formula.path}: the formula gives ${quoted(result.value)}; ${problem}`\n }\n return undefined\n}\n\nfunction kindProblem(value, kind) {\n if (kind === 'number') return isNumber(value) ? undefined : 'expected a number'\n if (Array.isArray(kind)) return kind.includes(value) ? undefined : `expected one of ${allowed(kind)}`\n if (kind === 'string') return isScalar(value) ? undefined : 'expected text'\n return isScalar(value) ? undefined : 'expected a string or a number'\n}\n\nfunction cellText(value) {\n if (typeof value === 'string') return value\n const text = JSON.stringify(value)\n return typeof text === 'string' ? text : ''\n}\n\n// -------------------------------------------------------------------------\n// Working a blueprint out: the client draws with these, the summary reads them.\n\nconst compiled = new WeakMap()\nconst treeOf = (formula) => {\n let entry = compiled.get(formula)\n if (entry === undefined) {\n entry = compileFormula(formula['='])\n compiled.set(formula, entry)\n }\n return entry\n}\n\nexport const choiceValue = option => option?.value ?? option?.label\n\nfunction walk(node, visit) {\n if (!isRecord(node)) return\n visit(node)\n if (LAYOUT.includes(node.type) && Array.isArray(node.children)) for (const child of node.children) walk(child, visit)\n}\n\nexport function viewInputs(view) {\n const found = []\n walk(view, (node) => { if (INPUTS.has(node.type)) found.push(node) })\n return found\n}\n\nexport function inputDefault(node) {\n if (node.type === 'toggle') return node.value === true\n if (node.type === 'choice') return node.value ?? choiceValue(Array.isArray(node.options) ? node.options[0] : undefined)\n return node.value\n}\n\nexport const hasInputs = view => viewInputs(view).length > 0\n\n// The values a view's formulas read: each input's default unless `values` sets it.\nexport function viewScope(view, values = {}) {\n const inputs = new Map()\n for (const node of viewInputs(view)) inputs.set(node.id, Object.hasOwn(values, node.id) ? values[node.id] : inputDefault(node))\n const lets = new Map()\n for (const [name, source] of Object.entries(isRecord(view?.let) ? view.let : {})) {\n const entry = compileFormula(source)\n if (entry.tree !== undefined) lets.set(name, entry.tree)\n }\n return createScope(inputs, lets)\n}\n\n// A property's value: the literal, or the formula worked out. A formula that fails\n// with these inputs gives `fallback`.\nexport function resolve(value, lookup, fallback = undefined) {\n if (!isFormula(value)) return value\n const entry = treeOf(value)\n if (entry.tree === undefined) return fallback\n const result = evaluate(entry.tree, lookup)\n return result.error === undefined ? result.value : fallback\n}\n\nexport const asText = value => (value === undefined || value === null ? '' : show(value))\n\n// -------------------------------------------------------------------------\n// Summaries\n\nfunction clip(text) {\n const flat = String(text).replace(/\\s+/g, ' ').trim()\n return flat.length <= SUMMARY_PART ? flat : flat.slice(0, SUMMARY_PART)\n}\n\nconst choiceLabel = (node, value) => (Array.isArray(node.options) ? node.options : []).find(option => choiceValue(option) === value)?.label ?? asText(value)\n\nfunction inputText(node, value) {\n if (node.type === 'toggle') return value === true ? 'on' : 'off'\n if (node.type === 'choice') return choiceLabel(node, value)\n return `${asText(value)}${node.unit ? ` ${node.unit}` : ''}`\n}\n\nfunction progressPercent(node, lookup) {\n if (node.percent !== undefined) return Number(resolve(node.percent, lookup, 0))\n const max = Number(resolve(node.max, lookup, 0))\n return max > 0 ? (Number(resolve(node.value, lookup, 0)) / max) * 100 : 0\n}\n\nfunction componentSummary(node, lookup) {\n const value = item => asText(resolve(item, lookup, ''))\n switch (node.type) {\n case 'text': return `text: ${value(node.text)}`\n case 'metric': return `metric: ${node.label}=${value(node.value)}`\n case 'table': return `table: ${(Array.isArray(node.columns) ? node.columns : []).map(column => column?.label ?? column?.key ?? '').filter(Boolean).join('/')}`\n case 'chart': {\n const series = Array.isArray(node.series) ? node.series[0] : undefined\n const values = Array.isArray(series?.values) ? series.values : []\n const unit = node.unit ? ` ${node.unit}` : ''\n return `chart: ${(Array.isArray(node.categories) ? node.categories : []).map((label, index) => `${label}=${value(values[index])}${unit}`).join(', ')}`\n }\n case 'progress': return `progress: ${node.label ? `${node.label} ` : ''}${Math.round(progressPercent(node, lookup))}%`\n case 'callout': return `callout: ${value(node.text)}`\n case 'sources': return `sources: ${(Array.isArray(node.items) ? node.items : []).map(item => item?.label).filter(Boolean).join('/')}`\n case 'slider': case 'number': case 'choice': case 'toggle': return `${node.type}: ${node.label}=${inputText(node, inputDefault(node))}`\n case 'options': return `options: ${(Array.isArray(node.options) ? node.options : []).map(option => option?.label).filter(Boolean).join('/')}`\n case 'confirm': return 'confirm'\n case 'form': return `form: ${(Array.isArray(node.fields) ? node.fields : []).map(field => field?.label ?? field?.id).filter(Boolean).join('/')}`\n case 'submit': return `submit: ${node.label ?? 'Send'}`\n default: return undefined\n }\n}\n\n// One line for a handoff or a checkpoint. Containers add nothing of their own;\n// each component keeps one short phrase, and the line stops after a few. Formulas\n// show what they give with the inputs as the Bot set them.\nexport function viewSummary(view) {\n const parts = []\n const lookup = viewScope(view)\n const visit = (node) => {\n if (parts.length >= SUMMARY_COUNT || !isRecord(node)) return\n const line = componentSummary(node, lookup)\n if (line !== undefined) parts.push(clip(line))\n if (parts.length >= SUMMARY_COUNT || !LAYOUT.includes(node.type) || !Array.isArray(node.children)) return\n for (const child of node.children) visit(child)\n }\n visit(view)\n return parts.join('; ')\n}\n\n// The inputs of an answer as `Label=value` pairs, for the Bot's history.\nexport function inputsSummary(view, inputs) {\n if (!isRecord(inputs)) return ''\n return viewInputs(view)\n .filter(node => Object.hasOwn(inputs, node.id))\n .map(node => `${node.label || node.id}=${inputText(node, inputs[node.id])}`)\n .join('; ')\n}\n\n// -------------------------------------------------------------------------\n// Answers\n\nfunction interactiveNodes(node, found = []) {\n walk(node, (item) => { if (INTERACTIVE.has(item.type)) found.push(item) })\n return found\n}\n\n// `action` is the id of the component the user submitted. One submit settles\n// the whole card, so only that component's values are kept, plus the inputs'\n// values when the view has inputs.\nexport function validateViewAnswer(view, action, values) {\n const nodes = interactiveNodes(view)\n if (typeof action !== 'string' || action === '') return { error: `action: expected an interactive component id; allowed: ${allowed(nodes.map(node => node.id))}` }\n const node = nodes.find(item => item.id === action)\n if (node === undefined) return { error: `action: no interactive component with id ${quoted(action)}; allowed: ${allowed(nodes.map(item => item.id))}` }\n if (!isRecord(values)) return { error: 'values: expected an object' }\n const inputs = validateInputs(view, values.inputs)\n if (inputs.error !== undefined) return inputs\n const extra = inputs.inputs === undefined ? {} : { inputs: inputs.inputs }\n if (node.type === 'submit') return { ...extra }\n const own = node.type === 'options' ? validateOptions(node, values) : node.type === 'confirm' ? validateConfirm(values) : validateForm(node, values)\n return own.error === undefined ? { ...own, ...extra } : own\n}\n\n// Every input of the view, as sent or else as the Bot set it.\nfunction validateInputs(view, sent) {\n const nodes = viewInputs(view)\n if (nodes.length === 0) return sent === undefined ? {} : { error: 'values.inputs: this view has no inputs' }\n if (sent !== undefined && !isRecord(sent)) return { error: 'values.inputs: expected an object of input ids to values' }\n const given = sent ?? {}\n const ids = nodes.map(node => node.id)\n const unknown = Object.keys(given).find(key => !ids.includes(key))\n if (unknown !== undefined) return { error: `values.inputs.${unknown}: unknown input; allowed: ${allowed(ids)}` }\n const inputs = {}\n for (const node of nodes) {\n const value = Object.hasOwn(given, node.id) ? given[node.id] : inputDefault(node)\n const at = `values.inputs.${node.id}`\n if (node.type === 'toggle' && typeof value !== 'boolean') return { error: `${at}: expected true or false` }\n if (node.type === 'choice' && !(Array.isArray(node.options) ? node.options : []).some(option => choiceValue(option) === value)) return { error: `${at}: expected one of the options' values` }\n if (node.type === 'slider' || node.type === 'number') {\n if (!isNumber(value)) return { error: `${at}: expected a number` }\n if ((node.min !== undefined && value < node.min) || (node.max !== undefined && value > node.max)) return { error: `${at}: expected a number from ${node.min ?? '-∞'} to ${node.max ?? '∞'}` }\n }\n inputs[node.id] = value\n }\n return { inputs }\n}\n\nfunction validateOptions(node, values) {\n if (!Array.isArray(values.selected)) return { error: 'values.selected: expected an array of option labels' }\n const labels = new Set((node.options ?? []).map(option => option?.label))\n const picked = values.selected.filter(label => typeof label === 'string' && labels.has(label))\n const selected = node.multi === true ? [...new Set(picked)] : picked.slice(0, 1)\n if (selected.length === 0) return { error: 'values.selected: select at least one option' }\n return { selected }\n}\n\nfunction validateConfirm(values) {\n if (typeof values.confirmed !== 'boolean') return { error: 'values.confirmed: expected a boolean' }\n return { confirmed: values.confirmed }\n}\n\nfunction validateForm(node, values) {\n if (!isRecord(values.fields)) return { error: 'values.fields: expected an object of field ids to strings' }\n const declared = (node.fields ?? []).map(field => field?.id).filter(id => typeof id === 'string')\n const allowedIds = new Set(declared)\n const fields = {}\n for (const [key, value] of Object.entries(values.fields)) {\n if (!allowedIds.has(key)) return { error: `values.fields.${key}: unknown field; allowed: ${allowed(declared)}` }\n if (typeof value !== 'string') return { error: `values.fields.${key}: expected a string` }\n if (value.length > MAX_TEXT) return { error: `values.fields.${key}: ${value.length} characters exceeds the limit of ${MAX_TEXT}` }\n fields[key] = value\n }\n return { fields }\n}\n","import { choiceValue, inputsSummary, validateViewAnswer, viewInputs } from './core/index.js'\nimport { isRecord, type ViewAnswer, type ViewNode } from './contracts.ts'\n\ntype Card = { id: string; title: string; view: ViewNode }\nfunction controls(view: ViewNode): ViewNode[] {\n return ['options', 'confirm', 'form', 'submit'].includes(view.type)\n ? [view] : (view.children ?? []).flatMap(controls)\n}\n\nexport function answerText(card: Pick<Card, 'title' | 'view'>, action: string, values: Record<string, unknown>): string {\n const node = controls(card.view).find(node => node.id === action)\n const lines = [card.title || 'Deep View']\n if (Array.isArray(values.selected)) lines.push(values.selected.map(String).join(', '))\n if (typeof values.confirmed === 'boolean') lines.push(values.confirmed\n ? node?.confirmLabel ?? 'Confirm' : node?.cancelLabel ?? 'Cancel')\n if (isRecord(values.fields)) {\n for (const field of node?.fields ?? []) lines.push(`${field.label}: ${String(values.fields[field.id] ?? '')}`)\n }\n const inputs = inputsSummary(card.view, values.inputs)\n if (inputs) lines.push(inputs)\n if (node?.type === 'submit') lines.push(node.label ?? 'Submit')\n return lines.join('\\n')\n}\n\n/** Legacy messages have no metadata. Restore only unambiguous, fully validated\n * answers that reproduce the exact text written by this plugin. Never guess\n * from ordinary prose, and never modify the stored message. */\nexport function legacyAnswer(card: Card, text: string): ViewAnswer | null {\n if (text.startsWith('{')) {\n try {\n const data: unknown = JSON.parse(text)\n if (!isRecord(data) || data.kind !== 'answer_to_pending_view' || data.tool !== 'show_view' || !Array.isArray(data.answers)) return null\n const answer = data.answers.find(value => isRecord(value) && value.id === card.id)\n if (!isRecord(answer) || typeof answer.action !== 'string') return null\n const values = validateViewAnswer(card.view, answer.action, answer.values)\n return values.error === undefined ? { id: card.id, action: answer.action, values } : null\n } catch { return null }\n }\n const lines = text.split('\\n')\n if (lines.shift() !== (card.title || 'Deep View')) return null\n const candidates: ViewAnswer[] = []\n for (const node of controls(card.view)) {\n const rest = [...lines]\n const values: Record<string, unknown> = {}\n if (node.type === 'options') {\n const line = rest.shift()\n if (line === undefined) continue\n const labels = node.options?.map(option => option.label) ?? []\n if (node.multi && labels.some(label => label.includes(', '))) continue\n values.selected = node.multi ? line.split(', ') : [line]\n } else if (node.type === 'confirm') {\n const line = rest.shift(), yes = node.confirmLabel ?? 'Confirm', no = node.cancelLabel ?? 'Cancel'\n if (yes === no || line !== yes && line !== no) continue\n values.confirmed = line === yes\n } else if (node.type === 'form') {\n const fields: Record<string, string> = {}\n let valid = true\n for (const field of node.fields ?? []) {\n const line = rest.shift(), prefix = `${field.label}: `\n if (line === undefined || !line.startsWith(prefix)) { valid = false; break }\n fields[field.id] = line.slice(prefix.length)\n }\n if (!valid) continue\n values.fields = fields\n }\n const inputs = viewInputs(card.view) as ViewNode[]\n if (inputs.length) {\n const pairs = rest.shift()?.split('; ')\n if (!pairs || pairs.length !== inputs.length) continue\n const sent: Record<string, unknown> = {}\n let valid = true\n for (let i = 0; i < inputs.length; i++) {\n const input = inputs[i], prefix = `${input.label || input.id}=`\n if (!pairs[i].startsWith(prefix)) { valid = false; break }\n const value = pairs[i].slice(prefix.length)\n if (input.type === 'toggle') sent[input.id!] = value === 'on' ? true : value === 'off' ? false : undefined\n else if (input.type === 'choice') {\n const choices = input.options?.filter(option => option.label === value) ?? []\n sent[input.id!] = choices.length === 1 ? choiceValue(choices[0]) : undefined\n } else {\n const unit = input.unit ? ` ${input.unit}` : ''\n sent[input.id!] = !unit || value.endsWith(unit) ? Number(unit ? value.slice(0, -unit.length) : value) : undefined\n }\n }\n if (!valid) continue\n values.inputs = sent\n }\n if (node.type === 'submit' && rest.shift() !== (node.label ?? 'Submit')) continue\n if (rest.length || !node.id) continue\n const checked = validateViewAnswer(card.view, node.id, values)\n if (checked.error === undefined && answerText(card, node.id, checked) === text) {\n candidates.push({ id: card.id, action: node.id, values: checked })\n }\n }\n return candidates.length === 1 ? candidates[0] : null\n}\n","import { randomUUID } from 'node:crypto'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type { ObjectJsonSchema } from '@deepseek-ai/dsh-tools'\nimport { createUserMessage } from '@deepseek-ai/dsh-llm'\nimport { registerHostRpc, type HostRpcContext } from '@klarkxy/dsh-plugin-kit/host-rpc'\nimport { checkShownView, validateViewAnswer, viewSummary } from './core/index.js'\nimport { answerText } from './answer-text.ts'\nimport { RPC_CHANNEL, VIEW_OWNER, isRecord, type PendingView, type RpcResult, type ShownView, type ViewNode, type ViewPresentation, type ViewAnswerMetadata } from './contracts.ts'\n\nexport const name = 'deep-view'\nexport const inject = ['tools', 'sessionController', 'sessions', 'agents', 'connection', 'webServer'] as const\n\ntype AgentLike = {\n id: string\n session: unknown\n followup(message: ReturnType<typeof createUserMessage>): void\n}\n// The real `agents` service returns the runtime Agent type; our local narrow\n// shape cannot feed includes() against it, so compare by id.\nconst isLiveRoot = (host: Host, agent: AgentLike | undefined) => agent !== undefined && host.agents.roots().some(root => (root as unknown as AgentLike).id === agent.id)\ntype Host = Context & HostRpcContext & {\n tools: {\n get(name: string, scope?: object): unknown\n register(definition: Record<string, unknown>): () => void\n }\n agents: { get(id: string): AgentLike | undefined; roots(): AgentLike[] }\n sessionController: { resolveAgent(id: string): Promise<{ agent?: AgentLike; error?: { message?: string } }> }\n sessions: { flush(session: unknown): Promise<boolean> }\n logger?: { warn(message: string, ...args: unknown[]): void }\n}\nconst ok = <T,>(value: T): RpcResult<T> => ({ ok: true, value })\nconst fail = (code: string, message: string): RpcResult<never> => ({ ok: false, error: { code, message } })\nconst short = (value: unknown, max = 160): value is string => typeof value === 'string' && value.length > 0 && value.length <= max\nconst checkedShown = (title: unknown, view: unknown) => checkShownView(title, view) as ShownView | { error: string }\nconst isShown = (value: ShownView | { error: string }): value is ShownView => !('error' in value)\n\nfunction presentation(args: unknown, value: unknown): ViewPresentation | undefined {\n if (!isRecord(value) || value.owner !== VIEW_OWNER || !['shown', 'pending'].includes(String(value.status))) return undefined\n const shown = checkedShown(isRecord(args) ? args.title : undefined, isRecord(args) ? args.view : undefined)\n if (!isShown(shown)) return undefined\n return {\n owner: VIEW_OWNER, ...(short(value.viewId, 80) ? { viewId: value.viewId } : {}),\n ...shown, awaitReply: value.awaitReply === true,\n }\n}\n\nexport function createShowViewTool(host: Host, pending: Map<string, PendingView>, makeId: () => string = randomUUID): Record<string, unknown> {\n return {\n name: 'show_view',\n description: [\n 'Attach one card below your final reply when a visual or interactive form beats prose: compared numbers, a trend, a share, progress; an estimate with user-adjustable inputs; or a choice the user answers afterwards (use ask_user_question when you cannot continue without it).',\n 'Prefer plain Markdown otherwise. Call once, then finish the reply; the card is not yet visible when this tool returns.',\n 'Never end on the call, wait or poll, repeat the card JSON, or claim the user saw it. Answers accept one reply, sent as the next user message. Never collect keys, tokens or passwords.',\n ].join(' '),\n // tools.register() takes raw JSON Schema; the per-field DSL is only for defineTool().\n parameters: {\n type: 'object',\n properties: {\n title: { type: 'string', description: 'Short heading above the card.' },\n view: { type: 'object', additionalProperties: true, description: [\n 'One ViewNode, nodes nest under stack|row(children,let?).',\n 'Display: text,metric{label,value},table{columns:[{key,label}],rows:[[cell]]},chart{kind:bar|hbar|line|area|donut,categories,series:[{name?,values}]},progress{percent|value+max},callout{text},sources{items:[{label,url}]}.',\n 'Inputs: slider,number,choice,toggle{id,label,value}. A {\"=\":\"expr\"} formula replaces a value or cell, reading input ids and let names.',\n 'Answers(need await_reply true): options{id,options,multi?},confirm{id},form{id,fields},submit{id,label}. No html.',\n ].join(' ') },\n await_reply: { type: 'boolean', description: 'Whether this card asks the user for a response.' },\n },\n required: ['view'],\n } satisfies ObjectJsonSchema,\n output: {\n schema: { type: 'object', properties: { owner: { type: 'string', const: VIEW_OWNER }, status: { type: 'string' }, viewId: { type: 'string' }, awaitReply: { type: 'boolean' }, summary: { type: 'string' } }, required: ['owner', 'status', 'awaitReply', 'summary'], additionalProperties: false },\n render: (_args: unknown, value: { summary?: string }) => [{ type: 'text', text: String(value.summary ?? '') }],\n presentationMeta: presentation,\n },\n async execute(args: unknown, exec: { agent?: AgentLike; callId?: string; concludeTurn(): void }) {\n const input = isRecord(args) ? args : {}\n const shown = checkedShown(input.title, input.view)\n if (!isShown(shown)) return { owner: VIEW_OWNER, status: 'invalid', awaitReply: false, summary: shown.error }\n if (typeof input.await_reply !== 'undefined' && typeof input.await_reply !== 'boolean') {\n return { owner: VIEW_OWNER, status: 'invalid', awaitReply: false, summary: 'await_reply: expected true or false' }\n }\n const awaitReply = input.await_reply ?? shown.interactive\n if (awaitReply !== shown.interactive) {\n return { owner: VIEW_OWNER, status: 'invalid', awaitReply: false, summary: shown.interactive ? 'This card has answer controls; omit await_reply or set it true.' : 'A display-only card cannot wait for an answer; omit await_reply or set it false.' }\n }\n const id = exec.agent?.id\n const agent = id === undefined ? undefined : host.agents.get(id)\n if (awaitReply && !isLiveRoot(host, agent)) {\n return { owner: VIEW_OWNER, status: 'invalid', awaitReply: false, summary: 'An interactive view only works in a live root session. Put the question or decision in your response instead.' }\n }\n let viewId: string | undefined\n if (awaitReply && agent) {\n viewId = makeId()\n // set() alone replaces an earlier unanswered card: the old card becomes\n // stale and its pending record points at the newest view only.\n pending.set(agent.id, { id: viewId, sessionId: agent.id, ...(exec.callId ? { callId: exec.callId } : {}), ...shown })\n }\n return {\n owner: VIEW_OWNER, status: awaitReply ? 'pending' : 'shown', ...(viewId ? { viewId } : {}), awaitReply,\n // A tool result is process data. The completed-turn reply surface owns\n // the card, so the model must still produce its final answer.\n summary: `Card prepared for the final reply. Finish with a concise final answer; do not call this tool again for the same card.${awaitReply ? ' The user can answer the card after your reply finishes; do not wait or poll.' : ''} ${viewSummary(shown.view)}`,\n }\n },\n isConcurrencySafe: () => false,\n }\n}\n\nexport function createRpc(host: Host, pending: Map<string, PendingView>) {\n const claims = new Set<string>()\n return async (endpoint: string, payload: unknown, signal: AbortSignal): Promise<RpcResult> => {\n if (!isRecord(payload) || !short(payload.sessionId, 200)) return fail('bad-request', 'A bounded sessionId is required')\n const sessionId = payload.sessionId\n const record = pending.get(sessionId)\n if (endpoint === 'pending') return ok(record?.callId === payload.callId || payload.callId === undefined ? record ?? null : null)\n if (endpoint === 'dismiss') {\n if (record?.id === payload.viewId) pending.delete(sessionId)\n return ok(true)\n }\n if (endpoint !== 'reply') return fail('not-found', 'Unknown Deep View endpoint')\n if (!record || !short(payload.viewId, 80) || payload.viewId !== record.id || !short(payload.action, 160) || !isRecord(payload.values)) {\n return fail('stale', 'This view is no longer open')\n }\n if (claims.has(record.id)) return fail('busy', 'This view is already being answered')\n const checked = validateViewAnswer(record.view as ViewNode, payload.action, payload.values) as { error?: string } & Record<string, unknown>\n if (checked.error !== undefined) return fail('invalid', checked.error)\n claims.add(record.id)\n pending.delete(sessionId)\n // Exact-once: the record is restored only when followup never appended a\n // user message. Once appended, a failed checkpoint may lose the card from\n // disk, but re-adding the record would let a retry send the same user\n // answer a second time. Restoration lives in the finally so cancellation\n // returns, resolve failures and append failures share one path.\n let appended = false\n try {\n if (signal.aborted) return fail('cancelled', 'The request was cancelled')\n const resolved = await host.sessionController.resolveAgent(sessionId)\n const agent = resolved.agent\n if (!agent || host.agents.get(agent.id) !== agent || !host.agents.roots().some(root => (root as unknown as AgentLike).id === agent.id)) throw new Error(resolved.error?.message ?? 'The session is not a live root session')\n if (signal.aborted) return fail('cancelled', 'The request was cancelled')\n // Text and answer facts share one durable message: neither can survive\n // without the other, and fork/history boundaries preserve their pairing.\n const deepView: ViewAnswerMetadata = {\n owner: VIEW_OWNER, version: 1,\n answer: { id: record.id, action: payload.action, values: checked },\n }\n agent.followup(createUserMessage({\n content: [{ type: 'text', text: answerText(record, payload.action, checked) }],\n source: { kind: 'user', deepView },\n }))\n appended = true\n await host.sessions.flush(agent.session)\n return ok({ answered: true })\n } catch (error) {\n return fail('internal', error instanceof Error ? error.message : String(error))\n } finally {\n if (!appended && !pending.has(sessionId)) pending.set(sessionId, record)\n claims.delete(record.id)\n }\n }\n}\n\nexport async function apply(ctx: Context): Promise<void> {\n const host = ctx as unknown as Host\n const pending = new Map<string, PendingView>()\n ctx.effect(() => {\n if (host.tools.get('show_view')) {\n host.logger?.warn('deep-view: show_view is already registered by another plugin; this bundle stays disabled for its own tool')\n return () => {}\n }\n try {\n return host.tools.register(createShowViewTool(host, pending))\n }\n catch (error) {\n host.logger?.warn('deep-view: show_view registration skipped: %s', error instanceof Error ? error.message : String(error))\n return () => {}\n }\n }, 'deep-view.tool')\n // Only admission events are observed, never scanned. A new human message closes a stale card.\n ctx.effect(() => ctx.on('session/event', (session: { id: string }, event: { type: string; data?: unknown }) => {\n if (event.type !== 'user/message' || !isRecord(event.data) || !isRecord(event.data.source) || event.data.source.kind !== 'user') return\n pending.delete(session.id)\n }), 'deep-view.close-pending')\n ctx.effect(() => registerHostRpc(host, RPC_CHANNEL, createRpc(host, pending), { maxBodyBytes: 24 * 1024 }), 'deep-view.rpc')\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../dsh-plugin-kit/src/log-shared.ts","../../dsh-plugin-kit/src/logger.ts","../../dsh-plugin-kit/src/host-rpc.ts","../src/index.ts"],"sourcesContent":["export type PluginLogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fault'\n\nexport const PLUGIN_LOG_LEVELS: readonly PluginLogLevel[] = ['debug', 'info', 'warn', 'error', 'fault']\nexport const DEFAULT_PLUGIN_LOG_LEVEL: PluginLogLevel = 'info'\nexport const PLUGIN_LOG_MAX_MESSAGE_CHARS = 16_000\nexport const PLUGIN_LOG_MAX_CONTEXT_CHARS = 8_000\n\nexport type PluginLogScalar = string | number | boolean | null\nexport type PluginLogContext = Record<string, PluginLogScalar | undefined>\n\nexport interface PluginLogInput {\n level: PluginLogLevel\n event: string\n message: string\n context?: PluginLogContext\n error?: unknown\n}\n\nexport interface PluginLogError {\n name: string\n message: string\n stack?: string\n code?: string\n}\n\nexport interface PluginLogEntry {\n version: 1\n at: string\n level: PluginLogLevel\n source: string\n surface: 'host' | 'client'\n profile?: string\n event: string\n message: string\n pid?: number\n context?: Record<string, PluginLogScalar>\n error?: PluginLogError\n}\n\nexport interface PluginLogger {\n readonly source: string\n readonly file: string | null\n readonly lastWriteError: string | null\n debug(event: string, message: string, context?: PluginLogContext): boolean\n info(event: string, message: string, context?: PluginLogContext): boolean\n warn(event: string, message: string, error?: unknown, context?: PluginLogContext): boolean\n error(event: string, message: string, error?: unknown, context?: PluginLogContext): boolean\n fault(event: string, message: string, error?: unknown, context?: PluginLogContext): boolean\n write(input: PluginLogInput): boolean\n child(context: PluginLogContext): PluginLogger\n}\n\nconst SOURCE_RE = /^[a-z][a-z0-9-]{0,63}$/\nconst EVENT_RE = /^[a-z][a-z0-9._-]{0,127}$/\nconst CONTEXT_KEY_RE = /^[a-zA-Z][a-zA-Z0-9._-]{0,63}$/\nconst SECRET_KEY_RE = /(?:api[_-]?key|access[_-]?token|refresh[_-]?token|bearer|authorization|cookie|set[_-]?cookie|nonce|credential|private[_-]?key|password|secret|app[_-]?secret|client[_-]?secret|z_c0|d_c0)$/i\n\nconst CHAT_PAYLOAD_RE =\n /\"role\"\\s*:\\s*\"(?:system|user|assistant|tool)\"|\"(?:messages|content|prompt|input_text|input_image|image_url)\"\\s*:\\s*[\\[{\"']/i\nconst CREDENTIAL_BODY_RE =\n /-----BEGIN (?:RSA |EC |OPENSSH |PRIVATE )?PRIVATE KEY-----|\"type\"\\s*:\\s*\"service_account\"|credentials\\.json|\\.dsh[/\\\\](?:credentials|auth)/i\nconst AUTH_HEADER_RE = /\\b(Authorization|Proxy-Authorization|Cookie|Set-Cookie)\\s*:\\s*[^\\r\\n]*/gi\nconst BEARER_RE = /\\bBearer\\s+[A-Za-z0-9._\\-+=/]{8,}/g\nconst SECRET_FIELD_RE =\n /([\"']?(?:api[_-]?key|access[_-]?token|refresh[_-]?token|token|bearer|authorization|cookie|set-cookie|nonce|credential|private[_-]?key|password|secret|app[_-]?secret|client[_-]?secret|password|z_c0|d_c0)[\"']?\\s*[:=]\\s*)(?:\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|[^\\s,&;}]+)/gi\nconst SECRET_QUERY_RE =\n /([?&](?:token|api[_-]?key|key|secret|password|bootstrap|code|sig|signature|credential|password)=)[^\\s&#\"']+/gi\nconst URL_CREDENTIAL_RE = /\\b(https?:\\/\\/)[^\\s/:@]+:[^\\s/@]+@/gi\nconst BOOTSTRAP_RE = /\\/bootstrap\\/[^\\s\"'?&#]+/gi\nconst KNOWN_TOKEN_RE = /\\b(?:sk-[A-Za-z0-9_-]{10,}|gh[pousr]_[A-Za-z0-9_]{16,}|github_pat_[A-Za-z0-9_]{20,}|tvly-[A-Za-z0-9_-]{10,}|AKIA[0-9A-Z]{16})\\b/g\nconst PATH_RE = /(?:[A-Za-z]:\\\\|\\\\\\\\)[^\\s\"'`<>|]+|(?:\\/(?:home|Users|tmp|var|root)\\/|~\\/)[^\\s\"'`<>|]+/g\n\nexport function isPluginLogLevel(value: unknown): value is PluginLogLevel {\n return typeof value === 'string' && (PLUGIN_LOG_LEVELS as readonly string[]).includes(value)\n}\n\nexport function pluginLogLevelEnabled(level: PluginLogLevel, minimum: PluginLogLevel): boolean {\n return PLUGIN_LOG_LEVELS.indexOf(level) >= PLUGIN_LOG_LEVELS.indexOf(minimum)\n}\n\nexport function normalizePluginLogSource(raw: string): string {\n const stripped = String(raw || '').trim().replace(/^@[^/]+\\//, '').toLowerCase()\n .replace(/[^a-z0-9-]+/g, '-').replace(/^-+|-+$/g, '')\n const prefixed = /^[a-z]/.test(stripped) ? stripped : `p-${stripped}`\n const bounded = prefixed.slice(0, 64).replace(/-+$/g, '')\n return SOURCE_RE.test(bounded) ? bounded : 'dsh-plugin'\n}\n\nexport function normalizePluginLogEvent(raw: string): string {\n const cleaned = String(raw || '').trim().toLowerCase()\n .replace(/[^a-z0-9._-]+/g, '-').replace(/^[^a-z]+/, '').slice(0, 128)\n return EVENT_RE.test(cleaned) ? cleaned : 'plugin.event'\n}\n\n/**\n * Parse a level specification like `debug` or `dsh-zhihu=debug,dsh-dot:warn,info`.\n * Source-specific rules win over a bare fallback level.\n */\nexport function parsePluginLogLevel(\n spec: string | undefined | null,\n source?: string,\n fallback: PluginLogLevel = DEFAULT_PLUGIN_LOG_LEVEL,\n): PluginLogLevel {\n if (!spec || typeof spec !== 'string') return fallback\n const normalizedSource = source ? normalizePluginLogSource(source) : undefined\n let wildcard: PluginLogLevel | undefined\n for (const token of spec.split(',').map(part => part.trim()).filter(Boolean)) {\n const lowered = token.toLowerCase()\n if (isPluginLogLevel(lowered)) {\n wildcard = lowered\n continue\n }\n const match = /^([^=:]+)[=:]([a-z]+)$/i.exec(token)\n if (!match) continue\n const target = match[1]!.trim()\n const candidate = match[2]!.trim().toLowerCase()\n if (!isPluginLogLevel(candidate)) continue\n if (target === '*') {\n wildcard = candidate\n continue\n }\n if (normalizedSource && normalizePluginLogSource(target) === normalizedSource) {\n return candidate\n }\n }\n return wildcard ?? fallback\n}\n\nexport function sanitizePluginLogText(text: string, maxChars = PLUGIN_LOG_MAX_MESSAGE_CHARS): string {\n if (!text) return ''\n if (CREDENTIAL_BODY_RE.test(text)) return '[omitted credential material]'\n if (CHAT_PAYLOAD_RE.test(text)) return '[omitted chat payload]'\n const redacted = text\n .replace(AUTH_HEADER_RE, '$1: [redacted]')\n .replace(BEARER_RE, 'Bearer [redacted]')\n .replace(SECRET_FIELD_RE, (full, prefix: string) => {\n const value = full.slice(prefix.length)\n if (value.startsWith('\"')) return `${prefix}\"[redacted]\"`\n if (value.startsWith(\"'\")) return `${prefix}'[redacted]'`\n return `${prefix}[redacted]`\n })\n .replace(SECRET_QUERY_RE, '$1[redacted]')\n .replace(URL_CREDENTIAL_RE, '$1[redacted]@')\n .replace(BOOTSTRAP_RE, '/bootstrap/[redacted]')\n .replace(KNOWN_TOKEN_RE, '[redacted]')\n .replace(PATH_RE, '[path]')\n return truncateLogText(redacted, maxChars)\n}\n\nexport function sanitizePluginLogContext(\n input: PluginLogContext | undefined,\n): Record<string, PluginLogScalar> | undefined {\n if (!input) return undefined\n const output: Record<string, PluginLogScalar> = {}\n for (const [key, value] of Object.entries(input).slice(0, 32)) {\n if (value === undefined || !CONTEXT_KEY_RE.test(key)) continue\n if (typeof value === 'number' && !Number.isFinite(value)) continue\n if (SECRET_KEY_RE.test(key)) {\n output[key] = '[redacted]'\n continue\n }\n output[key] = typeof value === 'string' ? sanitizePluginLogText(value, 1_000) : value\n }\n if (!Object.keys(output).length) return undefined\n const encoded = JSON.stringify(output)\n if (encoded.length <= PLUGIN_LOG_MAX_CONTEXT_CHARS) return output\n return { omitted: true, reason: 'Diagnostic context exceeded its size limit.' }\n}\n\nexport function sanitizePluginLogError(error: unknown): PluginLogError | undefined {\n if (error === undefined) return undefined\n const row = error && typeof error === 'object'\n ? error as { name?: unknown; message?: unknown; stack?: unknown; code?: unknown }\n : {}\n const rawMessage = typeof row.message === 'string' ? row.message : String(error)\n const result: PluginLogError = {\n name: typeof row.name === 'string' && row.name.trim() ? truncateLogText(row.name.trim(), 100) : 'Error',\n message: sanitizePluginLogText(rawMessage) || 'Unknown error',\n }\n if (typeof row.stack === 'string' && row.stack.trim()) {\n result.stack = sanitizePluginLogText(row.stack, 24_000)\n }\n if (typeof row.code === 'string' && /^[A-Za-z0-9_./:-]{1,100}$/.test(row.code)) {\n result.code = row.code\n } else if (typeof row.code === 'number' && Number.isFinite(row.code)) {\n result.code = String(row.code)\n }\n return result\n}\n\nexport function mergePluginLogContext(\n base: PluginLogContext | undefined,\n extra: PluginLogContext | undefined,\n): PluginLogContext | undefined {\n if (!base) return extra\n if (!extra) return base\n return { ...base, ...extra }\n}\n\nexport function buildPluginLogEntry(\n input: PluginLogInput,\n meta: {\n at: Date\n source: string\n surface: 'host' | 'client'\n profile?: string\n pid?: number\n correlation?: PluginLogContext\n },\n): PluginLogEntry {\n const entry: PluginLogEntry = {\n version: 1,\n at: meta.at.toISOString(),\n level: isPluginLogLevel(input.level) ? input.level : 'info',\n source: normalizePluginLogSource(meta.source),\n surface: meta.surface,\n ...(meta.profile ? { profile: meta.profile } : {}),\n event: normalizePluginLogEvent(input.event),\n message: sanitizePluginLogText(input.message || 'No diagnostic message was provided.', PLUGIN_LOG_MAX_MESSAGE_CHARS),\n ...(meta.pid !== undefined ? { pid: meta.pid } : {}),\n }\n const context = sanitizePluginLogContext(mergePluginLogContext(meta.correlation, input.context))\n if (context) entry.context = context\n const error = sanitizePluginLogError(input.error)\n if (error) entry.error = error\n return entry\n}\n\nexport function createChildPluginLogger(parent: PluginLogger, bound: PluginLogContext): PluginLogger {\n return {\n get source() { return parent.source },\n get file() { return parent.file },\n get lastWriteError() { return parent.lastWriteError },\n debug: (event, message, context) => parent.debug(event, message, mergePluginLogContext(bound, context)),\n info: (event, message, context) => parent.info(event, message, mergePluginLogContext(bound, context)),\n warn: (event, message, error, context) => parent.warn(event, message, error, mergePluginLogContext(bound, context)),\n error: (event, message, error, context) => parent.error(event, message, error, mergePluginLogContext(bound, context)),\n fault: (event, message, error, context) => parent.fault(event, message, error, mergePluginLogContext(bound, context)),\n write: input => parent.write({ ...input, context: mergePluginLogContext(bound, input.context) }),\n child: next => createChildPluginLogger(parent, mergePluginLogContext(bound, next) ?? {}),\n }\n}\n\nexport function truncateLogText(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text\n const marker = '[truncated]\\n'\n if (maxChars <= marker.length) return text.slice(0, Math.max(0, maxChars))\n return `${marker}${text.slice(-(maxChars - marker.length))}`\n}\n","import { AsyncLocalStorage } from 'node:async_hooks'\nimport {\n appendFileSync, closeSync, existsSync, lstatSync, mkdirSync, openSync,\n readSync, readdirSync, realpathSync, renameSync, unlinkSync,\n} from 'node:fs'\nimport { homedir } from 'node:os'\nimport { basename, dirname, join, resolve, sep } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport {\n DEFAULT_PLUGIN_LOG_LEVEL, buildPluginLogEntry, createChildPluginLogger,\n mergePluginLogContext, normalizePluginLogSource, parsePluginLogLevel,\n pluginLogLevelEnabled, sanitizePluginLogText,\n type PluginLogContext, type PluginLogEntry, type PluginLogInput,\n type PluginLogLevel, type PluginLogger,\n} from './log-shared.ts'\n\nexport * from './log-shared.ts'\n\nexport const PLUGIN_LOG_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000\nexport const PLUGIN_LOG_MAX_FILE_BYTES = 100 * 1024 * 1024\nexport const PLUGIN_LOG_MAX_ARCHIVE_BYTES = 100 * 1024 * 1024\nexport const PLUGIN_LOG_RECENT_LIMIT = 200\n\nconst PROFILE_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,63}$/\nconst ARCHIVE_RE = /^[a-z][a-z0-9-]{0,63}\\.\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}\\.\\d{3}Z\\.\\d+\\.\\d+\\.jsonl$/\n\nconst correlationStorage = new AsyncLocalStorage<PluginLogContext>()\nconst processFileLoggers = new Map<string, RotatingPluginLogger>()\nlet operationSequence = 0\n\nexport interface RotatingPluginLoggerOptions {\n directory?: string\n home?: string\n profile?: string\n minimumLevel?: PluginLogLevel\n env?: NodeJS.ProcessEnv\n now?: () => Date\n pid?: number\n maxFileBytes?: number\n maxArchiveBytes?: number\n maxAgeMs?: number\n recentLimit?: number\n forwardHostWarnError?: boolean\n}\n\nexport interface InstallPluginLoggerOptions extends RotatingPluginLoggerOptions {\n loadedContext?: PluginLogContext\n}\n\ntype HostContextLike = {\n baseUrl?: unknown\n get?: (name: string, ...rest: unknown[]) => unknown\n effect?: (callback: () => () => void | Promise<void>, label?: string) => unknown\n logger?: {\n warn?: (...args: unknown[]) => void\n error?: (...args: unknown[]) => void\n }\n}\n\nexport function safeProfileName(profile: string | undefined | null): string {\n const trimmed = String(profile ?? '').trim()\n if (PROFILE_RE.test(trimmed)) return trimmed.toLowerCase()\n const cleaned = trimmed.toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 64)\n return cleaned && PROFILE_RE.test(cleaned) ? cleaned : 'default'\n}\n\nexport function pluginLogDirectory(home: string, profile = 'default'): string {\n return join(resolve(home), 'logs', 'plugins', safeProfileName(profile))\n}\n\nexport function resolveHostLogTarget(\n ctx: unknown,\n options: Pick<RotatingPluginLoggerOptions, 'directory' | 'home' | 'profile' | 'env'> = {},\n): { directory: string | null; anchor: string | null; profile?: string } {\n const env = options.env ?? process.env\n if (options.directory?.trim()) {\n const dir = resolve(options.directory.trim())\n return { directory: dir, anchor: dir, ...(options.profile ? { profile: safeProfileName(options.profile) } : {}) }\n }\n if (options.home?.trim()) {\n const home = resolve(options.home.trim())\n const profile = safeProfileName(options.profile)\n return { directory: pluginLogDirectory(home, profile), anchor: home, profile }\n }\n if (env.DSH_PLUGIN_LOG_DIR?.trim()) {\n const dir = resolve(env.DSH_PLUGIN_LOG_DIR.trim())\n return { directory: dir, anchor: dir, ...(options.profile ? { profile: safeProfileName(options.profile) } : {}) }\n }\n const host = ctx && typeof ctx === 'object' ? ctx as HostContextLike : undefined\n let profileCtx: { home?: unknown; name?: unknown; dir?: unknown } | undefined\n try {\n profileCtx = host?.get?.('profileContext', false) as typeof profileCtx\n } catch {\n try { profileCtx = host?.get?.('profileContext') as typeof profileCtx } catch { profileCtx = undefined }\n }\n if (\n typeof profileCtx?.home === 'string' && profileCtx.home.trim()\n && typeof profileCtx.dir === 'string' && profileCtx.dir.trim()\n ) {\n const home = resolve(profileCtx.home.trim())\n const dir = resolve(profileCtx.dir.trim())\n if (isInside(home, dir)) {\n const profile = safeProfileName(typeof profileCtx.name === 'string' ? profileCtx.name : basename(dir))\n return { directory: pluginLogDirectory(home, profile), anchor: home, profile }\n }\n }\n const inUnitTest = Boolean(env.VITEST || env.NODE_TEST_CONTEXT)\n if (!inUnitTest && typeof host?.baseUrl === 'string' && host.baseUrl.trim()) {\n const basePath = pathFromBaseUrl(host.baseUrl)\n const configuredHome = resolve((env.DSH_HOME?.trim() || join(homedir(), '.dsh')).trim())\n const profilesRoot = join(configuredHome, 'profiles')\n if (basePath && isInside(profilesRoot, basePath) && !samePath(profilesRoot, basePath)) {\n const rel = basePath.slice(profilesRoot.length).replace(/^[/\\\\]+/, '')\n const firstSegment = rel.split(/[/\\\\]/)[0]\n if (firstSegment) {\n const profile = safeProfileName(firstSegment)\n return { directory: pluginLogDirectory(configuredHome, profile), anchor: configuredHome, profile }\n }\n }\n }\n return { directory: null, anchor: null, ...(options.profile ? { profile: safeProfileName(options.profile) } : {}) }\n}\n\n/**\n * Synchronous, append-only rotating JSONL logger modeled on DSH Spaces\n * diagnostics: 7-day or 100 MiB active rotation, 7-day / 100 MiB archive\n * retention, secret and path redaction, and non-throwing write resilience.\n */\nexport class RotatingPluginLogger implements PluginLogger {\n readonly source: string\n readonly file: string | null\n private lastError: string | null = null\n private size = 0\n private openedAt = 0\n private initialized = false\n private writing = false\n private sequence = 0\n private loggedWriteFailure = false\n private readonly recent: PluginLogEntry[] = []\n private readonly directory: string | null\n private readonly anchor: string | null\n private readonly profile: string | undefined\n private readonly minimum: PluginLogLevel\n private readonly now: () => Date\n private readonly pid: number\n private readonly maxFileBytes: number\n private readonly maxArchiveBytes: number\n private readonly maxAgeMs: number\n private readonly recentLimit: number\n\n constructor(source: string, options: RotatingPluginLoggerOptions & { anchor?: string | null } = {}) {\n this.source = normalizePluginLogSource(source)\n const env = options.env ?? process.env\n const resolved = options.directory !== undefined || options.home !== undefined\n ? resolveHostLogTarget(undefined, options)\n : { directory: null, anchor: options.anchor ?? null, profile: options.profile }\n this.directory = resolved.directory\n this.anchor = options.anchor ?? resolved.anchor\n this.profile = options.profile ?? resolved.profile\n this.file = this.directory ? join(this.directory, `${this.source}.jsonl`) : null\n this.minimum = options.minimumLevel ?? parsePluginLogLevel(env.DSH_PLUGIN_LOG_LEVEL, this.source, DEFAULT_PLUGIN_LOG_LEVEL)\n this.now = options.now ?? (() => new Date())\n this.pid = options.pid ?? process.pid\n this.maxFileBytes = options.maxFileBytes ?? PLUGIN_LOG_MAX_FILE_BYTES\n this.maxArchiveBytes = options.maxArchiveBytes ?? PLUGIN_LOG_MAX_ARCHIVE_BYTES\n this.maxAgeMs = options.maxAgeMs ?? PLUGIN_LOG_MAX_AGE_MS\n this.recentLimit = Math.max(1, options.recentLimit ?? PLUGIN_LOG_RECENT_LIMIT)\n }\n\n get lastWriteError(): string | null {\n return this.lastError\n }\n\n recentEntries(limit = this.recentLimit): PluginLogEntry[] {\n return this.recent.slice(-Math.max(0, limit))\n }\n\n debug(event: string, message: string, context?: PluginLogContext): boolean {\n return this.write({ level: 'debug', event, message, ...(context ? { context } : {}) })\n }\n\n info(event: string, message: string, context?: PluginLogContext): boolean {\n return this.write({ level: 'info', event, message, ...(context ? { context } : {}) })\n }\n\n warn(event: string, message: string, error?: unknown, context?: PluginLogContext): boolean {\n return this.write({\n level: 'warn', event, message,\n ...(error !== undefined ? { error } : {}),\n ...(context ? { context } : {}),\n })\n }\n\n error(event: string, message: string, error?: unknown, context?: PluginLogContext): boolean {\n return this.write({\n level: 'error', event, message,\n ...(error !== undefined ? { error } : {}),\n ...(context ? { context } : {}),\n })\n }\n\n fault(event: string, message: string, error?: unknown, context?: PluginLogContext): boolean {\n return this.write({\n level: 'fault', event, message,\n ...(error !== undefined ? { error } : {}),\n ...(context ? { context } : {}),\n })\n }\n\n child(context: PluginLogContext): PluginLogger {\n return createChildPluginLogger(this, context)\n }\n\n write(input: PluginLogInput): boolean {\n if (!pluginLogLevelEnabled(input.level, this.minimum) || this.writing) return false\n const at = this.now()\n let entry: PluginLogEntry\n let line: string\n try {\n entry = buildPluginLogEntry(input, {\n at,\n source: this.source,\n surface: 'host',\n profile: this.profile,\n pid: this.pid,\n correlation: correlationStorage.getStore(),\n })\n line = `${JSON.stringify(entry)}\\n`\n } catch {\n return false\n }\n this.pushRecent(entry)\n if (!this.directory || !this.file) return true\n this.writing = true\n try {\n this.openManagedDirectory()\n this.prepare(at)\n if (\n this.size > 0\n && (this.size + Buffer.byteLength(line) > this.maxFileBytes || at.getTime() - this.openedAt >= this.maxAgeMs)\n ) {\n this.rotate(at)\n }\n appendFileSync(this.file, line, { encoding: 'utf8', mode: 0o600 })\n this.size += Buffer.byteLength(line)\n this.prune(at)\n this.lastError = null\n this.loggedWriteFailure = false\n return true\n } catch (error) {\n const detail = sanitizePluginLogText(error instanceof Error ? error.message : String(error), 500)\n this.lastError = `The plugin diagnostic log could not be written: ${detail}`\n this.initialized = false\n if (!this.loggedWriteFailure) {\n this.loggedWriteFailure = true\n try {\n process.stderr.write(`DSH Plugin (${this.source}): ${this.lastError}. The original operation continues unchanged.\\n`)\n } catch {\n // Broken stderr must never affect caller behavior.\n }\n }\n return false\n } finally {\n this.writing = false\n }\n }\n\n private pushRecent(entry: PluginLogEntry): void {\n this.recent.push(entry)\n const overflow = this.recent.length - this.recentLimit\n if (overflow > 0) this.recent.splice(0, overflow)\n }\n\n private prepare(at: Date): void {\n if (this.initialized || !this.file) return\n this.openManagedDirectory()\n const stat = this.regularFile(this.file)\n this.size = stat?.size ?? 0\n const stamps = stat ? [stat.birthtimeMs, stat.mtimeMs].filter(value => value > 0) : []\n this.openedAt = stamps.length ? Math.min(...stamps) : at.getTime()\n this.initialized = true\n }\n\n private rotate(at: Date): void {\n if (!this.directory || !this.file) return\n const stamp = at.toISOString().replace(/:/g, '-')\n const name = `${this.source}.${stamp}.${this.pid}.${this.sequence++}.jsonl`\n if (!ARCHIVE_RE.test(name)) throw new Error('Diagnostic log archive name is invalid.')\n const archive = join(this.directory, name)\n if (lexists(archive)) throw new Error('Diagnostic log archive already exists.')\n try {\n renameSync(this.file, archive)\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code\n if (code === 'ENOENT') {\n this.size = 0\n this.openedAt = at.getTime()\n return\n }\n throw error\n }\n this.size = 0\n this.openedAt = at.getTime()\n }\n\n private rotateStaleActive(at: Date): void {\n if (!this.file) return\n const stat = this.regularFile(this.file)\n if (!stat || stat.size === 0) return\n if (at.getTime() - stat.mtimeMs < this.maxAgeMs) return\n this.rotate(at)\n }\n\n private prune(at: Date): void {\n if (!this.directory) return\n this.rotateStaleActive(at)\n const archives: Array<{ name: string; size: number; mtime: number }> = []\n let total = 0\n for (const name of readdirSync(this.directory)) {\n if (!ARCHIVE_RE.test(name) || !name.startsWith(`${this.source}.`)) continue\n const file = join(this.directory, name)\n const stat = lstatSync(file)\n if (stat.isSymbolicLink() || !stat.isFile()) throw new Error('Diagnostic log archive is not a regular file.')\n if (at.getTime() - stat.mtimeMs >= this.maxAgeMs) {\n try { unlinkSync(file) } catch { /* concurrent prune */ }\n continue\n }\n archives.push({ name, size: stat.size, mtime: stat.mtimeMs })\n total += stat.size\n }\n archives.sort((left, right) => left.mtime - right.mtime || left.name.localeCompare(right.name))\n while (total > this.maxArchiveBytes && archives.length) {\n const oldest = archives.shift()!\n try { unlinkSync(join(this.directory, oldest.name)) } catch { /* concurrent prune */ }\n total -= oldest.size\n }\n }\n\n private openManagedDirectory(): void {\n if (!this.directory) return\n if (this.anchor) {\n const anchorStat = existsSync(this.anchor) ? lstatSync(this.anchor) : undefined\n if (anchorStat?.isSymbolicLink()) throw new Error('Diagnostic log anchor cannot be a symbolic link.')\n }\n mkdirSync(this.directory, { recursive: true, mode: 0o700 })\n const stat = lstatSync(this.directory)\n if (stat.isSymbolicLink() || !stat.isDirectory()) {\n throw new Error('Diagnostic log directory is not a real directory.')\n }\n const realDir = realpathSync(this.directory)\n if (this.anchor) {\n const realAnchor = realpathSync(this.anchor)\n if (!isInside(realAnchor, realDir)) {\n throw new Error('Diagnostic log directory escaped its managed root.')\n }\n }\n }\n\n private regularFile(file: string): { size: number; birthtimeMs: number; mtimeMs: number } | undefined {\n try {\n const stat = lstatSync(file)\n if (stat.isSymbolicLink() || !stat.isFile()) throw new Error('Diagnostic log is not a regular file.')\n const expected = join(realpathSync(dirname(file)), basename(file))\n if (!samePath(realpathSync(file), expected)) throw new Error('Diagnostic log path could not be verified.')\n return stat\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined\n throw error\n }\n }\n}\n\nexport function createPluginLogger(\n ctxOrSource: unknown,\n maybeSource?: string | RotatingPluginLoggerOptions,\n maybeOptions?: RotatingPluginLoggerOptions,\n): PluginLogger {\n const hasCtx = typeof ctxOrSource !== 'string'\n const ctx = hasCtx ? ctxOrSource : undefined\n const source = hasCtx ? String(maybeSource ?? 'dsh-plugin') : ctxOrSource\n const options = (hasCtx ? maybeOptions : maybeSource as RotatingPluginLoggerOptions | undefined) ?? {}\n const normalized = normalizePluginLogSource(source)\n const target = resolveHostLogTarget(ctx, options)\n\n let backing: RotatingPluginLogger\n const canShare = Boolean(\n target.directory\n && options.minimumLevel === undefined\n && options.now === undefined\n && options.pid === undefined\n && options.maxFileBytes === undefined\n && options.maxArchiveBytes === undefined\n && options.maxAgeMs === undefined,\n )\n if (canShare && target.directory) {\n const key = resolve(target.directory, `${normalized}.jsonl`)\n let shared = processFileLoggers.get(key)\n if (!shared) {\n shared = new RotatingPluginLogger(normalized, {\n ...options,\n directory: target.directory,\n anchor: target.anchor,\n profile: target.profile,\n })\n processFileLoggers.set(key, shared)\n }\n backing = shared\n } else {\n backing = new RotatingPluginLogger(normalized, {\n ...options,\n ...(target.directory ? { directory: target.directory, anchor: target.anchor } : {}),\n ...(target.profile ? { profile: target.profile } : {}),\n })\n }\n\n if (options.forwardHostWarnError === false || !ctx || typeof ctx !== 'object') {\n return backing\n }\n return wrapWithHostForwarding(backing, ctx as HostContextLike)\n}\n\nexport function installPluginLogger(\n ctx: unknown,\n source: string,\n options: InstallPluginLoggerOptions = {},\n): PluginLogger {\n const logger = createPluginLogger(ctx, source, options)\n logger.info('plugin.loaded', 'Host plugin initialized.', options.loadedContext)\n const host = ctx && typeof ctx === 'object' ? ctx as HostContextLike : undefined\n if (typeof host?.effect === 'function') {\n try {\n host.effect(() => () => {\n logger.debug('plugin.disposed', 'Host plugin disposed.')\n }, `${logger.source}.logger`)\n } catch {\n // Non-Cordis or mock effect implementation.\n }\n }\n return logger\n}\n\nfunction wrapWithHostForwarding(backing: PluginLogger, host: HostContextLike): PluginLogger {\n const forward = (input: PluginLogInput) => {\n if (input.level !== 'warn' && input.level !== 'error' && input.level !== 'fault') return\n try {\n const hostLogger = host.logger\n if (!hostLogger) return\n const detail = input.error instanceof Error\n ? `${input.message} (${input.error.message})`\n : input.error !== undefined\n ? `${input.message} (${String(input.error)})`\n : input.message\n const text = sanitizePluginLogText(`${backing.source} [${input.event}]: ${detail}`, 1_000)\n if (input.level === 'warn') {\n if (typeof hostLogger.warn === 'function') hostLogger.warn(text)\n } else if (typeof hostLogger.error === 'function') {\n hostLogger.error(text)\n } else if (typeof hostLogger.warn === 'function') {\n hostLogger.warn(text)\n }\n } catch {\n // Host logger forwarding is best-effort.\n }\n }\n const wrapped: PluginLogger = {\n get source() { return backing.source },\n get file() { return backing.file },\n get lastWriteError() { return backing.lastWriteError },\n debug: (event, message, context) => backing.debug(event, message, context),\n info: (event, message, context) => backing.info(event, message, context),\n warn: (event, message, error, context) => {\n const wrote = backing.warn(event, message, error, context)\n forward({ level: 'warn', event, message, error, context })\n return wrote\n },\n error: (event, message, error, context) => {\n const wrote = backing.error(event, message, error, context)\n forward({ level: 'error', event, message, error, context })\n return wrote\n },\n fault: (event, message, error, context) => {\n const wrote = backing.fault(event, message, error, context)\n forward({ level: 'fault', event, message, error, context })\n return wrote\n },\n write: input => {\n const wrote = backing.write(input)\n forward(input)\n return wrote\n },\n child: context => createChildPluginLogger(wrapped, context),\n }\n return wrapped\n}\n\nexport function nextPluginOperationId(prefix = 'op'): string {\n return `${normalizePluginLogSource(prefix)}-${process.pid}-${++operationSequence}`\n}\n\nexport function currentPluginLogContext(): PluginLogContext | undefined {\n return correlationStorage.getStore()\n}\n\nexport function withPluginLogContext<T>(context: PluginLogContext, action: () => T): T {\n const merged = mergePluginLogContext(correlationStorage.getStore(), context) ?? {}\n return correlationStorage.run(merged, action)\n}\n\nexport async function pluginLogStep<T>(\n logger: PluginLogger,\n step: string,\n context: PluginLogContext | undefined,\n action: () => Promise<T>,\n completedLevel: PluginLogLevel = 'debug',\n): Promise<T> {\n const started = Date.now()\n const base = { ...context, step }\n logger.debug('step.started', 'Operation step started.', base)\n try {\n const result = await action()\n logger.write({\n level: completedLevel,\n event: 'step.completed',\n message: 'Operation step completed.',\n context: { ...base, durationMs: Date.now() - started },\n })\n return result\n } catch (error) {\n logger.error('step.failed', 'Operation step failed.', error, {\n ...base,\n durationMs: Date.now() - started,\n })\n throw error\n }\n}\n\nexport function pluginLogSyncStep<T>(\n logger: PluginLogger,\n step: string,\n context: PluginLogContext | undefined,\n action: () => T,\n completedLevel: PluginLogLevel = 'debug',\n): T {\n const started = Date.now()\n const base = { ...context, step }\n logger.debug('step.started', 'Operation step started.', base)\n try {\n const result = action()\n logger.write({\n level: completedLevel,\n event: 'step.completed',\n message: 'Operation step completed.',\n context: { ...base, durationMs: Date.now() - started },\n })\n return result\n } catch (error) {\n logger.error('step.failed', 'Operation step failed.', error, {\n ...base,\n durationMs: Date.now() - started,\n })\n throw error\n }\n}\n\nexport function readPluginLogTail(file: string, maxBytes = 256 * 1024): string {\n const stat = lstatSync(file)\n if (stat.isSymbolicLink() || !stat.isFile()) throw new Error('Diagnostic log is not a regular file.')\n if (stat.size <= 0 || maxBytes <= 0) return ''\n const length = Math.min(stat.size, maxBytes)\n const descriptor = openSync(file, 'r')\n try {\n const buffer = Buffer.alloc(length)\n const read = readSync(descriptor, buffer, 0, buffer.length, stat.size - length)\n let text = buffer.subarray(0, read).toString('utf8')\n if (stat.size > length) {\n const newline = text.indexOf('\\n')\n text = newline === -1 ? '' : text.slice(newline + 1)\n }\n return text\n } finally {\n closeSync(descriptor)\n }\n}\n\nfunction lexists(file: string): boolean {\n try {\n lstatSync(file)\n return true\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return false\n throw error\n }\n}\n\nfunction pathFromBaseUrl(baseUrl: string): string | null {\n try {\n return baseUrl.includes('://') ? resolve(fileURLToPath(baseUrl)) : resolve(baseUrl)\n } catch {\n return null\n }\n}\n\nfunction samePath(left: string, right: string): boolean {\n const a = resolve(left)\n const b = resolve(right)\n return process.platform === 'win32' ? a.toLowerCase() === b.toLowerCase() : a === b\n}\n\nfunction isInside(root: string, target: string): boolean {\n const rootResolved = resolve(root)\n const targetResolved = resolve(target)\n if (samePath(rootResolved, targetResolved)) return true\n const prefix = rootResolved.endsWith(sep) ? rootResolved : rootResolved + sep\n return process.platform === 'win32'\n ? targetResolved.toLowerCase().startsWith(prefix.toLowerCase())\n : targetResolved.startsWith(prefix)\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { RpcResult } from './contracts.ts'\nimport { nextPluginOperationId, withPluginLogContext, type PluginLogger } from './logger.ts'\n\nexport interface HostRpcContext {\n webServer: { register(route: { kind: 'prefix'; path: string; handler(req: IncomingMessage, res: ServerResponse): void | Promise<void> }): () => void }\n connection: { requestRejection?: (request: IncomingMessage) => number | undefined }\n}\n\ntype Rejection = { status: number; body?: string }\n\nexport interface HostRpcTransportOptions {\n maxBodyBytes?: number\n isEndpoint?: (endpoint: string) => boolean\n caseInsensitiveContentType?: boolean\n emptyBodyAsNull?: boolean\n beforeBody?: (request: IncomingMessage, endpoint: string) => Rejection | undefined\n errorBody?: (status: number, error?: unknown) => string | undefined\n logger?: PluginLogger\n}\n\nexport interface HostRpcOptions extends HostRpcTransportOptions {\n requirePayload?: boolean\n}\n\n/** The shared authenticated HTTP boundary. Each plugin still owns its RPC envelope semantics. */\nexport function registerHostRpcTransport(\n ctx: HostRpcContext,\n channel: string,\n dispatch: (endpoint: string, body: unknown, signal: AbortSignal, response: ServerResponse) => void | Promise<void>,\n options: HostRpcTransportOptions = {},\n): () => void {\n const bodyLimit = options.maxBodyBytes ?? 64 * 1024\n if (!Number.isSafeInteger(bodyLimit) || bodyLimit <= 0) throw new Error('Invalid RPC body limit')\n const isEndpoint = options.isEndpoint ?? ((endpoint: string) => /^[a-z.]+$/.test(endpoint))\n const log = options.logger\n return ctx.webServer.register({ kind: 'prefix', path: channel, handler: async (req, res) => {\n const reject = (status: number, error?: unknown, override?: string) => {\n if (res.destroyed) return\n if (status === 413) res.writeHead(status, { connection: 'close' })\n else res.writeHead(status)\n res.end(override ?? options.errorBody?.(status, error) ?? (status === 500 ? 'rpc request failed' : ''))\n }\n let endpoint = ''\n try {\n // Host admission always runs before plugin-specific checks or body reads.\n if (typeof ctx.connection.requestRejection !== 'function') {\n log?.error('rpc.admission.unavailable', 'Host RPC admission policy is unavailable.', undefined, { channel, status: 503 })\n reject(503)\n return\n }\n const rejection = ctx.connection.requestRejection(req)\n if (rejection !== undefined) {\n log?.warn('rpc.admission.rejected', 'Host RPC request rejected by connection policy.', undefined, { channel, status: rejection })\n reject(rejection)\n return\n }\n const pathname = new URL(req.url ?? '/', 'http://dsh.internal').pathname\n endpoint = pathname.startsWith(`${channel}/`) ? pathname.slice(channel.length + 1) : ''\n if (req.method !== 'POST' || !isEndpoint(endpoint)) {\n log?.debug('rpc.route.rejected', 'Host RPC route or method rejected.', { channel, endpoint: endpoint || null, method: req.method ?? null, status: 404 })\n reject(404)\n return\n }\n const contentType = String(req.headers['content-type'] ?? '').split(';', 1)[0]?.trim()\n if ((options.caseInsensitiveContentType ? contentType.toLowerCase() : contentType) !== 'application/json') {\n log?.debug('rpc.content-type.rejected', 'Host RPC content-type rejected.', { channel, endpoint, status: 415 })\n reject(415); return\n }\n const guarded = options.beforeBody?.(req, endpoint)\n if (guarded) {\n log?.debug('rpc.guard.rejected', 'Host RPC request rejected before body read.', { channel, endpoint, status: guarded.status })\n reject(guarded.status, undefined, guarded.body)\n return\n }\n\n const controller = new AbortController()\n res.on('close', () => { if (!res.writableEnded) controller.abort() })\n const chunks: Buffer[] = []\n let size = 0\n for await (const chunk of req) {\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n size += buffer.length\n if (size > bodyLimit) {\n log?.warn('rpc.body.too-large', 'Host RPC request exceeded body limit.', undefined, { channel, endpoint, maxBodyBytes: bodyLimit })\n reject(413); req.destroy(); return\n }\n chunks.push(buffer)\n }\n let body: unknown\n try { body = JSON.parse(Buffer.concat(chunks).toString('utf8') || (options.emptyBodyAsNull ? 'null' : '')) }\n catch {\n log?.debug('rpc.body.invalid-json', 'Host RPC request body is not valid JSON.', { channel, endpoint, status: 400 })\n reject(400)\n return\n }\n if (log) {\n await withPluginLogContext(\n { rpcChannel: channel, rpcEndpoint: endpoint, operationId: nextPluginOperationId('rpc') },\n () => dispatch(endpoint, body, controller.signal, res),\n )\n } else {\n await dispatch(endpoint, body, controller.signal, res)\n }\n } catch (error) {\n log?.error('rpc.dispatch.failed', 'Unhandled host RPC handler error.', error, { channel, endpoint: endpoint || null, status: 500 })\n reject(500, error)\n }\n } })\n}\n\n/** Write the native Connection response envelope after a plugin has handled a request. */\nexport function sendHostRpcResponse(response: ServerResponse, rpcId: string, result: unknown, noStore = true): void {\n if (response.destroyed) return\n response.writeHead(200, { 'content-type': 'application/json', ...(noStore ? { 'cache-control': 'no-store' } : {}) })\n response.end(JSON.stringify({ type: 'server-response', rpcId, result }))\n}\n\n/** Safe host RPC registration. Missing requestRejection fails closed. */\nexport function registerHostRpc<R extends RpcResult = RpcResult>(\n ctx: HostRpcContext,\n channel: string,\n call: (endpoint: string, payload: unknown, signal: AbortSignal) => Promise<R>,\n options: HostRpcOptions = {},\n): () => void {\n const log = options.logger\n return registerHostRpcTransport(ctx, channel, async (endpoint, body, signal, res) => {\n if (!body || typeof body !== 'object' || Array.isArray(body)) {\n log?.debug('rpc.envelope.invalid', 'Host RPC envelope must be a JSON object.', { channel, endpoint })\n res.writeHead(400); res.end(); return\n }\n const request = body as Record<string, unknown>\n if (request.type !== 'client-request' || request.method !== endpoint || typeof request.rpcId !== 'string'\n || (options.requirePayload && !Object.hasOwn(request, 'payload'))) {\n log?.debug('rpc.envelope.invalid', 'Host RPC envelope failed validation.', { channel, endpoint })\n res.writeHead(400); res.end(); return\n }\n const started = Date.now()\n const raw = await call(endpoint, request.payload, signal)\n const durationMs = Date.now() - started\n if (raw.ok) {\n log?.debug('rpc.call.completed', 'Host RPC call succeeded.', { channel, endpoint, durationMs })\n } else {\n log?.warn('rpc.call.error', 'Host RPC call returned an application error.', undefined, {\n channel, endpoint, code: raw.error?.code ?? null, durationMs,\n })\n }\n const result = raw.ok ? raw : { ...raw, error: { details: {}, ...raw.error } }\n sendHostRpcResponse(res, request.rpcId, result)\n }, options)\n}\n","import { randomUUID } from 'node:crypto'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type { ObjectJsonSchema } from '@deepseek-ai/dsh-tools'\nimport { createUserMessage } from '@deepseek-ai/dsh-llm'\nimport { registerHostRpc, type HostRpcContext } from '@klarkxy/dsh-plugin-kit/host-rpc'\nimport { installPluginLogger, type PluginLogger } from '@klarkxy/dsh-plugin-kit/logger'\nimport { checkShownView, validateViewAnswer, viewSummary } from './core/index.js'\nimport { answerText } from './answer-text.ts'\nimport { HOST_SERVICE, PLUGIN_NAME, RPC_CHANNEL, VIEW_OWNER, isRecord, type DeepViewHost, type PendingView, type RpcResult, type ShownView, type ViewNode, type ViewPresentation, type ViewAnswerMetadata } from './contracts.ts'\n\nexport const name = 'deep-view'\nexport const inject = ['tools', 'sessionController', 'sessions', 'agents', 'connection', 'webServer'] as const\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context { [HOST_SERVICE]: DeepViewHost }\n}\n\nconst MAX_REDIRECTS = 256\n\nexport function resolveSessionId(redirects: ReadonlyMap<string, string>, sessionId: string): string {\n let current = sessionId\n const seen = new Set<string>()\n while (!seen.has(current)) {\n seen.add(current)\n const next = redirects.get(current)\n if (!next) break\n current = next\n }\n return current\n}\n\nexport function handoffPendingSession(\n pending: Map<string, PendingView>,\n redirects: Map<string, string>,\n fromSessionId: string,\n toSessionId: string,\n): boolean {\n if (!short(fromSessionId, 200) || !short(toSessionId, 200) || fromSessionId === toSessionId) return false\n const source = resolveSessionId(redirects, fromSessionId)\n const target = resolveSessionId(redirects, toSessionId)\n if (source === target) return false\n redirects.set(source, target)\n if (fromSessionId !== source) redirects.set(fromSessionId, target)\n while (redirects.size > MAX_REDIRECTS) {\n const oldest = redirects.keys().next().value\n if (oldest === undefined) break\n redirects.delete(oldest)\n }\n const record = pending.get(source)\n if (!record) return false\n pending.delete(source)\n if (pending.has(target)) return false\n pending.set(target, { ...record, sessionId: target })\n return true\n}\n\ntype AgentLike = {\n id: string\n session: unknown\n followup(message: ReturnType<typeof createUserMessage>): void\n}\n// The real `agents` service returns the runtime Agent type; our local narrow\n// shape cannot feed includes() against it, so compare by id.\nconst isLiveRoot = (host: Host, agent: AgentLike | undefined) => agent !== undefined && host.agents.roots().some(root => (root as unknown as AgentLike).id === agent.id)\ntype Host = Context & HostRpcContext & {\n tools: {\n get(name: string, scope?: object): unknown\n register(definition: Record<string, unknown>): () => void\n }\n agents: { get(id: string): AgentLike | undefined; roots(): AgentLike[] }\n sessionController: { resolveAgent(id: string): Promise<{ agent?: AgentLike; error?: { message?: string } }> }\n sessions: { flush(session: unknown): Promise<boolean> }\n logger?: { warn(message: string, ...args: unknown[]): void }\n}\nconst ok = <T,>(value: T): RpcResult<T> => ({ ok: true, value })\nconst fail = (code: string, message: string): RpcResult<never> => ({ ok: false, error: { code, message } })\nconst short = (value: unknown, max = 160): value is string => typeof value === 'string' && value.length > 0 && value.length <= max\nconst checkedShown = (title: unknown, view: unknown) => checkShownView(title, view) as ShownView | { error: string }\nconst isShown = (value: ShownView | { error: string }): value is ShownView => !('error' in value)\n\n// The host snapshots presentationMeta as JSON on every result, so a result\n// without a card reports null; undefined fails the whole call as invalid output.\nfunction presentation(args: unknown, value: unknown): ViewPresentation | null {\n if (!isRecord(value) || value.owner !== VIEW_OWNER || !['shown', 'pending'].includes(String(value.status))) return null\n const shown = checkedShown(isRecord(args) ? args.title : undefined, isRecord(args) ? args.view : undefined)\n if (!isShown(shown)) return null\n return {\n owner: VIEW_OWNER, ...(short(value.viewId, 80) ? { viewId: value.viewId } : {}),\n ...shown, awaitReply: value.awaitReply === true,\n }\n}\n\nexport function createShowViewTool(\n host: Host,\n pending: Map<string, PendingView>,\n makeId: () => string = randomUUID,\n logger?: PluginLogger,\n): Record<string, unknown> {\n return {\n name: 'show_view',\n description: [\n 'Attach one card below your final reply when a visual or interactive form beats prose: compared numbers, a trend, a share, progress; an estimate with user-adjustable inputs; or a choice the user answers afterwards (use ask_user_question when you cannot continue without it).',\n 'Prefer plain Markdown otherwise. Call once, then finish the reply; the card is not yet visible when this tool returns.',\n 'Never end on the call, wait or poll, repeat the card JSON, or claim the user saw it. Answers accept one reply, sent as the next user message. Never collect keys, tokens or passwords.',\n ].join(' '),\n // tools.register() takes raw JSON Schema; the per-field DSL is only for defineTool().\n parameters: {\n type: 'object',\n properties: {\n title: { type: 'string', description: 'Short heading above the card.' },\n view: { type: 'object', additionalProperties: true, description: [\n 'One ViewNode, nodes nest under stack|row(children,let?).',\n 'Display: text,metric{label,value},table{columns:[{key,label}],rows:[[cell]]},chart{kind:bar|hbar|line|area|donut,categories,series:[{name?,values}]},progress{percent|value+max},callout{text},sources{items:[{label,url}]}.',\n 'Inputs: slider,number,choice,toggle{id,label,value}. A {\"=\":\"expr\"} formula replaces a value or cell, reading input ids and let names.',\n 'Answers(need await_reply true): options{id,options:[{label,description?}],multi?},confirm{id},form{id,fields:[{id,label,placeholder?}]},submit{id,label}. No html.',\n ].join(' ') },\n await_reply: { type: 'boolean', description: 'Whether this card asks the user for a response.' },\n },\n required: ['view'],\n } satisfies ObjectJsonSchema,\n output: {\n schema: { type: 'object', properties: { owner: { type: 'string', const: VIEW_OWNER }, status: { type: 'string' }, viewId: { type: 'string' }, awaitReply: { type: 'boolean' }, summary: { type: 'string' } }, required: ['owner', 'status', 'awaitReply', 'summary'], additionalProperties: false },\n render: (_args: unknown, value: { summary?: string }) => [{ type: 'text', text: String(value.summary ?? '') }],\n presentationMeta: presentation,\n },\n async execute(args: unknown, exec: { agent?: AgentLike; callId?: string; concludeTurn(): void }) {\n const input = isRecord(args) ? args : {}\n const shown = checkedShown(input.title, input.view)\n if (!isShown(shown)) {\n logger?.debug('view.invalid', 'Rejected invalid show_view arguments.', {\n sessionId: exec.agent?.id ?? null,\n reason: shown.error,\n })\n return { owner: VIEW_OWNER, status: 'invalid', awaitReply: false, summary: shown.error }\n }\n if (typeof input.await_reply !== 'undefined' && typeof input.await_reply !== 'boolean') {\n return { owner: VIEW_OWNER, status: 'invalid', awaitReply: false, summary: 'await_reply: expected true or false' }\n }\n const awaitReply = input.await_reply ?? shown.interactive\n if (awaitReply !== shown.interactive) {\n return { owner: VIEW_OWNER, status: 'invalid', awaitReply: false, summary: shown.interactive ? 'This card has answer controls; omit await_reply or set it true.' : 'A display-only card cannot wait for an answer; omit await_reply or set it false.' }\n }\n const id = exec.agent?.id\n const agent = id === undefined ? undefined : host.agents.get(id)\n if (awaitReply && !isLiveRoot(host, agent)) {\n logger?.debug('view.non-root-rejected', 'Rejected interactive show_view outside a live root session.', {\n sessionId: id ?? null,\n })\n return { owner: VIEW_OWNER, status: 'invalid', awaitReply: false, summary: 'An interactive view only works in a live root session. Put the question or decision in your response instead.' }\n }\n let viewId: string | undefined\n if (awaitReply && agent) {\n viewId = makeId()\n // set() alone replaces an earlier unanswered card: the old card becomes\n // stale and its pending record points at the newest view only.\n pending.set(agent.id, { id: viewId, sessionId: agent.id, ...(exec.callId ? { callId: exec.callId } : {}), ...shown })\n }\n logger?.info('view.prepared', 'Prepared Deep View card.', {\n sessionId: agent?.id ?? id ?? null,\n viewId: viewId ?? null,\n awaitReply,\n })\n return {\n owner: VIEW_OWNER, status: awaitReply ? 'pending' : 'shown', ...(viewId ? { viewId } : {}), awaitReply,\n // A tool result is process data. The completed-turn reply surface owns\n // the card, so the model must still produce its final answer.\n summary: `Card prepared for the final reply. Finish with a concise final answer; do not call this tool again for the same card.${awaitReply ? ' The user can answer the card after your reply finishes; do not wait or poll.' : ''} ${viewSummary(shown.view)}`,\n }\n },\n isConcurrencySafe: () => false,\n }\n}\n\nexport function createRpc(\n host: Host,\n pending: Map<string, PendingView>,\n redirects: ReadonlyMap<string, string> = new Map(),\n logger?: PluginLogger,\n) {\n const claims = new Set<string>()\n return async (endpoint: string, payload: unknown, signal: AbortSignal): Promise<RpcResult> => {\n if (!isRecord(payload) || !short(payload.sessionId, 200)) return fail('bad-request', 'A bounded sessionId is required')\n const sessionId = resolveSessionId(redirects, payload.sessionId)\n const record = pending.get(sessionId)\n if (endpoint === 'pending') return ok(record?.callId === payload.callId || payload.callId === undefined ? record ?? null : null)\n if (endpoint === 'dismiss') {\n if (record && record.id === payload.viewId) {\n pending.delete(sessionId)\n logger?.debug('view.dismissed', 'Dismissed pending Deep View card.', { sessionId, viewId: record.id })\n }\n return ok(true)\n }\n if (endpoint !== 'reply') return fail('not-found', 'Unknown Deep View endpoint')\n if (!record || !short(payload.viewId, 80) || payload.viewId !== record.id || !short(payload.action, 160) || !isRecord(payload.values)) {\n logger?.debug('reply.stale', 'Rejected reply for stale or closed Deep View card.', { sessionId })\n return fail('stale', 'This view is no longer open')\n }\n if (claims.has(record.id)) return fail('busy', 'This view is already being answered')\n const checked = validateViewAnswer(record.view as ViewNode, payload.action, payload.values) as { error?: string } & Record<string, unknown>\n if (checked.error !== undefined) {\n logger?.debug('reply.invalid', 'Rejected invalid Deep View reply.', {\n sessionId,\n viewId: record.id,\n action: payload.action,\n reason: checked.error,\n })\n return fail('invalid', checked.error)\n }\n claims.add(record.id)\n pending.delete(sessionId)\n // Exact-once: the record is restored only when followup never appended a\n // user message. Once appended, a failed checkpoint may lose the card from\n // disk, but re-adding the record would let a retry send the same user\n // answer a second time. Restoration lives in the finally so cancellation\n // returns, resolve failures and append failures share one path.\n let appended = false\n try {\n if (signal.aborted) return fail('cancelled', 'The request was cancelled')\n // A live root answers directly. Plugin-owned root sessions (for example a\n // chat drawn by its own plugin under the subagent origin) are refused by the\n // session controller, so it is only asked to resume sessions that are not live.\n const live = host.agents.get(sessionId)\n const resolved = isLiveRoot(host, live) ? { agent: live } : await host.sessionController.resolveAgent(sessionId)\n const agent = resolved.agent\n if (!agent || host.agents.get(agent.id) !== agent || !host.agents.roots().some(root => (root as unknown as AgentLike).id === agent.id)) throw new Error(('error' in resolved ? resolved.error?.message : undefined) ?? 'The session is not a live root session')\n if (signal.aborted) return fail('cancelled', 'The request was cancelled')\n // Text and answer facts share one durable message: neither can survive\n // without the other, and fork/history boundaries preserve their pairing.\n const deepView: ViewAnswerMetadata = {\n owner: VIEW_OWNER, version: 1,\n answer: { id: record.id, action: payload.action, values: checked },\n }\n agent.followup(createUserMessage({\n content: [{ type: 'text', text: answerText(record, payload.action, checked) }],\n source: { kind: 'user', deepView },\n }))\n appended = true\n await host.sessions.flush(agent.session)\n logger?.info('reply.submitted', 'Submitted Deep View reply to live session.', {\n sessionId: agent.id,\n viewId: record.id,\n action: payload.action,\n })\n return ok({ answered: true })\n } catch (error) {\n logger?.error('reply.failed', 'Failed to deliver Deep View reply.', error, {\n sessionId,\n viewId: record.id,\n action: payload.action,\n appended,\n })\n return fail('internal', error instanceof Error ? error.message : String(error))\n } finally {\n if (!appended && !pending.has(sessionId)) pending.set(sessionId, record)\n claims.delete(record.id)\n }\n }\n}\n\nexport async function apply(ctx: Context): Promise<void> {\n const host = ctx as unknown as Host\n const logger = installPluginLogger(ctx, PLUGIN_NAME, { forwardHostWarnError: false })\n const pending = new Map<string, PendingView>()\n const redirects = new Map<string, string>()\n ctx.provide(HOST_SERVICE, {\n handoffSession: (fromSessionId, toSessionId) => {\n const moved = handoffPendingSession(pending, redirects, fromSessionId, toSessionId)\n if (moved) logger.debug('session.handoff', 'Moved pending Deep View card across session handoff.', { fromSessionId, toSessionId })\n return moved\n },\n })\n ctx.effect(() => {\n if (host.tools.get('show_view')) {\n logger.warn('tool.already-registered', 'show_view is already registered by another plugin; skipping registration.')\n host.logger?.warn('deep-view: show_view is already registered by another plugin; this bundle stays disabled for its own tool')\n return () => {}\n }\n try {\n return host.tools.register(createShowViewTool(host, pending, randomUUID, logger))\n }\n catch (error) {\n logger.warn('tool.register-failed', 'show_view tool registration failed.', error)\n host.logger?.warn('deep-view: show_view registration skipped: %s', error instanceof Error ? error.message : String(error))\n return () => {}\n }\n }, 'deep-view.tool')\n // Only admission events are observed, never scanned. A new human message closes a stale card.\n ctx.effect(() => ctx.on('session/event', (session: { id: string }, event: { type: string; data?: unknown }) => {\n if (event.type !== 'user/message' || !isRecord(event.data) || !isRecord(event.data.source) || event.data.source.kind !== 'user') return\n pending.delete(resolveSessionId(redirects, session.id))\n }), 'deep-view.close-pending')\n ctx.effect(() => registerHostRpc(host, RPC_CHANNEL, createRpc(host, pending, redirects, logger), { maxBodyBytes: 24 * 1024, logger }), 'deep-view.rpc')\n}\n"],"mappings":"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"}
|
package/lib/widget.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { g as ViewNode } from "./contracts2.js";
|
|
2
|
+
import { ComponentType } from "react";
|
|
3
|
+
//#region src/ui.d.ts
|
|
4
|
+
type ViewT = (key: string, params?: Record<string, unknown>) => string;
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region src/chart.d.ts
|
|
7
|
+
type ChartHandle = {
|
|
8
|
+
label: string | null;
|
|
9
|
+
asTable: boolean;
|
|
10
|
+
toggleTable(): void;
|
|
11
|
+
copy(): void;
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/widget.d.ts
|
|
15
|
+
type MarkdownProps = {
|
|
16
|
+
text: string;
|
|
17
|
+
streaming?: boolean;
|
|
18
|
+
labels: ViewLabels;
|
|
19
|
+
variant?: 'body' | 'compact';
|
|
20
|
+
};
|
|
21
|
+
type ViewLabels = {
|
|
22
|
+
code: {
|
|
23
|
+
copyLabel: string;
|
|
24
|
+
copiedLabel: string;
|
|
25
|
+
toolbarLabels?: {
|
|
26
|
+
codeLabel: string;
|
|
27
|
+
wrapLabel: string;
|
|
28
|
+
unwrapLabel: string;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
footnotes: string;
|
|
32
|
+
};
|
|
33
|
+
type Answer = {
|
|
34
|
+
id: string;
|
|
35
|
+
action: string;
|
|
36
|
+
values: Record<string, unknown>;
|
|
37
|
+
};
|
|
38
|
+
type WidgetCardProps = {
|
|
39
|
+
title?: string;
|
|
40
|
+
view: ViewNode;
|
|
41
|
+
onSubmit?: (action: string, values: Record<string, unknown>) => void;
|
|
42
|
+
onDismiss?: () => void;
|
|
43
|
+
busy?: boolean;
|
|
44
|
+
settled?: boolean;
|
|
45
|
+
answer?: Answer | null;
|
|
46
|
+
t?: ViewT;
|
|
47
|
+
labels?: ViewLabels;
|
|
48
|
+
Markdown?: ComponentType<MarkdownProps>;
|
|
49
|
+
localOnly?: boolean;
|
|
50
|
+
};
|
|
51
|
+
type Ctx = {
|
|
52
|
+
values: Record<string, unknown>;
|
|
53
|
+
setInput(id: string, value: unknown): void;
|
|
54
|
+
lookup(name: string): unknown;
|
|
55
|
+
locked: boolean;
|
|
56
|
+
answerLocked: boolean;
|
|
57
|
+
busy: boolean;
|
|
58
|
+
settled: boolean;
|
|
59
|
+
answer?: Answer | null;
|
|
60
|
+
onSubmit?: (action: string, values: Record<string, unknown>) => void;
|
|
61
|
+
registerChart(key: string, handle: ChartHandle): (() => void) | void;
|
|
62
|
+
refreshCharts(): void;
|
|
63
|
+
};
|
|
64
|
+
declare function WidgetView({ view, onSubmit, settled, answer, busy, registerChart, refreshCharts, t, labels, Markdown }: Omit<WidgetCardProps, 'title'> & {
|
|
65
|
+
registerChart: Ctx['registerChart'];
|
|
66
|
+
refreshCharts: () => void;
|
|
67
|
+
}): import("react").JSX.Element;
|
|
68
|
+
declare function WidgetCard({ title, view, onSubmit, onDismiss, busy, settled, answer, t, labels, Markdown, localOnly }: WidgetCardProps): import("react").JSX.Element;
|
|
69
|
+
//#endregion
|
|
70
|
+
export { Answer, MarkdownProps, ViewLabels, WidgetCard, WidgetCardProps, WidgetView };
|
|
71
|
+
//# sourceMappingURL=widget.d.ts.map
|