@adhdev/mesh-shared 1.0.79 → 1.0.80-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/json.ts","../src/git-normalize.ts","../src/session-normalize.ts","../src/node-normalize.ts","../src/node-facts.ts","../src/workspace-normalize.ts","../src/daemon-normalize.ts","../src/git-summarize.ts","../src/git-diff.ts","../src/brain-routing.ts","../src/slot-proposal.ts","../src/interpolation.ts","../src/mesh-tool-names.ts","../src/mesh-status-probe.ts","../src/rpc-chunking.ts","../src/semver-compare.ts","../src/protocol/envelope.ts","../src/protocol/daemon-server.ts","../src/protocol/dashboard-server.ts","../src/protocol/dashboard-daemon-p2p.ts","../src/protocol/dashboard-wire-version.ts","../src/ws-protocol.ts","../src/interactive-prompt-constants.ts","../src/session-status.ts","../src/mesh-vocabulary.ts","../src/outbound-message.ts","../src/mission-brief.ts","../src/worker-protocol.ts","../src/assistant-protocol.ts","../src/turn-evidence.ts","../src/session-launch.ts","../src/turn-ipc-guards.ts","../src/turn-ipc-turn.ts","../src/turn-ipc-mission.ts","../src/turn-ipc-queue.ts","../src/turn-ipc-stats.ts","../src/turn-ipc.ts","../src/path-ownership.ts","../src/keyed-doc-delta.ts"],"sourcesContent":["/**\n * @adhdev/mesh-shared — pure, dependency-free mesh/git status normalizers shared\n * by daemon-core (standalone / local IPC) and web-core (cloud / P2P transit).\n *\n * This package exists to kill a recurring bug class: the cloud and standalone\n * transports each used to carry their own hand-synced copy of these normalizers,\n * and they drifted (cloud would strip/reshape fields, the web filter would drop\n * entries the standalone path kept). Both cores now import this single source of\n * truth. It MUST stay a pure leaf — types + pure functions on plain JS objects,\n * no Node/DOM APIs, no git exec, no transport, and an empty dependency set.\n */\n\nexport * from './json'\nexport * from './types'\nexport * from './git-normalize'\nexport * from './session-normalize'\nexport * from './node-normalize'\nexport * from './node-facts'\nexport * from './workspace-normalize'\nexport * from './daemon-normalize'\nexport * from './git-summarize'\nexport * from './git-diff'\nexport * from './brain-routing'\nexport * from './slot-proposal'\nexport * from './interpolation'\nexport * from './mesh-tool-names'\nexport * from './mesh-status-probe'\nexport * from './rpc-chunking'\nexport * from './semver-compare'\nexport * from './ws-protocol'\nexport * from './interactive-prompt-constants'\nexport * from './session-status'\nexport * from './mesh-vocabulary'\nexport * from './outbound-message'\nexport * from './worker-protocol'\nexport * from './assistant-protocol'\nexport * from './protocol'\nexport * from './turn-evidence'\nexport * from './session-launch'\nexport * from './turn-ipc'\nexport * from './path-ownership'\nexport * from './mission-brief'\nexport * from './keyed-doc-delta'\n","/**\n * Pure JSON-record reading primitives shared by the cloud (web-core / P2P transit)\n * and standalone (daemon-core / local IPC) mesh normalizers.\n *\n * These operate only on plain JS values — no Node/DOM APIs, no transport, no git\n * exec — so both cores can import them without violating the core↔core dependency\n * ban. They are the single source of truth for the field-coercion rules that the\n * two transports previously hand-synced (and drifted on).\n */\n\nexport type JsonRecord = Record<string, unknown>\n\nexport function readRecord(value: unknown): JsonRecord {\n return value && typeof value === 'object' && !Array.isArray(value) ? value as JsonRecord : {}\n}\n\n/** A plain-object record, or undefined — for callers that must tell \"absent\" from \"empty\". */\nexport function readOptionalRecord(value: unknown): JsonRecord | undefined {\n return value && typeof value === 'object' && !Array.isArray(value) ? value as JsonRecord : undefined\n}\n\nexport function readString(...values: unknown[]): string | undefined {\n for (const value of values) {\n if (typeof value !== 'string') continue\n const trimmed = value.trim()\n if (trimmed) return trimmed\n }\n return undefined\n}\n\n/** The first non-blank trimmed string, or '' — readString for callers that want a plain string. */\nexport function readText(...values: unknown[]): string {\n return readString(...values) ?? ''\n}\n\nexport function readNumber(...values: unknown[]): number | undefined {\n for (const value of values) {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n }\n return undefined\n}\n\nexport function readBoolean(...values: unknown[]): boolean | undefined {\n for (const value of values) {\n if (typeof value === 'boolean') return value\n }\n return undefined\n}\n\nexport function readStringArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((entry): entry is string => typeof entry === 'string' && entry.trim().length > 0)\n : []\n}\n\n/**\n * Coerce a value that is either an already-parsed plain object or a JSON string\n * into a plain object record. Arrays, primitives, parse failures and empty\n * strings all collapse to {} — callers treat the result as a best-effort record.\n *\n * This is the single source of truth for the `parseJsonRecord`/`parseJsonObject`\n * coercion that cloud mesh normalizers previously hand-redefined per file.\n */\nexport function parseJsonRecord(value: unknown): JsonRecord {\n if (!value) return {}\n if (typeof value === 'object') return readRecord(value)\n if (typeof value !== 'string') return {}\n const trimmed = value.trim()\n if (!trimmed) return {}\n try {\n return readRecord(JSON.parse(trimmed))\n } catch {\n return {}\n }\n}\n\n/**\n * Join a (possibly absent) repo root with a relative submodule path. Returns the\n * path unchanged when it is already absolute, and undefined when nothing usable\n * can be derived — callers must treat the result as optional.\n */\nexport function joinRepoPath(root: string | undefined, relativePath: string | undefined): string | undefined {\n const normalizedRoot = typeof root === 'string' ? root.trim().replace(/[\\\\/]+$/, '') : ''\n const normalizedPath = typeof relativePath === 'string' ? relativePath.trim() : ''\n if (!normalizedPath) return undefined\n if (/^(?:[A-Za-z]:[\\\\/]|\\/)/.test(normalizedPath)) return normalizedPath\n if (!normalizedRoot) return undefined\n return `${normalizedRoot}/${normalizedPath.replace(/^[\\\\/]+/, '')}`\n}\n","/**\n * Canonical git-status normalizers shared by the cloud (web-core) and standalone\n * (daemon-core router) mesh paths. Previously each transport hand-maintained its\n * own copy and they drifted (e.g. submodule drop rules, evidence checks); this is\n * the one implementation both import.\n */\n\nimport { joinRepoPath, readBoolean, readNumber, readRecord, readString, type JsonRecord } from './json'\nimport type { DaemonBuildBehind, GitRepoStatus, GitSubmoduleStatus, GitUpstreamFreshness } from './types'\n\nexport function scoreGitUpstreamFreshness(status: GitUpstreamFreshness | undefined): number {\n switch (status) {\n case 'fresh':\n return 30\n case 'no_upstream':\n return 4\n case 'unchecked':\n case undefined:\n return 0\n case 'stale':\n return -10\n case 'unavailable':\n return -15\n default:\n return 0\n }\n}\n\nexport function readGitSubmodules(value: unknown, parentRepoRoot?: string): GitSubmoduleStatus[] | undefined {\n if (!Array.isArray(value)) return undefined\n const submodules = value\n .map(entry => {\n const submodule = readRecord(entry)\n const path = readString(submodule.path)\n const commit = readString(submodule.commit)\n const repoPath = readString(submodule.repoPath, submodule.repo_root)\n ?? joinRepoPath(parentRepoRoot, path)\n // repoPath is only used for the submodule node's display workspace, which is\n // allowed to be empty. The cloud P2P transit path can deliver submodule entries\n // without repoPath (and a per-node git object without a derivable repoRoot), so\n // dropping on missing repoPath would silently strip every submodule graph node.\n // Keep any submodule that carries both path and commit.\n if (!path || !commit) return null\n const result: GitSubmoduleStatus = {\n path,\n commit,\n dirty: readBoolean(submodule.dirty) ?? false,\n outOfSync: readBoolean(submodule.outOfSync, submodule.out_of_sync) ?? false,\n }\n const lastCheckedAt = readNumber(submodule.lastCheckedAt, submodule.last_checked_at)\n if (lastCheckedAt !== undefined) result.lastCheckedAt = lastCheckedAt\n if (repoPath) result.repoPath = repoPath\n const error = readString(submodule.error)\n if (error) result.error = error\n return result\n })\n .filter((entry): entry is GitSubmoduleStatus => entry !== null)\n return submodules.length > 0 ? submodules : undefined\n}\n\nexport function hasGitStatusEvidence(status: JsonRecord): boolean {\n // BUG FIX: a transit-reshaped git status that carries only a repoRoot/workspace\n // (e.g. cloud P2P stripped the branch/upstream/counters but kept the path) must\n // NOT be dropped — otherwise the node loses its git object and any submodules\n // hanging off it. Treat a present repoRoot/repo_root/workspace as evidence too.\n return readBoolean(status.isGitRepo) !== undefined\n || Boolean(readString(status.branch, status.upstream, status.upstreamStatus, status.upstream_status, status.headCommit))\n || Boolean(readString(status.repoRoot, status.repo_root, status.workspace))\n || readNumber(\n status.ahead,\n status.behind,\n status.staged,\n status.modified,\n status.untracked,\n status.deleted,\n status.renamed,\n status.lastCheckedAt,\n status.last_checked_at,\n ) !== undefined\n || (Array.isArray(status.submodules) && status.submodules.length > 0)\n}\n\nexport function normalizeGitStatus(\n status: JsonRecord,\n node: JsonRecord,\n options?: { lastCheckedAt?: number },\n): GitRepoStatus | undefined {\n const explicitIsGitRepo = readBoolean(status.isGitRepo)\n if (!Object.keys(status).length || !hasGitStatusEvidence(status)) return undefined\n const isGitRepo = explicitIsGitRepo ?? true\n const conflictFiles = Array.isArray(status.conflictFiles)\n ? status.conflictFiles.filter((entry): entry is string => typeof entry === 'string')\n : []\n const conflictCount = readNumber(status.conflicts) ?? conflictFiles.length\n const hasConflicts = readBoolean(status.hasConflicts) ?? conflictCount > 0\n // node.workspace is in the fallback chain so a transit node carrying its path only\n // on the node (not the inner git object) still yields a parentRepoRoot for submodules.\n const repoRoot = readString(status.repoRoot, status.repo_root, node.repoRoot, node.repo_root, status.workspace, node.workspace) || undefined\n const submodules = readGitSubmodules(status.submodules, repoRoot)\n const upstreamStatus = readString(status.upstreamStatus, status.upstream_status)\n const upstreamFetchedAt = readNumber(status.upstreamFetchedAt, status.upstream_fetched_at)\n const upstreamFetchError = readString(status.upstreamFetchError, status.upstream_fetch_error)\n const error = readString(status.error)\n const staged = readNumber(status.staged) ?? 0\n const modified = readNumber(status.modified) ?? 0\n const untracked = readNumber(status.untracked) ?? 0\n const deleted = readNumber(status.deleted) ?? 0\n const renamed = readNumber(status.renamed) ?? 0\n const lastCheckedAt = options?.lastCheckedAt ?? readNumber(status.lastCheckedAt, status.last_checked_at)\n return {\n workspace: readString(status.workspace, node.workspace) || '',\n repoRoot: repoRoot ?? null,\n isGitRepo,\n branch: readString(status.branch) ?? null,\n headCommit: readString(status.headCommit) ?? null,\n headMessage: readString(status.headMessage) ?? null,\n upstream: readString(status.upstream) ?? null,\n upstreamStatus: (upstreamStatus as GitUpstreamFreshness) ?? 'unchecked',\n ...(upstreamFetchedAt !== undefined ? { upstreamFetchedAt } : {}),\n ...(upstreamFetchError ? { upstreamFetchError } : {}),\n ahead: readNumber(status.ahead) ?? 0,\n behind: readNumber(status.behind) ?? 0,\n staged,\n modified,\n untracked,\n deleted,\n renamed,\n dirty: readBoolean(status.dirty, status.isDirty, status.is_dirty) ?? (staged + modified + untracked + deleted + renamed > 0 || hasConflicts),\n hasConflicts,\n conflictFiles,\n stashCount: readNumber(status.stashCount, status.stash_count) ?? 0,\n ...(lastCheckedAt !== undefined ? { lastCheckedAt } : {}),\n ...(submodules ? { submodules } : {}),\n // Deploy-lag visibility: daemonBuildBehind is computed by the reporting\n // daemon's git probe (build commit vs workspace/submodule HEAD). It must\n // survive relay reassembly or downstream staleDaemonBuild surfaces\n // (dashboard Status tab badge, MCP staleDaemonBuilds warning) never fire\n // for remote nodes.\n ...(status.daemonBuildBehind && typeof status.daemonBuildBehind === 'object'\n ? { daemonBuildBehind: status.daemonBuildBehind as unknown as DaemonBuildBehind }\n : {}),\n ...(error ? { error } : {}),\n }\n}\n\nexport function scoreGitStatusCandidate(git: GitRepoStatus | undefined): number {\n if (!git) return Number.NEGATIVE_INFINITY\n let score = 0\n if (git.isGitRepo === true) score += 50\n if (git.isGitRepo === false) score -= 10\n if (git.branch) score += 20\n if (git.headCommit) score += 20\n if (git.upstream) score += 10\n score += scoreGitUpstreamFreshness(git.upstreamStatus)\n if (typeof git.ahead === 'number') score += 2\n if (typeof git.behind === 'number') score += 2\n if (Array.isArray(git.submodules) && git.submodules.length > 0) score += 4 + git.submodules.length\n if (git.error) score -= 20\n return score\n}\n\n/**\n * Pick the best git status out of the four transit envelope slots a mesh node can\n * carry: lastGit.status, lastGit.result.status, lastProbe.git.status,\n * lastProbe.git.result.status. Returns undefined when none carry git evidence.\n */\nexport function pickBestTransitGitStatus(node: JsonRecord, options?: { lastCheckedAt?: number }): GitRepoStatus | undefined {\n const rawGit = readRecord(node.lastGit ?? node.last_git)\n const gitResult = readRecord(rawGit.result)\n const directStatus = readRecord(rawGit.status)\n const nestedStatus = readRecord(gitResult.status)\n const rawProbe = readRecord(node.lastProbe ?? node.last_probe)\n const probeGit = readRecord(rawProbe.git)\n const probeGitResult = readRecord(probeGit.result)\n const probeDirectStatus = readRecord(probeGit.status)\n const probeNestedStatus = readRecord(probeGitResult.status)\n let best: { git: GitRepoStatus; score: number } | null = null\n for (const status of [directStatus, nestedStatus, probeDirectStatus, probeNestedStatus]) {\n const normalized = normalizeGitStatus(status, node, options)\n if (!normalized) continue\n const score = scoreGitStatusCandidate(normalized)\n if (!best || score > best.score) best = { git: normalized, score }\n }\n return best?.git\n}\n","/**\n * Canonical mesh-session record normalizer shared by the cloud (web-core) mesh\n * paths. Parses an already-transit-shaped session record into a typed\n * RepoMeshSessionStatus.\n */\n\nimport { readBoolean, readRecord, readString } from './json'\nimport type { RepoMeshSessionStatus } from './types'\n\n/**\n * Build a deterministic synthetic session id from a record that has no explicit\n * id. Two transit refreshes of the same logical session produce the same id so\n * downstream dedupe stays stable across refreshes (a random id would create a new\n * node every poll). Derived from the stable identifying fields available on the\n * record; prefixed \"synthetic:\" so callers can tell it apart from a real id.\n */\nfunction deriveSyntheticSessionId(record: ReturnType<typeof readRecord>): string | undefined {\n const parts = [\n readString(record.workspace),\n readString(record.providerType, record.provider),\n readString(record.role),\n readString(record.state, record.status),\n readString(record.title),\n readString(record.createdAt, record.created_at),\n readString(record.startedAt, record.started_at),\n ].filter((part): part is string => Boolean(part))\n if (parts.length === 0) return undefined\n return `synthetic:${parts.join('|')}`\n}\n\n/**\n * Session-id equivalence — the sessionId counterpart of daemonIdsEquivalent /\n * meshNodeIdMatches. A session id is SINGLE-FORM: one canonical UUID minted once\n * via crypto.randomUUID() in the provider instance and carried verbatim across\n * daemons, with no node/daemon-id style serialization variants. Equivalence is\n * therefore an exact match after trimming, never matching an absent/empty id\n * against another absent/empty id. Routing every mesh comparison site through\n * this one predicate keeps that single-form policy in one place (and gives any\n * future session-id aliasing a single seam) instead of scattering raw `===`.\n */\nexport function sessionIdsEquivalent(a: string | null | undefined, b: string | null | undefined): boolean {\n const idA = readString(a)\n const idB = readString(b)\n if (!idA || !idB) return false\n return idA === idB\n}\n\nexport function normalizeMeshSessionRecord(entry: unknown): RepoMeshSessionStatus | null {\n const record = readRecord(entry)\n // BUG FIX: cloud transit can reshape/strip the explicit id field. Fall back\n // through sessionId → session_id → id, then to a DETERMINISTIC synthetic id\n // derived from record content so the session survives the round trip instead\n // of being dropped (and so dedupe stays stable across refreshes). Return null\n // ONLY when the record carries no identifying fields at all.\n const sessionId = readString(record.sessionId, record.session_id, record.id)\n ?? deriveSyntheticSessionId(record)\n if (!sessionId) return null\n return {\n sessionId,\n ...(readString(record.providerType, record.provider) ? { providerType: readString(record.providerType, record.provider) } : {}),\n ...(readString(record.state, record.status) ? { state: readString(record.state, record.status) } : {}),\n ...(readString(record.chatStatus, record.chat_status) ? { chatStatus: readString(record.chatStatus, record.chat_status) } : {}),\n ...(readString(record.lifecycle) ? { lifecycle: readString(record.lifecycle) as RepoMeshSessionStatus['lifecycle'] } : {}),\n ...(readString(record.surfaceKind, record.surface_kind) ? { surfaceKind: readString(record.surfaceKind, record.surface_kind) as RepoMeshSessionStatus['surfaceKind'] } : {}),\n ...(readString(record.recoveryState, record.recovery_state) ? { recoveryState: readString(record.recoveryState, record.recovery_state) } : {}),\n ...(readString(record.workspace) ? { workspace: readString(record.workspace) } : {}),\n ...(readString(record.title) ? { title: readString(record.title) } : {}),\n ...(readString(record.role) ? { role: readString(record.role) } : {}),\n ...(readBoolean(record.isSelfCoordinator, record.is_self_coordinator) !== undefined ? { isSelfCoordinator: readBoolean(record.isSelfCoordinator, record.is_self_coordinator) } : {}),\n ...(readString(record.statusNote, record.status_note) ? { statusNote: readString(record.statusNote, record.status_note) } : {}),\n ...(readString(record.createdAt, record.created_at) ? { createdAt: readString(record.createdAt, record.created_at) } : {}),\n ...(readString(record.startedAt, record.started_at) ? { startedAt: readString(record.startedAt, record.started_at) } : {}),\n ...(readString(record.lastActivityAt, record.last_activity_at) ? { lastActivityAt: readString(record.lastActivityAt, record.last_activity_at) } : {}),\n ...(readBoolean(record.isCached, record.is_cached) !== undefined ? { isCached: readBoolean(record.isCached, record.is_cached) } : {}),\n }\n}\n","/**\n * Canonical mesh-node identity normalizer shared by daemon-core (standalone /\n * local IPC) and web-core (cloud / P2P transit) — the node-id counterpart of\n * session-normalize.ts.\n *\n * A mesh node record can carry its stable identifier under THREE different field\n * names depending on the serialization path it travelled, all with the same\n * value:\n * - `id` — config canonical form (mesh registry / persisted config)\n * - `nodeId` — runtime/wire camelCase form (inline-cache de-serialization,\n * mesh_status output via readStringValue(node.nodeId, node.id))\n * - `node_id` — SQLite DB column form leaked onto the object\n *\n * Comparing only `node.id` (or a 2-way `id ?? nodeId` that omits `node_id`)\n * against a target id silently drops nodes that arrived in another form — e.g. an\n * inline-cached worktree node, leaving a target-routed task permanently pending\n * with a misleading `no_node_satisfies_required_tags` skip. This module is the\n * single 3-way source of truth so every comparison site absorbs all three forms.\n */\n\nimport { readString } from './json'\nimport type { MeshNodeIdentified } from './types'\n\n/**\n * Read a mesh node's stable identifier, absorbing any of the three\n * serialization forms (`id` / `nodeId` / `node_id`). Returns undefined when the\n * record carries no usable id in any form.\n */\nexport function normalizeMeshNodeId(node: MeshNodeIdentified | null | undefined): string | undefined {\n const record = (node && typeof node === 'object' ? node : {}) as MeshNodeIdentified\n return readString(record.id, record.nodeId, record.node_id)\n}\n\n/**\n * Whether a mesh node record matches the given candidate id, comparing the\n * node's normalized id (any form) against the candidate. False when either side\n * is empty — never matches an absent id against an absent candidate.\n */\nexport function meshNodeIdMatches(\n node: MeshNodeIdentified | null | undefined,\n candidateId: string | null | undefined,\n): boolean {\n if (!candidateId) return false\n const trimmed = candidateId.trim()\n if (!trimmed) return false\n return normalizeMeshNodeId(node) === trimmed\n}\n","/**\n * MeshNodeFacts — the versioned per-machine RUNTIME facts bundle a reporting\n * daemon ships wholesale (design: root repo\n * docs/design/2026-07-25-deploy-lag-visibility.md §(a)).\n *\n * The mirror-defect class (a field reaching the dashboard for self nodes but\n * not remote ones, or vice versa) came from every fact being plumbed\n * field-by-field through six reassembly layers. The bundle rule that kills the\n * class: producers build it with ONE builder (daemon-core buildLocalNodeFacts —\n * used by BOTH the reporter envelope and the self-node stamp), and every relay\n * layer passes the object through OPAQUELY — never rebuild it field-by-field.\n * schemaVersion lets future fields ride through old relays untouched.\n *\n * Slots are deliberately NOT part of the bundle: they are coordinator-owned\n * config (REMOTE-NODE-SLOTS-COORDINATOR-LOCAL), not a reported runtime fact.\n */\n\nexport interface MeshNodeFactsDaemonBuild {\n /** Full build commit baked into the running daemon (40-hex). */\n commit?: string\n commitShort?: string\n version?: string\n builtAt?: string\n}\n\n/**\n * One rolling quota window, structurally identical to daemon-core's\n * `QuotaWindow`. Redeclared here rather than imported because this package is a\n * dependency-free leaf (see the header of index.ts) and must never import\n * daemon-core — the dependency arrow points the other way. daemon-core's\n * richer type stays assignable to this one, so the producer passes its snapshot\n * straight through with no mapping layer to drift.\n */\nexport interface MeshNodeFactsQuotaWindow {\n usedPercent: number\n windowMinutes: number\n resetsAt: number | null\n}\n\n/**\n * A provider's quota snapshot as reported by the node that owns the credentials.\n *\n * `status` is the field that matters to a reader: 'ok' means the windows are\n * usable, anything else means they are not. A node that CANNOT read a quota\n * still reports an entry (status 'unavailable'/'error' + metadata.failureKind)\n * rather than omitting the provider — an absent entry means \"this node never\n * told us\", a present failing entry means \"this node looked and could not\n * tell\", and a reader that cannot distinguish those two cannot diagnose\n * anything. Extra provider-specific fields (buckets, monthly) ride through via\n * the index signature.\n */\nexport interface MeshNodeFactsProviderQuota {\n provider: string\n status: string\n session: MeshNodeFactsQuotaWindow | null\n weekly: MeshNodeFactsQuotaWindow | null\n /** 30-day billing-style window, only for providers that report one\n * (cursor-cli). Promoted from the index signature 2026-08-24 so readers\n * can render it typed — an 'ok' cursor snapshot often carries ONLY this\n * axis, and a reader that looks at session/weekly alone misreads a\n * healthy reading as a failure. */\n monthly?: MeshNodeFactsQuotaWindow | null\n /** Per-pool quota buckets, only for providers whose plan has more than one\n * pool (antigravity-cli: Gemini vs Claude/GPT groups, each with a 5h and\n * a weekly bucket). `session`/`weekly` above collapse these to the WORST\n * bucket per window (the routing-safe headline); the buckets carry the\n * per-pool detail a reader should surface. Promoted from the index\n * signature 2026-08-24, same reasoning as `monthly`. */\n buckets?: Array<{\n name?: string\n usedPercent?: number\n windowMinutes?: number\n resetsAt?: number | null\n [extra: string]: unknown\n }> | null\n /** Unix ms of the snapshot itself — older than the bundle's reportedAt. */\n updatedAt: number\n error: string | null\n /**\n * `accountEmail` is PII and rides this bundle because the bundle is\n * P2P/local only — it must never be added to a server-bound payload. See\n * daemon-core `QuotaMetadata.accountEmail` and the regression suite that\n * pins its absence from every server allow-list.\n */\n metadata?: {\n failureKind?: string\n source?: string\n planType?: string | null\n accountEmail?: string | null\n /**\n * True when `session`/`weekly` are NOT this snapshot's own reading but a\n * retained last-good reading carried forward by daemon-core's\n * `carryForwardLastGoodWindows` (quota/refresh.ts) after a TRANSIENT\n * fetch failure (expired token, network blip, rate limit). `status` on\n * this same entry is the fresh failure, not 'ok' — the numbers are real,\n * just not from THIS tick. A reader should label them (e.g. \"· refreshing\")\n * rather than presenting them as a freshly measured value.\n */\n lastGoodWindows?: boolean\n /**\n * Unix ms when the reporting node last ATTEMPTED a refresh of this\n * provider — deliberately distinct from `updatedAt`, which dates the\n * DATA. They differ for file-source providers (claude-cli reports its\n * statusline snapshot's capture time, codex-cli the rollout entry's),\n * whose `updatedAt` does not move while the source file is unchanged\n * however often it is successfully re-read.\n *\n * A reader judging FRESHNESS wants `updatedAt`. This field answers the\n * different question \"is that node still looking?\", which is what makes\n * \"3h old but re-checked a minute ago\" distinguishable from \"3h old and\n * nobody has looked since\". Absent on entries written by daemons\n * predating the field.\n */\n fetchedAt?: number\n [extra: string]: unknown\n }\n [extra: string]: unknown\n}\n\n/**\n * One provider's enablement state on the reporting machine — see\n * `MeshNodeFacts.providerEnablement`.\n *\n * Both fields are REQUIRED booleans on the wire even though the underlying\n * config defaults are asymmetric (`enabled` defaults false, `quotaEnabled`\n * defaults true). The producer resolves those defaults before stamping, so a\n * reader never re-derives them — a second copy of the default rules is exactly\n * the drift this shape avoids. Absence is expressed by omitting the whole\n * provider entry (or the whole bundle field), never by a missing sub-field.\n */\nexport interface MeshNodeFactsProviderEnablement {\n /** \"This machine uses provider X\" — gates launching and mesh claims. */\n enabled: boolean\n /** \"...and its quota is probed here\" — an independent user opt-out. */\n quotaEnabled: boolean\n}\n\nexport interface MeshNodeFacts {\n schemaVersion: number\n reportedAt: number\n daemonBuild?: MeshNodeFactsDaemonBuild\n providerVersions?: Record<string, string>\n /**\n * Verified-channel PIN per provider type: which provider MANIFEST the node\n * actually loads. NOT the same as `providerVersions`, which is the CLI\n * BINARY version — a node can run kimi-code 1.2.3 while pinned to kimi\n * spec 1.0.0. Keep them separate; folding them would repeat the\n * multi-identifier confusion behind the canon-identity defect class.\n *\n * This is what makes a remote node's pin knowable. Provider fixes do not\n * propagate on their own (the pin advances only on an explicit\n * activation, by design), so without this field a node that never adopted\n * a published fix looks exactly like one that did.\n *\n * A missing entry means \"no pin\", never a fabricated value.\n */\n providerSpecPins?: Record<string, string>\n platform?: string\n arch?: string\n machineNickname?: string\n /**\n * Per-provider quota snapshots, keyed by QuotaProvider id ('claude-cli',\n * 'codex-cli', 'cursor-cli', 'kimi'). Consumed by ROUTING as well as observation: the\n * coordinator's quota gate / spread bonus (daemon-core mesh-quota-routing.ts,\n * thresholds in RepoMeshPolicy.quotaRouting) reads exactly this shape, so\n * field renames here are a routing-contract change, not a cosmetic one.\n * Both consumers fail open on missing/stale data.\n *\n * Freshness is `Date.now() - reportedAt` (the bundle stamp) plus each\n * entry's own `updatedAt`; there is deliberately NO ttl/expiry field here,\n * because refresh cadence is owned by the reporting node and the delivery\n * cadence by whoever calls git_status. Neither end is in a position to\n * assert a TTL, so readers judge age themselves (the routing consumer's\n * rule: quotaSnapshotAgeMs in daemon-core mesh-quota-routing.ts).\n */\n quota?: Record<string, MeshNodeFactsProviderQuota>\n /**\n * Per-provider ENABLEMENT state on the reporting machine, keyed the same\n * way as `quota`. Exists because `quota` alone cannot answer \"why is there\n * no snapshot\": a provider that is disabled — on either axis — is pruned\n * from the quota cache entirely (daemon-core quota/refresh.ts drops it and\n * refuses to restore it from disk), so a deliberate opt-out and a\n * never-yet-measured provider both arrive as the SAME absent entry. On the\n * node that owns the config that ambiguity is resolvable by reading the\n * config; for every OTHER node in the mesh it was not resolvable at all,\n * which is what this field fixes.\n *\n * The two axes mirror ProviderLoader exactly and are INDEPENDENT:\n * `enabled` is \"this machine uses provider X\" (gates launching and mesh\n * claims), `quotaEnabled` gates ONLY the quota probe — a machine can use a\n * provider and still opt out of having its usage read.\n *\n * ★An ABSENT bundle field means \"this node did not tell us\" — a daemon too\n * old to send it — and must NEVER be read as \"disabled\". The consumer\n * (daemon-core mesh-quota-routing.ts classifyAbsentQuotaReason) keeps its\n * unclassified fallback for exactly that case; treating absence as\n * disabled would invent a fail-closed verdict out of a missing field.\n *\n * Booleans keyed by provider type only — no free text, no credentials.\n */\n providerEnablement?: Record<string, MeshNodeFactsProviderEnablement>\n /** Future fields ride through opaquely — do not enumerate them in relays. */\n [extra: string]: unknown\n}\n\n/**\n * Validate the minimal envelope shape and pass EVERYTHING else through\n * untouched. Returns undefined for anything that is not a v1+ bundle so\n * callers skip the stamp instead of shipping garbage.\n */\nexport function normalizeMeshNodeFacts(raw: unknown): MeshNodeFacts | undefined {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return undefined\n const record = raw as Record<string, unknown>\n const schemaVersion = Number(record.schemaVersion)\n const reportedAt = Number(record.reportedAt)\n if (!Number.isFinite(schemaVersion) || schemaVersion < 1) return undefined\n if (!Number.isFinite(reportedAt) || reportedAt <= 0) return undefined\n return { ...record, schemaVersion, reportedAt } as MeshNodeFacts\n}\n\n/**\n * Provider types with a SHIPPED quota fetcher — the providers whose quota can\n * actually be read on a node today.\n *\n * This must mirror `REFRESHERS` in daemon-core's `quota/refresh.ts`, which is\n * the runtime authority: a provider absent from REFRESHERS is never probed, so\n * offering it a quota switch anywhere would promise a control that does\n * nothing. It lives here, in the dependency-free leaf, for the same reason\n * `formatQuotaAccount` does — the machine page and the new-install surfaces are\n * in web-core, the fetchers and the `adhdev setup` wizard reach it from\n * daemon-core, and the dependency arrow only runs one way. This list previously\n * existed as a hand-copied literal in web-core's ProvidersTab; that copy is now\n * derived from this one.\n *\n * Deliberately NOT necessarily the same set as the `QuotaProvider` union in\n * daemon-core's quota/types.ts: that union is the set of valid keys a snapshot\n * can be carried under, while membership HERE means \"a fetcher exists\".\n *\n * Known non-members and why, so this is not re-litigated per surface:\n * - cursor-cli — permanently impossible; no personal usage API exists\n *\n * ★grok-cli WAS listed here as impossible and is not: that verdict came from\n * probing `api.x.ai` / `management-api.x.ai` (the team-API billing axis, which\n * genuinely rejects a CLI OAuth token) and from reading `grok --help`, where\n * the `/usage` view does not appear because it is a TUI slash command. The\n * subscription quota is served by the CLI's own chat proxy — see the endpoint\n * provenance note in daemon-core `quota/fetchers/grok.ts`.\n *\n * ★antigravity-cli was likewise twice judged impossible, from reading\n * `agy --help` where the usage view does not appear because it is a TUI view.\n * Its quota comes from the SHARED Gemini Code Assist backend\n * (`daily-cloudcode-pa.googleapis.com/v1internal:retrieveUserQuotaSummary` —\n * the host `agy` itself uses; the unprefixed `cloudcode-pa` host 429s Google\n * AI Pro Antigravity accounts), and its credential lives in the OS keyring,\n * not the stale on-disk token file — see the provenance note in daemon-core\n * `quota/fetchers/antigravity.ts`. Supported on macOS and Windows; other\n * platforms report `unsupported` rather than guess at a keyring backend\n * nobody has verified.\n *\n * ★Adding a provider here without adding its fetcher to REFRESHERS re-creates\n * exactly the \"switch that does nothing\" this constant prevents.\n */\nexport const QUOTA_SUPPORTED_PROVIDERS: readonly string[] = [\n 'antigravity-cli',\n 'claude-cli',\n 'codex-cli',\n 'cursor-cli',\n 'grok-cli',\n 'kimi',\n 'opencode',\n]\n\n/** Whether this provider's quota can be probed at all — see QUOTA_SUPPORTED_PROVIDERS. */\nexport function supportsQuota(providerType: string | undefined | null): boolean {\n return !!providerType && QUOTA_SUPPORTED_PROVIDERS.includes(providerType)\n}\n\n/**\n * The account/plan label for a provider quota row: \"you@example.com · Plus\".\n *\n * Lives HERE, in the dependency-free leaf, because both renderers need it and\n * they cannot share code any other way: the dashboards are in web-core and the\n * `adhdev quota` CLI is in daemon-core, and the dependency arrow runs\n * web-core → daemon-core, never back. Duplicating the formatter in the CLI is\n * what produced the drift this function exists to prevent — the CLI showed no\n * account at all while the UI showed one.\n *\n * Both halves are optional and independent: codex reports both, kimi reports\n * neither, and Claude Code exposes no account at all. Returns null when there\n * is nothing to say, so a provider without an account renders no empty slot and\n * no \"unknown\" placeholder — the absence is simply invisible, in every surface.\n *\n * ★The email is PII travelling on a P2P-only path. Rendering it locally is\n * fine; it must never be forwarded to a server payload or a push body. See\n * daemon-core QuotaMetadata.accountEmail and the server-boundary suite.\n */\nexport function formatQuotaAccount(quota: MeshNodeFactsProviderQuota | undefined): string | null {\n const meta = quota?.metadata\n const email = typeof meta?.accountEmail === 'string' ? meta.accountEmail.trim() : ''\n const plan = typeof meta?.planType === 'string' ? meta.planType.trim() : ''\n const parts = [email, plan].filter(Boolean)\n return parts.length > 0 ? parts.join(' · ') : null\n}\n\n/**\n * Stable built-in provider order for a DEFAULTED node priority (no operator\n * order known): these first when present, then the rest alphabetically. The\n * `mesh_init` providerPriority suggestion leads with the same list.\n */\nexport const BUILTIN_PROVIDER_PREFERENCE: readonly string[] = ['claude-cli', 'codex-cli', 'gemini-cli']\n\n/** Order provider types by BUILTIN_PROVIDER_PREFERENCE, then alphabetically (de-duplicated). */\nexport function orderProvidersByBuiltinPreference(types: readonly unknown[]): string[] {\n const unique = [...new Set(types.map((t) => (typeof t === 'string' ? t.trim() : '')).filter(Boolean))]\n const rank = (t: string) => {\n const i = BUILTIN_PROVIDER_PREFERENCE.indexOf(t)\n return i < 0 ? BUILTIN_PROVIDER_PREFERENCE.length : i\n }\n return unique.sort((a, b) => rank(a) - rank(b) || a.localeCompare(b))\n}\n\n/**\n * The provider order a node with NO providerPriority and NO capability slots\n * defaults to, from its own facts bundle: the providers it reports enabled\n * (`providerEnablement[type].enabled === true` — the reporting machine's own\n * verdict), narrowed to the CLIs it reports detected (`providerVersions`, the\n * detection pass that stamps binary versions) when any enabled one is listed\n * there. Ordered by BUILTIN_PROVIDER_PREFERENCE.\n *\n * The single rule for every reader — daemon-core auto-launch / slot resolution,\n * the MCP launch readiness + type-omitted launch, the `adhdev mesh` CLI — so a\n * node is not \"launch ready\" on one surface and `missing_provider_priority` on\n * another. Returns [] when nothing usable is reported.\n */\nexport function defaultProviderPriorityFromNodeFacts(facts: unknown): string[] {\n const f = facts && typeof facts === 'object' && !Array.isArray(facts) ? facts as Record<string, unknown> : null\n const enablement = f?.providerEnablement\n if (!enablement || typeof enablement !== 'object' || Array.isArray(enablement)) return []\n const enabled = Object.entries(enablement as Record<string, unknown>)\n .filter(([, v]) => !!v && typeof v === 'object' && (v as Record<string, unknown>).enabled === true)\n .map(([type]) => type)\n const versions = f?.providerVersions\n const detected = versions && typeof versions === 'object' && !Array.isArray(versions)\n ? enabled.filter((type) => {\n const v = (versions as Record<string, unknown>)[type]\n return typeof v === 'string' && !!v.trim()\n })\n : []\n return orderProvidersByBuiltinPreference(detected.length ? detected : enabled)\n}\n","/**\n * Canonical workspace-path normalizer for mesh node/session scope comparison,\n * shared by daemon-core (standalone / local IPC) and any other core that has to\n * tell a base node apart from a co-located worktree clone whose ONLY structural\n * difference is its distinct workspace root.\n *\n * One physical daemon can host a base node plus several worktree nodes. Session\n * records, queue claims, and read_chat requests are scoped to a node by matching\n * the session's actual workspace against the node's declared workspace. Those two\n * paths can arrive in different but equivalent spellings (back/forward slashes,\n * trailing separators, Windows case-insensitivity), so a raw string compare would\n * either falsely separate equal paths or fail to engage at all.\n *\n * This folds separator style, trailing slashes, and case into a single comparable\n * form. It was previously a module-private copy in daemon-core's\n * mesh-events-coordinator.ts (WTCLAIM fix-B); promoting it here keeps the one\n * comparison rule identical across the enqueue→claim path, the mesh_status\n * per-node session filter, and the read_chat node scope guard. Pure string ops —\n * no Node/DOM APIs — so it stays a valid mesh-shared leaf.\n */\nexport function normalizeMeshWorkspaceForCompare(dir?: string | null): string {\n if (typeof dir !== 'string') return ''\n return dir.trim().replace(/[\\\\/]+/g, '/').replace(/\\/+$/, '').toLowerCase()\n}\n\n/**\n * Whether two workspace paths refer to the same workspace root after\n * normalization. Returns false when either side is empty — an unknown workspace\n * never \"matches\" another, so callers must decide separately whether an unknown\n * workspace should be treated permissively (the WTCLAIM convention: unknown →\n * do not block).\n */\nexport function meshWorkspacesEquivalent(a?: string | null, b?: string | null): boolean {\n const left = normalizeMeshWorkspaceForCompare(a)\n const right = normalizeMeshWorkspaceForCompare(b)\n if (!left || !right) return false\n return left === right\n}\n","/**\n * Canonical coordinator/daemon-id form normalizer shared by daemon-core (the mesh\n * reconcile loop, pending-event queue, and MCP surface) — the daemon-id counterpart\n * of node-normalize.ts.\n *\n * A daemon answers to the SAME machine under three interchangeable id forms, all\n * derived from one `mach_<hex>` machine id:\n * - bare — `mach_<hex>` (loadConfig().machineId; stamped by the local\n * queue-assignment dispatch path)\n * - cloud — `daemon_mach_<hex>` (the coordinator mesh node's config-form\n * daemonId, which the MCP layer's resolveCoordinatorDaemonId\n * prefers and stamps onto a worker's meshCoordinatorDaemonId)\n * - standalone — `standalone_mach_<hex>` (a standalone daemon's status instanceId)\n *\n * A worker's completion event is scoped (`coordinator_daemon_id`) with whichever\n * form the dispatch path happened to stamp, but the coordinator that later drains /\n * surfaces that event resolves its OWN id through a different path and frequently\n * holds a DIFFERENT form. Because the scope filter is an exact-string match\n * (`coordinator_daemon_id IS NULL OR IN (...)` in SQL, `.includes()` in JS), a\n * completion stamped `daemon_mach_X` is silently skipped by a coordinator whose\n * self-id set only contains bare `mach_X` (or standalone form) — the event never\n * surfaces and the coordinator is never auto-notified, while NULL-scoped events\n * (e.g. worktree bootstrap) always pass via the `IS NULL` branch.\n *\n * This module is the single source of truth that collapses the three forms to one\n * machine core and EXPANDS a self-id set to every equivalent form, so a scope match\n * succeeds regardless of which form stamped the event. Expansion stays WITHIN a\n * single machine core (`daemon_mach_X` only ever expands to other `mach_X` forms),\n * so an event scoped to a DIFFERENT coordinator is never falsely claimed.\n */\n\nimport { readString } from './json'\n\nconst DAEMON_ID_PREFIXES = ['daemon_', 'standalone_'] as const\n\n/**\n * A daemon DO addressed by a raw 64-hex DO id (`idFromString`) rather than by a\n * canonical name (`idFromName(\"daemon_mach_<hex>\")`). Decide by FORMAT, not by\n * length — the canonical name is 43+ chars, so a `length > 32` heuristic would\n * misclassify it. Mirrors the server's session-routing `isRawDoId`.\n */\nexport function isRawDaemonDoId(id: string | null | undefined): boolean {\n const trimmed = readString(id)\n return !!trimmed && /^[0-9a-f]{64}$/i.test(trimmed)\n}\n\n/** The machine-evidence fields a real daemon reports about its hardware. */\nexport interface DaemonMachineEvidence {\n machineNickname?: string | null\n nickname?: string | null\n hostname?: string | null\n platform?: string | null\n machineId?: string | null\n machine?: { hostname?: string | null; platform?: string | null } | null\n sessions?: unknown[] | null\n}\n\n/**\n * A phantom daemon entry — a UI surface must not offer it as a real machine.\n *\n * Symptom block for the raw-DO-id ghost (GHOST-MACHINE-REGISTRATIONS). When the\n * `X-ADHDEV-Daemon` instanceId header is missing or unparseable, the /ws handler\n * falls back to a random DO name, so every reconnect mints a FRESH raw 64-hex DO\n * id. Those keys accumulate as hardware-less entries that render as a bare hash\n * where a machine name belongs.\n *\n * BOTH conditions are required, and the second is what keeps this safe:\n * 1. the id is a raw DO id — no `daemon_`/`standalone_` canonical prefix.\n * 2. no machine evidence at all — no nickname, hostname, platform, registered\n * machineId, and no sessions.\n *\n * A legacy / not-yet-reauthed daemon that ACTUALLY reports itself fails (2) and\n * therefore still renders, still attaches, and still routes — dropping on (1)\n * alone would make real daemons disappear from the picker. This is strictly a\n * PRESENTATION filter: routing tables (server `lastStatuses`, P2P relay) keep\n * the entry, because the raw key still resolves via `idFromString`.\n *\n * The server applies the same rule to its dashboard payloads via\n * `_unresolvedIdentity` (UserSession.isPhantomMachineEntry). That marker is\n * server-internal and never reaches the browser, and the client daemon store\n * never evicts an entry once injected — so a client surface reading the merged\n * P2P/WS store must re-derive the verdict from the entry SHAPE. This function is\n * that shared rule.\n */\nexport function isPhantomDaemonEntry(\n entry: (DaemonMachineEvidence & { id?: string | null }) | null | undefined,\n): boolean {\n if (!entry) return false\n if (!isRawDaemonDoId(entry.id)) return false\n const hasMachineEvidence = Boolean(\n readString(entry.machineNickname)\n || readString(entry.nickname)\n || readString(entry.hostname)\n || readString(entry.platform)\n || readString(entry.machine?.hostname)\n || readString(entry.machine?.platform)\n || readString(entry.machineId)\n || (Array.isArray(entry.sessions) && entry.sessions.length > 0),\n )\n return !hasMachineEvidence\n}\n\n/**\n * Reduce any daemon-id form to its machine core: strips a leading `daemon_` /\n * `standalone_` prefix, leaving the bare `mach_<hex>` (or returning a non-prefixed\n * id unchanged). Returns undefined for an empty/absent id.\n */\nexport function machineCoreFromDaemonId(id: string | null | undefined): string | undefined {\n const trimmed = readString(id)\n if (!trimmed) return undefined\n for (const prefix of DAEMON_ID_PREFIXES) {\n if (trimmed.startsWith(prefix)) {\n const core = trimmed.slice(prefix.length).trim()\n return core || undefined\n }\n }\n return trimmed\n}\n\n/**\n * Canonicalize any daemon-id form to the single CANON producer form\n * `daemon_mach_<core>` (the cloud `daemon_` form).\n *\n * CANON-IDENTITY double-dispatch root cause: the coordinator daemon id is stamped\n * onto a worker dispatch by TWO independent producers — the MCP-side\n * resolveCoordinatorDaemonId (which prefers the coordinator mesh node's config-form\n * `daemon_mach_X` daemonId) and the daemon-core queue dispatch (which stamps the\n * bare `loadConfig().machineId` = `mach_X`). When the SAME coordinator dispatches\n * the same task down both paths, the two worker sessions are stamped with two\n * DIFFERENT coordinator-id forms; a raw-string dedup that should recognise \"this\n * task is already dispatched by me\" fails, and the task runs twice.\n *\n * The durable fix is comparator-side (daemonIdsEquivalent / expandDaemonIdForms),\n * but unifying every PRODUCER on one canonical form shrinks the surface so even a\n * raw `===` agrees. The canon is the cloud `daemon_` form because that is what the\n * coordinator mesh node's config-form daemonId already carries and what the cloud\n * P2P signaling layer registers a daemon under — so canonicalizing the bare/standalone\n * fallback forms makes them consistent with the already-working primary path.\n *\n * Only a `mach_<…>` core is rewritten; an arbitrary/non-machine id (e.g. a custom\n * node id) is returned unchanged so it is never ballooned into a spurious `daemon_`\n * form. Idempotent. Returns undefined for an empty/absent id.\n */\nexport function canonicalDaemonId(id: string | null | undefined): string | undefined {\n const core = machineCoreFromDaemonId(id)\n if (!core) return undefined\n if (!core.startsWith('mach_')) return core\n return `daemon_${core}`\n}\n\n/** True when both ids resolve to the same machine core — i.e. they are the same\n * daemon under different id forms. False when either side is empty. */\nexport function daemonIdsEquivalent(a: string | null | undefined, b: string | null | undefined): boolean {\n const coreA = machineCoreFromDaemonId(a)\n const coreB = machineCoreFromDaemonId(b)\n if (!coreA || !coreB) return false\n return coreA === coreB\n}\n\n/**\n * Expand a set of coordinator/daemon ids to every equivalent form, so an\n * exact-string scope filter (SQL `IN (...)` or JS `.includes()`) matches a\n * completion stamped in any form of the same machine. The original ids are kept in\n * their input order and FIRST (callers that treat `[0]` as the primary — e.g.\n * per-daemon JSONL file naming — keep their original primary); the derived\n * `mach_<hex>` / `daemon_mach_<hex>` / `standalone_mach_<hex>` forms are appended.\n *\n * Derived prefixed forms are emitted ONLY for a core that looks like a real machine\n * id (`mach_<…>`), so arbitrary/test ids (e.g. `node-daemon-id`) are passed through\n * untouched and never balloon into spurious forms. Result is de-duplicated.\n */\nexport function expandDaemonIdForms(\n ids: string | null | undefined | ReadonlyArray<string | null | undefined>,\n): string[] {\n const list = Array.isArray(ids) ? ids : ids != null ? [ids] : []\n const out: string[] = []\n const seen = new Set<string>()\n const add = (value: string | undefined): void => {\n if (!value || seen.has(value)) return\n seen.add(value)\n out.push(value)\n }\n // Pass 1: originals first, in input order (preserve caller's primary at [0]).\n for (const raw of list) add(readString(raw))\n // Pass 2: derived machine-core forms for any id that resolves to a `mach_` core.\n for (const raw of list) {\n const core = machineCoreFromDaemonId(readString(raw))\n if (!core || !core.startsWith('mach_')) continue\n add(core)\n for (const prefix of DAEMON_ID_PREFIXES) add(`${prefix}${core}`)\n }\n return out\n}\n","/**\n * Canonical compact git-shape summarizer used by debug/log surfaces on both the\n * cloud (daemon-cloud mesh command summarizer) and standalone (daemon-core router\n * RepoMeshStatusDebug) paths. Produces a small, log-safe projection of a git\n * status record — commit SHAs are truncated to 12 chars.\n *\n * Transport-specific envelope unwrapping (result / result.status / top-level)\n * stays in the caller; this takes an already-unwrapped status record.\n */\n\nimport { readBoolean, readNumber, readRecord, readString } from './json'\n\nexport function summarizeGitShape(status: unknown): Record<string, unknown> | null {\n const record = readRecord(status)\n if (!Object.keys(record).length) return null\n const submodules = Array.isArray(record.submodules)\n ? record.submodules.map((entry: unknown) => {\n const sub = readRecord(entry)\n return {\n path: readString(sub.path) ?? null,\n commit: readString(sub.commit)?.slice(0, 12) ?? null,\n dirty: readBoolean(sub.dirty) ?? false,\n outOfSync: readBoolean(sub.outOfSync, sub.out_of_sync) ?? false,\n }\n })\n : []\n return {\n isGitRepo: readBoolean(record.isGitRepo),\n workspace: readString(record.workspace) ?? null,\n repoRoot: readString(record.repoRoot, record.repo_root) ?? null,\n branch: readString(record.branch) ?? null,\n upstream: readString(record.upstream) ?? null,\n upstreamStatus: readString(record.upstreamStatus, record.upstream_status) ?? null,\n headCommit: readString(record.headCommit, record.head_commit)?.slice(0, 12) ?? null,\n ahead: readNumber(record.ahead) ?? null,\n behind: readNumber(record.behind) ?? null,\n dirtyCounts: {\n staged: readNumber(record.staged) ?? 0,\n modified: readNumber(record.modified) ?? 0,\n untracked: readNumber(record.untracked) ?? 0,\n deleted: readNumber(record.deleted) ?? 0,\n renamed: readNumber(record.renamed) ?? 0,\n },\n lastCheckedAt: readNumber(record.lastCheckedAt, record.last_checked_at) ?? null,\n submoduleCount: submodules.length,\n submodules,\n }\n}\n","/**\n * Projection of a daemon `git_diff_file` answer into the per-file row the MCP\n * `git_diff` tool and the cloud git-diff shortcut both return: the diff text\n * capped at `maxLines` (with a visible truncation marker), plus the file's\n * change metadata from the diff summary.\n */\n\nimport { readRecord } from './json'\n\nexport interface GitFileDiffRow {\n path: string\n old_path?: string | null\n status?: string\n diff: string\n truncated: boolean\n binary: boolean\n error?: string\n}\n\n/** Cap diff text at `maxLines`; a truncated diff ends with a `... (truncated)` marker line. */\nfunction truncateDiffText(text: string, maxLines: number): { diff: string; truncated: boolean } {\n const lines = text.split('\\n')\n const truncated = lines.length > maxLines\n return {\n diff: truncated ? lines.slice(0, maxLines).join('\\n') + '\\n... (truncated)' : text,\n truncated,\n }\n}\n\n/** One changed file's row from its `git_diff_file` answer (either `{ diff: {...} }` or the bare diff record). */\nexport function projectFileDiffRow(\n file: { path: string; oldPath?: string | null; status?: string },\n rawResult: unknown,\n maxLines: number,\n): GitFileDiffRow {\n const raw = readRecord(rawResult)\n const d = readRecord(raw.diff ?? rawResult)\n const text = typeof d.diff === 'string' ? d.diff : ''\n const { diff, truncated } = truncateDiffText(text, maxLines)\n return {\n path: file.path,\n old_path: file.oldPath ?? null,\n status: file.status ?? 'M',\n diff,\n truncated,\n binary: typeof d.binary === 'boolean' ? d.binary : false,\n }\n}\n","/**\n * Brain-routing (task difficulty → provider/model/thinking) types.\n *\n * The coordinator classifies each task it enqueues by execution difficulty, and a\n * per-difficulty \"brain\" preset resolves that into a concrete provider / model /\n * thinking-level for the launched session. The goal is token economy: an `easy`\n * task runs on a cheaper model at low reasoning effort; a `difficult` task gets a\n * stronger model at high effort. This picks the single brain that *executes* a\n * task, stored machine-local (`~/.adhdev/meshes.json`).\n */\n\n/** The fixed difficulty axis the coordinator classifies a task into. */\nexport type MeshTaskDifficulty = 'easy' | 'medium' | 'difficult' | 'freeform'\n\nexport const MESH_TASK_DIFFICULTIES: MeshTaskDifficulty[] = ['easy', 'medium', 'difficult', 'freeform']\n\n/**\n * A per-difficulty brain preset: which provider / model / thinking level a task of\n * that difficulty should run on. Every field is optional — a preset may set only a\n * model (keep the routed provider) or only a thinking level. Applied at enqueue:\n * an explicit model/thinkingLevel on the task always wins over the preset.\n */\nexport interface BrainSlot {\n /** Optional provider type, e.g. 'claude-cli' | 'codex-cli'. Absent → keep the tag/priority-routed provider. */\n provider?: string\n /** Optional model, e.g. 'opus' | 'sonnet' | 'haiku'. Best-effort at launch (initialModel). */\n model?: string\n /** Optional standard thinking level, 'low' | 'medium' | 'high'. Best-effort (initialThinkingLevel). */\n thinkingLevel?: 'low' | 'medium' | 'high'\n}\n\n/**\n * Per-difficulty brain bindings for ONE mesh, stored machine-local in\n * `~/.adhdev/meshes.json` under that mesh's entry (`meshes[].difficultyBrains`).\n * The scope is per mesh: two meshes on the same\n * machine hold independent presets, so one can pin `difficult` to a cheaper model\n * without changing what any other mesh runs. (It formerly sat at the config root\n * keyed by difficulty alone — and since this map picks the MODEL a task runs on,\n * that meant the shipped defaults, and any one mesh's override, applied to every\n * mesh on the machine.) A difficulty absent from the map has no preset — the task\n * runs with no difficulty-derived model/thinking (ordinary routing).\n */\nexport type DifficultyBrainMap = Partial<Record<MeshTaskDifficulty, BrainSlot>>\n\n/** True for a recognized difficulty value. */\nexport function isMeshTaskDifficulty(value: unknown): value is MeshTaskDifficulty {\n return typeof value === 'string' && (MESH_TASK_DIFFICULTIES as string[]).includes(value)\n}\n\n/**\n * Shipped difficulty presets: NONE. Operator-authored capability slots are the\n * authority: easy < medium < difficult is a hard minimum (freeform is explicitly\n * unconstrained), while the preset map only supplies optional launch axes.\n *\n * WHY THIS IS EMPTY (it formerly shipped easy→haiku/low, medium→sonnet/medium,\n * difficult→opus/high):\n *\n * 1. WRONG AXIS. `opus`/`sonnet`/`haiku` are Claude model families, but the\n * preset was stamped on a task at ENQUEUE time — before routing has chosen\n * a node, let alone a provider. A `difficult` task therefore carried\n * `model: 'opus'` even when it landed on kimi / codex / antigravity. The\n * CODEX-400 guard (model-provider-compat.ts) exists ONLY to strip these\n * Claude aliases back off before a non-Anthropic launch — a workaround for\n * a value that should never have been stamped provider-blind.\n *\n * 2. IT FOUGHT THE SLOTS. Operators express model choice per node via\n * capability slots (`mesh_node_slots` action \"set\"), which know the provider. A\n * mesh-wide preset that also picks a model duplicated that decision from a\n * position with strictly less information, and needed the modelSource\n * ('explicit' vs 'preset') precedence machinery plus a fail-closed\n * slot-model guard just to keep the slot winning.\n *\n * Removing the shipped defaults does NOT remove the feature: the map is still\n * honored, so an operator who deliberately sets presets (difficulty_brains_set)\n * keeps exactly that behavior. It only stops the mesh from inventing a model\n * nobody configured. A node WITH slots is unaffected (its slots already decided);\n * a node WITHOUT slots now launches on the provider's own default model instead\n * of a Claude alias picked blind.\n */\nexport const DEFAULT_DIFFICULTY_BRAINS: DifficultyBrainMap = {}\n\n/** Normalize a raw thinking level to the standard union, or undefined. */\nexport function normalizeThinkingLevel(value: unknown): 'low' | 'medium' | 'high' | undefined {\n const v = typeof value === 'string' ? value.trim().toLowerCase() : ''\n return v === 'low' || v === 'medium' || v === 'high' ? v : undefined\n}\n\n/** Normalize a raw BrainSlot (trim strings, drop empties, clamp thinkingLevel). */\nexport function normalizeBrainSlot(raw: unknown): BrainSlot {\n const r = (raw && typeof raw === 'object') ? raw as Record<string, unknown> : {}\n const provider = typeof r.provider === 'string' ? r.provider.trim() : ''\n const model = typeof r.model === 'string' ? r.model.trim() : ''\n const thinkingLevel = normalizeThinkingLevel(r.thinkingLevel)\n return {\n ...(provider ? { provider } : {}),\n ...(model ? { model } : {}),\n ...(thinkingLevel ? { thinkingLevel } : {}),\n }\n}\n\n/** Normalize a raw DifficultyBrainMap, dropping unknown keys and empty slots. */\nexport function normalizeDifficultyBrainMap(raw: unknown): DifficultyBrainMap {\n const out: DifficultyBrainMap = {}\n if (!raw || typeof raw !== 'object') return out\n for (const key of MESH_TASK_DIFFICULTIES) {\n const slot = normalizeBrainSlot((raw as Record<string, unknown>)[key])\n if (slot.provider || slot.model || slot.thinkingLevel) out[key] = slot\n }\n return out\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Node capability slots (node capability slots design, 2026-07-09)\n//\n// A node's \"Preferred AI tools\" list is redefined as an ordered array of\n// capability slots. Each slot bundles what used to be scattered across\n// providerPriority (order), a per-provider maxParallel cap, and the\n// the owning mesh's difficultyBrains (difficulty → model/thinking). Slot order =\n// preference. This single profile is the source of truth for task routing and\n// orchestrator-proposed edits.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * One capability slot on a mesh node. Extends the BrainSlot shape\n * (provider/model/thinkingLevel) with the difficulty range it handles, capability\n * tags, and a per-slot parallelism cap.\n */\nexport interface NodeCapabilitySlot {\n /** Provider type this slot uses, e.g. 'claude-cli' | 'codex-cli'. Required (a slot is defined by its provider). */\n provider: string\n /** Optional model, e.g. 'opus' | 'sonnet' | 'haiku'. Best-effort at launch. */\n model?: string\n /**\n * Optional thinking level. The provider's own vocabulary (e.g. low/medium/high,\n * or codex's low/medium/high/max) passed through verbatim — best-effort at\n * launch. A string, not the standard union, so provider-declared levels like\n * 'max' are not dropped.\n */\n thinkingLevel?: string\n /**\n * Difficulty grades this slot handles. On an explicit-slot node these form a\n * hard minimum: higher grades may run lower tasks, but lower grades never run\n * higher tasks. Empty/absent is ungraded and only unconstrained freeform tasks\n * use it; legacy providerPriority-derived slots remain backward-compatible.\n */\n difficulty?: MeshTaskDifficulty[]\n /** Capability tags this slot satisfies (matched against a task's requiredTags). */\n capability?: string[]\n /** Per-node·per-slot max concurrent tasks. Omit = no per-slot cap. */\n maxParallel?: number\n}\n\n/** Normalize a raw NodeCapabilitySlot; returns null when it has no usable provider. */\nexport function normalizeNodeCapabilitySlot(raw: unknown): NodeCapabilitySlot | null {\n const r = (raw && typeof raw === 'object') ? raw as Record<string, unknown> : {}\n const provider = typeof r.provider === 'string' ? r.provider.trim() : ''\n if (!provider) return null\n const model = typeof r.model === 'string' ? r.model.trim() : ''\n // Pass the provider's own thinking-level vocabulary through verbatim (don't\n // clamp to low/medium/high — a provider may declare 'max' etc.).\n const thinkingLevel = typeof r.thinkingLevel === 'string' ? r.thinkingLevel.trim() : ''\n const difficulty = Array.isArray(r.difficulty)\n ? (r.difficulty.filter(isMeshTaskDifficulty) as MeshTaskDifficulty[])\n : []\n const capability = Array.isArray(r.capability)\n ? r.capability.filter((t): t is string => typeof t === 'string' && !!t.trim()).map(t => t.trim())\n : []\n const maxParallelNum = Number(r.maxParallel)\n const maxParallel = Number.isFinite(maxParallelNum) && maxParallelNum > 0 ? Math.floor(maxParallelNum) : undefined\n return {\n provider,\n ...(model ? { model } : {}),\n ...(thinkingLevel ? { thinkingLevel } : {}),\n ...(difficulty.length ? { difficulty } : {}),\n ...(capability.length ? { capability } : {}),\n ...(maxParallel !== undefined ? { maxParallel } : {}),\n }\n}\n\n/** Normalize a raw slot array, dropping provider-less entries. */\nexport function normalizeNodeCapabilitySlots(raw: unknown): NodeCapabilitySlot[] {\n if (!Array.isArray(raw)) return []\n const out: NodeCapabilitySlot[] = []\n for (const entry of raw) {\n const slot = normalizeNodeCapabilitySlot(entry)\n if (slot) out.push(slot)\n }\n return out\n}\n\n/**\n * Back-compat migration: derive capability slots from the legacy fields when a\n * node has no explicit `slots`. Order follows providerPriority; difficulty/model/\n * thinking are folded in from the OWNING MESH's difficultyBrains (each difficulty\n * attaches to the slot whose provider the brain preset names, or — when the brain\n * has no provider — to every slot as a shared model/thinking default for that\n * difficulty).\n *\n * (Legacy nodes' per-provider `maxParallel` cap has been migrated onto\n * `slots[].maxParallel` at config-load time, so it is no longer folded in here.)\n *\n * Returns [] when there's nothing to derive (caller then keeps legacy behavior:\n * first available provider).\n */\nexport function deriveSlotsFromLegacy(input: {\n providerPriority?: string[]\n difficultyBrains?: DifficultyBrainMap\n}): NodeCapabilitySlot[] {\n const priority = Array.isArray(input.providerPriority)\n ? input.providerPriority.filter((p): p is string => typeof p === 'string' && !!p.trim()).map(p => p.trim())\n : []\n if (priority.length === 0) return []\n\n // Brain presets keyed by the provider they name (provider-specific), plus a\n // provider-agnostic list applied to every slot as a shared default.\n const brains = input.difficultyBrains || {}\n const byProvider = new Map<string, Array<{ difficulty: MeshTaskDifficulty; model?: string; thinkingLevel?: 'low' | 'medium' | 'high' }>>()\n const shared: Array<{ difficulty: MeshTaskDifficulty; model?: string; thinkingLevel?: 'low' | 'medium' | 'high' }> = []\n for (const diff of MESH_TASK_DIFFICULTIES) {\n const b = brains[diff]\n if (!b) continue\n const entry = { difficulty: diff, model: b.model, thinkingLevel: b.thinkingLevel }\n if (b.provider) {\n const list = byProvider.get(b.provider) ?? []\n list.push(entry)\n byProvider.set(b.provider, list)\n } else {\n shared.push(entry)\n }\n }\n\n return priority.map((provider): NodeCapabilitySlot => {\n // Provider-specific brain first, else the shared default, else nothing.\n const specific = byProvider.get(provider) || []\n const applied = specific.length ? specific : shared\n const difficulty = applied.map(a => a.difficulty)\n // Fold model/thinking from the applied presets: take the first that sets each.\n const model = applied.find(a => a.model)?.model\n const thinkingLevel = applied.find(a => a.thinkingLevel)?.thinkingLevel\n return {\n provider,\n ...(model ? { model } : {}),\n ...(thinkingLevel ? { thinkingLevel } : {}),\n ...(difficulty.length ? { difficulty } : {}),\n }\n })\n}\n\n/**\n * The reverse direction of deriveSlotsFromLegacy: derive the legacy\n * `providerPriority` order from capability slots — each slot's provider, in\n * first-appearance order, de-duplicated. Slot order = preference is the settled\n * slots semantics (node capability slots design, 2026-07-09), so this is what readers of the\n * legacy `policy.providerPriority` field must fall back to when a node declares\n * slots but no explicit providerPriority (otherwise such a node reads as\n * unlaunchable even though its slots fully determine the preference order).\n *\n * Accepts the raw `policy.slots` value (normalized internally). Returns [] when\n * there's nothing to derive (caller then keeps legacy behavior: no priority).\n */\nexport function deriveProviderPriorityFromSlots(slots: unknown): string[] {\n const seen = new Set<string>()\n const out: string[] = []\n for (const slot of normalizeNodeCapabilitySlots(slots)) {\n if (seen.has(slot.provider)) continue\n seen.add(slot.provider)\n out.push(slot.provider)\n }\n return out\n}\n","/**\n * CLI auto-detect → capability-slot PROPOSAL generator.\n *\n * Detection of installed CLI providers already exists per node (the status\n * snapshot's `availableProviders`), and applying a slot profile already exists\n * (`mesh_node_slots` action \"set\", dry-run by default). What was missing is the bit in\n * between: turning \"these CLIs are installed on this node\" into a concrete\n * `NodeCapabilitySlot[]` draft the operator can review. This module is that\n * bridge, and nothing more — it is a PURE proposal generator. It never writes;\n * the caller feeds its output into the existing dry-run/approve tools.\n *\n * ─── Why the mapping is a static table ───────────────────────────────────────\n *\n * Provider manifests carry NO difficulty or capability-grade information. The\n * fields that look like they might (`modelOptions`, `thinkingLevelOptions`)\n * describe what a provider ACCEPTS, not what it is GOOD AT — a provider listing\n * `opus` says nothing about whether opus should get the hard tasks. So there is\n * no honest way to derive difficulty from the manifest today.\n *\n * The table below is therefore seeded from the operator's real, in-use slot\n * configuration rather than from a guess. That makes it a starting point with\n * actual provenance, and it is deliberately isolated in ONE constant so the\n * planned usage-data-driven replacement has a single, obvious swap point.\n *\n * Kept in the dependency-free mesh-shared leaf because both daemon-core (which\n * has the detection data) and mcp-server (which owns the propose/apply tools)\n * need it, and it is pure data + pure functions on plain objects.\n */\nimport {\n normalizeNodeCapabilitySlot,\n type MeshTaskDifficulty,\n type NodeCapabilitySlot,\n} from './brain-routing'\n\n/**\n * One provider's seeded slot recipe. A provider may map to MORE THAN ONE slot\n * (claude-cli does: a wide sonnet slot plus a narrow opus slot for the hard\n * work), which is why the table's values are arrays.\n */\nexport interface CliSlotRecipe {\n /** Optional model to pin on the slot. Best-effort at launch. */\n model?: string\n /** Optional thinking level, in the provider's own vocabulary. */\n thinkingLevel?: string\n /** Difficulty range this slot handles. Empty = general-purpose. */\n difficulty?: MeshTaskDifficulty[]\n /** Per-slot concurrency cap. */\n maxParallel?: number\n /**\n * Set when this recipe is an unvalidated guess rather than a transcription\n * of a slot the operator actually runs. Surfaced on the proposal so the\n * reviewer knows which lines to scrutinize.\n */\n provisional?: boolean\n /** Short human-readable justification, echoed into the proposal. */\n rationale?: string\n}\n\n/**\n * ★ THE MAPPING TABLE — the single swap point.\n *\n * Seeded (2026-08-03) from the operator's live slot configuration, on the\n * reasoning that a transcription of what is actually in production beats an\n * invented heuristic. Replace wholesale once usage data (success rate, cost,\n * turn latency per provider×difficulty) can drive it.\n *\n * Every entry reflects a real configured slot. A provider absent from the table\n * falls back to {@link UNKNOWN_CLI_SLOT_RECIPE}, the only `provisional` recipe.\n */\nexport const CLI_SLOT_RECIPES: Readonly<Record<string, readonly CliSlotRecipe[]>> = Object.freeze<Record<string, readonly CliSlotRecipe[]>>({\n 'claude-cli': [\n {\n model: 'sonnet',\n thinkingLevel: 'high',\n difficulty: ['medium', 'easy'],\n maxParallel: 5,\n rationale: 'Primary workhorse — widest parallelism for routine work.',\n },\n {\n model: 'opus',\n thinkingLevel: 'high',\n difficulty: ['difficult'],\n maxParallel: 1,\n rationale: 'Reserved for hard tasks; capped at 1 to bound cost.',\n },\n ],\n 'kimi': [\n {\n model: 'kimi-code/k3',\n difficulty: ['medium', 'difficult'],\n maxParallel: 2,\n rationale: 'Independent second opinion on mid/hard work.',\n },\n ],\n 'codex-cli': [\n {\n difficulty: ['medium', 'difficult', 'freeform'],\n maxParallel: 2,\n rationale: 'Broad range including freeform; no model pin.',\n },\n ],\n 'antigravity-cli': [\n {\n model: 'Gemini 3.1 Pro (High)',\n difficulty: ['easy'],\n maxParallel: 2,\n rationale: 'Cheap capacity for easy tasks.',\n },\n ],\n 'cursor-cli': [\n {\n model: 'auto',\n difficulty: ['easy'],\n maxParallel: 1,\n rationale: 'Easy tasks only; auto model selection.',\n },\n ],\n})\n\n/**\n * Fallback for a detected CLI provider absent from {@link CLI_SLOT_RECIPES}.\n * Deliberately timid: one general-purpose slot at the lowest parallelism, so an\n * unrecognized provider can be used but never silently soaks up the queue.\n */\nexport const UNKNOWN_CLI_SLOT_RECIPE: Readonly<CliSlotRecipe> = Object.freeze<CliSlotRecipe>({\n difficulty: ['medium'],\n maxParallel: 1,\n provisional: true,\n rationale: 'Unrecognized provider — conservative default (medium, maxParallel 1). Review before relying on it.',\n})\n\n/** A detected, installed CLI provider on one node — the generator's input. */\nexport interface DetectedCliProvider {\n /** Provider type id, e.g. 'claude-cli'. */\n type: string\n /** Human-readable name, for display in the proposal. */\n displayName?: string\n /** Detected version, when known. Display only — never affects the mapping. */\n version?: string\n}\n\n/** One proposed slot plus why it was proposed. */\nexport interface ProposedSlotEntry {\n slot: NodeCapabilitySlot\n /** True when the provider had no table entry and took the conservative fallback. */\n unknownProvider: boolean\n /** True when the recipe behind this slot is flagged as an unvalidated estimate. */\n provisional: boolean\n rationale?: string\n}\n\n/** The full slot proposal for one node, including what a write would DESTROY. */\nexport interface SlotProposal {\n /** The draft slot list — a WHOLESALE replacement for the node's policy.slots. */\n proposedSlots: NodeCapabilitySlot[]\n /** Per-slot provenance, index-aligned with `proposedSlots`. */\n entries: ProposedSlotEntry[]\n /** Provider types detected but not present in the mapping table. */\n unknownProviders: string[]\n /** Provider types whose proposal rests on an unvalidated estimate. */\n provisionalProviders: string[]\n /**\n * Slots currently configured on the node that the proposal does NOT\n * reproduce — i.e. what applying this proposal would DELETE. Slot writes are\n * wholesale replacements, so an operator-hand-tuned slot absent from the\n * detection-derived draft is silently destroyed unless it is named here.\n */\n droppedSlots: NodeCapabilitySlot[]\n /** Provider types that appear in `droppedSlots` but in no proposed slot at all. */\n droppedProviders: string[]\n /** True when applying the proposal would remove at least one existing slot. */\n destructive: boolean\n}\n\n/** Stable key identifying a slot's identity for current-vs-proposed diffing. */\nfunction slotKey(slot: NodeCapabilitySlot): string {\n return [\n slot.provider,\n slot.model ?? '',\n slot.thinkingLevel ?? '',\n [...(slot.difficulty ?? [])].sort().join('|'),\n [...(slot.capability ?? [])].sort().join('|'),\n slot.maxParallel ?? '',\n ].join('\\u0000')\n}\n\n/** Dedupe detected providers by type, preserving first-seen order. */\nfunction dedupeDetected(detected: readonly DetectedCliProvider[]): DetectedCliProvider[] {\n const seen = new Set<string>()\n const out: DetectedCliProvider[] = []\n for (const d of detected) {\n const type = typeof d?.type === 'string' ? d.type.trim() : ''\n if (!type || seen.has(type)) continue\n seen.add(type)\n out.push({ ...d, type })\n }\n return out\n}\n\n/**\n * Build a capability-slot proposal from a node's detected CLI providers.\n *\n * Pure and total: zero detections yields an empty proposal (never throws), which\n * the caller should treat as \"nothing to propose\" rather than \"replace the\n * node's slots with nothing\".\n *\n * `currentSlots` is optional but strongly recommended — it is the only way the\n * returned proposal can report what a wholesale write would destroy.\n */\nexport function buildSlotProposal(\n detected: readonly DetectedCliProvider[],\n currentSlots: readonly NodeCapabilitySlot[] = [],\n): SlotProposal {\n const providers = dedupeDetected(detected ?? [])\n const proposedSlots: NodeCapabilitySlot[] = []\n const entries: ProposedSlotEntry[] = []\n const unknownProviders: string[] = []\n const provisionalProviders: string[] = []\n\n for (const provider of providers) {\n const known = CLI_SLOT_RECIPES[provider.type]\n const recipes: readonly CliSlotRecipe[] = known ?? [UNKNOWN_CLI_SLOT_RECIPE]\n const isUnknown = !known\n if (isUnknown) unknownProviders.push(provider.type)\n\n let providerProvisional = false\n for (const recipe of recipes) {\n // Normalize through the SAME normalizer the daemon applies on write, so\n // a proposal can never preview a shape the write would reshape.\n const slot = normalizeNodeCapabilitySlot({\n provider: provider.type,\n model: recipe.model,\n thinkingLevel: recipe.thinkingLevel,\n difficulty: recipe.difficulty,\n maxParallel: recipe.maxParallel,\n })\n if (!slot) continue\n const provisional = recipe.provisional === true\n if (provisional) providerProvisional = true\n proposedSlots.push(slot)\n entries.push({\n slot,\n unknownProvider: isUnknown,\n provisional,\n ...(recipe.rationale ? { rationale: recipe.rationale } : {}),\n })\n }\n if (providerProvisional) provisionalProviders.push(provider.type)\n }\n\n // What a wholesale write would destroy: every currently-configured slot with\n // no exact counterpart in the draft.\n const proposedKeys = new Set(proposedSlots.map(slotKey))\n const droppedSlots = currentSlots.filter(slot => !proposedKeys.has(slotKey(slot)))\n const proposedProviders = new Set(proposedSlots.map(s => s.provider))\n const droppedProviders = [...new Set(\n droppedSlots.map(s => s.provider).filter(p => !proposedProviders.has(p)),\n )]\n\n return {\n proposedSlots,\n entries,\n unknownProviders,\n provisionalProviders,\n droppedSlots,\n droppedProviders,\n destructive: droppedSlots.length > 0,\n }\n}\n","\nexport function interpolateString(template: string, ctx: Record<string, unknown>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) => {\n const val = ctx[key];\n return val !== undefined ? String(val) : `{{${key}}}`;\n });\n}\n","/**\n * Canonical Repo Mesh coordinator tool-name registry — the single source of truth\n * the three surfaces must agree on:\n *\n * 1. mcp-server `ALL_MESH_TOOLS` (the published MCP tool schemas),\n * 2. daemon-core `coordinator-prompt.ts` `TOOLS_SECTION` (what the coordinator LLM\n * is told it can call), and\n * 3. the `NN tools` doc comments in the mesh-tools barrels.\n *\n * mcp-server does not depend on daemon-core's internal prompt, and daemon-core cannot\n * import mcp-server (dependency direction: daemon-core ← mcp-server). This dependency-\n * free leaf is the only place both can reference, so the 6-6 consistency test\n * (daemon-core coordinator-prompt.test.ts) and mcp-server both assert against THIS\n * list. Adding a new mesh tool means adding its name here first; the tests then force\n * the schema + prompt + barrel comment to catch up, which is exactly the regression\n * gate that let coordinator-prompt drift 14 tools behind the schema before.\n *\n * Order mirrors mcp-server `ALL_MESH_TOOLS` for easy visual diffing, but the consistency\n * checks are set-based (order-insensitive).\n */\nexport const CANONICAL_MESH_TOOL_NAMES = [\n 'mesh_status',\n 'mesh_route_preview',\n 'mesh_list_nodes',\n // Batch before task, mirroring ALL_MESH_TOOLS.\n 'mesh_enqueue_batch',\n 'mesh_enqueue_task',\n 'mesh_view_queue',\n 'mesh_queue_cancel',\n 'mesh_queue_requeue',\n 'mesh_send_task',\n 'mesh_read_chat',\n 'mesh_read_debug',\n 'mesh_read_terminal',\n 'mesh_send_keys',\n 'mesh_launch_session',\n 'mesh_git_status',\n 'mesh_read_node_logs',\n 'mesh_fast_forward_node',\n 'mesh_restart_daemon',\n 'mesh_checkpoint',\n 'mesh_approve',\n 'mesh_answer_question',\n 'mesh_list_pending_approvals',\n 'mesh_create',\n 'mesh_add_node',\n 'mesh_clone_node',\n 'mesh_remove_node',\n 'mesh_cleanup_worktree_nodes',\n 'mesh_refine_node',\n 'mesh_refine_batch',\n 'mesh_config',\n 'mesh_init',\n 'mesh_cleanup_sessions',\n 'mesh_task_history',\n // Deprecated alias of mesh_task_history (2026-10-08: the kind/since/node query\n // axes moved onto mesh_task_history). Still published for one release so older\n // coordinator prompts keep working; drop it — here, in ALL_MESH_TOOLS, the\n // dispatch table and the prompt index — in the next release.\n 'mesh_ledger_query',\n 'mesh_note',\n 'mesh_reconcile_ledger',\n 'mesh_mission_upsert',\n 'mesh_mission_list',\n 'mesh_review_inbox',\n 'mesh_node_slots',\n] as const;\n\nexport type CanonicalMeshToolName = typeof CANONICAL_MESH_TOOL_NAMES[number];\n\n/** The count the `NN tools` barrel doc comments and consistency test assert against. */\nexport const CANONICAL_MESH_TOOL_COUNT = CANONICAL_MESH_TOOL_NAMES.length;\n\n/**\n * Tool names retired by the 2026-09-26 tool-surface consolidation (60 → 48).\n * Every capability behind them is still reachable: each retired name maps to the\n * merged tool plus the discriminator argument that selects the same behaviour.\n *\n * mcp-server answers a call to a retired name with an error naming the\n * replacement (it does NOT forward silently — a coordinator running an old\n * prompt must learn the new spelling), and the daemon-core coordinator prompt\n * test asserts none of these names is advertised anywhere in the prompt.\n *\n * `args` is the discriminator to add; every other argument keeps its name.\n * `note` carries any extra guidance when an argument moved in a rename.\n */\nexport const RETIRED_MESH_TOOLS: Readonly<Record<string, {\n readonly tool: CanonicalMeshToolName;\n readonly args: Readonly<Record<string, string>>;\n readonly note?: string;\n}>> = {\n mesh_node_slots_set: { tool: 'mesh_node_slots', args: { action: 'set' } },\n mesh_node_slots_list: { tool: 'mesh_node_slots', args: { action: 'list' } },\n mesh_node_slots_propose: { tool: 'mesh_node_slots', args: { action: 'propose' } },\n mesh_record_note: { tool: 'mesh_note', args: { action: 'record' } },\n mesh_forget_note: { tool: 'mesh_note', args: { action: 'forget' } },\n mesh_reinit: { tool: 'mesh_init', args: { mode: 'reinit' } },\n mesh_refine_config: { tool: 'mesh_config', args: { kind: 'refine' } },\n mesh_change_impact_config: { tool: 'mesh_config', args: { kind: 'change_impact' } },\n mesh_write_mesh_json_config: { tool: 'mesh_config', args: { kind: 'mesh_json' } },\n mesh_plan_onboarding: { tool: 'mesh_create', args: { mode: 'plan' } },\n mesh_prune_stale_direct: { tool: 'mesh_cleanup_sessions', args: { mode: 'prune_stale_direct' } },\n};\n\nconst COORDINATOR_PROMPT_APPEND_REMOVED = 'Per-machine coordinator prompt files are no longer read. For a standing instruction on this project\\'s coordinator, put it in the repo\\'s .adhdev/mesh.json coordinator.systemPromptAppend (mesh_config kind \"mesh_json\"), or record a durable lesson with mesh_note.';\n\n/**\n * Tool names removed outright (no merged replacement), mapped to the guidance a\n * coordinator on an old prompt needs to do the same job with the remaining tools.\n */\nexport const REMOVED_MESH_TOOLS: Readonly<Record<string, string>> = {\n mesh_magi_review: 'For a multi-perspective review, send the same question to 2-3 workers on different providers with mesh_send_task, wait for their report_completion, then synthesize the answers yourself.',\n mesh_magi_collect: 'Worker answers arrive as report_completion events; synthesize them yourself.',\n mesh_magi_kind_panel: 'There are no review panels any more; pick the workers per review with mesh_send_task.',\n mesh_magi_kind_panel_set: 'There are no review panels any more; pick the workers per review with mesh_send_task.',\n mesh_magi_kind_panel_list: 'There are no review panels any more; pick the workers per review with mesh_send_task.',\n // 2026-10-08: was a pure alias — mesh_refine_node's default dry-run returns the same plan.\n mesh_refine_plan: 'Call mesh_refine_node with the same node_id and no execute: its default dry-run returns the same Refinery plan and executes nothing.',\n // 2026-10-08: the per-machine coordinator-prompts/ file layer was removed (assistant-layer design §11 Q2).\n mesh_coordinator_prompt_append: COORDINATOR_PROMPT_APPEND_REMOVED,\n mesh_coordinator_prompt_append_get: COORDINATOR_PROMPT_APPEND_REMOVED,\n mesh_coordinator_prompt_append_set: COORDINATOR_PROMPT_APPEND_REMOVED,\n};\n\n/**\n * The error text for a call to a retired or removed tool name, or null when\n * `name` is neither. One wording shared by every MCP mode so the redirect reads\n * the same wherever an old prompt calls it.\n */\nexport function retiredMeshToolError(name: string): string | null {\n if (Object.prototype.hasOwnProperty.call(REMOVED_MESH_TOOLS, name)) {\n return `Tool \"${name}\" was removed. ${REMOVED_MESH_TOOLS[name]}`;\n }\n const entry = Object.prototype.hasOwnProperty.call(RETIRED_MESH_TOOLS, name) ? RETIRED_MESH_TOOLS[name] : undefined;\n if (!entry) return null;\n const discriminator = Object.entries(entry.args).map(([k, v]) => `${k}: \"${v}\"`).join(', ');\n return `Tool \"${name}\" was retired (merged into ${entry.tool}). Call ${entry.tool} with ${discriminator} and the same other arguments.`\n + (entry.note ? ` ${entry.note}` : '');\n}\n","/**\n * OFFLINE-NODE-STATUS-REFRESH — the status-origin probe marker.\n *\n * A remote `git_status` (or any relayed/dispatched mesh command) that originates from\n * an explicit_refresh / mesh_status aggregate carries this marker inside its ARGS. The\n * daemon-cloud dispatch wrapper and MCP relay handler read it to grant the SHORT\n * connect-wait budget so a single offline (powered-off) peer no longer blocks the whole\n * status assembly for ~90s.\n *\n * It is deliberately an args marker rather than adding `git_status` to the global\n * probe-class command set: a user-driven / targeted `git_status` (no marker) must keep\n * waiting out the full connect deadline for a slow relay to open (rc.503 intent). Only a\n * status-origin probe opts into the short budget.\n *\n * The key is `_`-prefixed so it travels alongside the real args (workspace,\n * refreshUpstream, includeSubmodules, …) and is ignored by the git_status handler; the\n * dispatch/relay sites strip it defensively before the command executes so it never\n * reaches a handler that echoes unknown args.\n *\n * This dependency-free leaf is the single source of truth shared by daemon-core (the\n * aggregate probe producer), mcp-server (the MCP relay producer), and daemon-cloud (the\n * dispatch/relay consumer) so the key cannot drift between producer and consumer.\n */\nexport const STATUS_PROBE_ARG_KEY = '_statusProbe' as const;\n\n/** Stamp the status-origin probe marker onto a command's args (non-mutating). */\nexport function withStatusProbeMarker(\n args: Record<string, unknown> = {},\n): Record<string, unknown> {\n return { ...args, [STATUS_PROBE_ARG_KEY]: true };\n}\n\n/** True when the args carry the status-origin probe marker. */\nexport function argsCarryStatusProbeMarker(args: unknown): boolean {\n return (\n !!args &&\n typeof args === 'object' &&\n (args as Record<string, unknown>)[STATUS_PROBE_ARG_KEY] === true\n );\n}\n\n/**\n * Return a shallow copy of args with the internal marker removed so it never leaks to\n * the executing command handler. Returns the original reference when no marker is\n * present (avoids an allocation on the common path).\n */\nexport function stripStatusProbeMarker(\n args: Record<string, unknown>,\n): Record<string, unknown> {\n if (!argsCarryStatusProbeMarker(args)) return args;\n const { [STATUS_PROBE_ARG_KEY]: _drop, ...rest } = args;\n return rest;\n}\n","/**\n * Mesh RPC frame chunking — split/reassemble oversized mesh envelopes.\n *\n * WHY THIS EXISTS\n * The mesh DataChannel path (`daemon-mesh-manager`) writes every RPC envelope as a\n * SINGLE `dc.sendMessage(JSON.stringify(envelope))` frame. That was fine while every\n * mesh arg was small text, but a coordinator dispatching an IMAGE to a worker puts a\n * multi-MB base64 part inside `args` — far past what one DataChannel frame carries, so\n * the send throws or the frame is dropped and the dispatch silently dies.\n *\n * The dashboard P2P path already solved exactly this problem and has been running in\n * production: `packages/daemon-cloud/src/daemon-p2p/data-channel-router.ts` (send +\n * reassemble) and `packages/web-cloud/src/p2p.ts` (browser side). This module is a PORT\n * of that proven scheme onto the mesh envelope shape — deliberately NOT a new protocol.\n * The boundary values are carried over unchanged (see the constants below for why each\n * one is what it is).\n *\n * It lives in mesh-shared because it is pure string/JSON work with no transport, no\n * Node API and no DOM API — the same reason the normalizers live here. `daemon-cloud`\n * (sender/receiver) is the only current consumer, but keeping it in the pure leaf means\n * the standalone side can reassemble with the identical code rather than a hand-synced\n * copy, which is the drift bug class this package was created to kill.\n *\n * FAILURE POLICY (DoD): reassembly never degrades silently. A malformed, out-of-range,\n * over-budget or unparseable chunk stream yields an explicit typed failure that the\n * caller turns into an RPC error — never a partially-applied or truncated envelope.\n */\n\n/**\n * Inline ceiling: an envelope whose JSON is at or below this goes out as one frame,\n * exactly as before this module existed. 60_000 (not 65_536) matches the dashboard\n * path and leaves headroom under the common 64KiB SCTP message limit so the frame is\n * never the thing that trips a transport-level cap.\n */\nexport const MESH_MAX_INLINE_FRAME_BYTES = 60_000\n\n/**\n * Per-chunk payload slice, in CHARACTERS. Ported unchanged from the dashboard path.\n *\n * Why 16_000 chars is safe under a 60_000-BYTE ceiling, with ~3.75x of headroom:\n * `splitMeshFrame` slices the ALREADY-SERIALIZED outer frame, so the text being cut\n * is JSON output — control characters are pre-expanded to `\\u00XX` ASCII before they\n * ever reach the slicer. Re-escaping that slice inside the chunk envelope can at worst\n * double the backslashes. Measured worst cases for a 16_000-char slice:\n * backslashes / astral emoji → 32,073 bytes\n * Korean (3-byte, unescaped) → 48,073 bytes ← densest observed\n * plain ASCII → 16,073 bytes\n * All are under MESH_MAX_INLINE_FRAME_BYTES. `splitMeshFrame` still MEASURES each\n * envelope and shrinks on overflow, so the guarantee is enforced rather than assumed\n * if either constant is ever retuned — but at these values that path is unreachable,\n * which is exactly what `assertMeshChunkConstantsAreSafe` pins down.\n */\nexport const MESH_CHUNK_PAYLOAD_CHARS = 16_000\n\n/**\n * Hard cap on chunk count for one frame. 1024 × ~16KB ≈ 16MB of transferable payload,\n * which comfortably covers a screenshot while bounding what a single peer can make the\n * receiver buffer. Exceeding it is an explicit refusal, never a truncated send.\n */\nexport const MESH_MAX_CHUNKS = 1024\n\n/**\n * Reassembly budget for one frame, in bytes. Bounds receiver memory independently of\n * chunk count so a peer cannot send 1024 maximally-large chunks to force an oversized\n * allocation. Mirrors the dashboard receiver's MAX_REASSEMBLED_JSON_BYTES.\n */\nexport const MESH_MAX_REASSEMBLED_BYTES = 16_000_000\n\n/**\n * How long a partially-received frame is retained. A sender that dies mid-stream must\n * not pin receiver memory forever; the partial is swept and the frame simply never\n * completes (the RPC's own deadline then reports it).\n */\nexport const MESH_CHUNK_TTL_MS = 60_000\n\n/** Envelope `kind` for a chunk of a larger mesh frame. */\nexport const MESH_CHUNK_KIND = 'rpc_chunk'\n\nexport interface MeshChunkEnvelope {\n v: number\n kind: typeof MESH_CHUNK_KIND\n /** Groups the chunks of one logical frame. */\n chunkId: string\n /** 0-based position of this chunk. */\n index: number\n /** Total chunk count for this frame; constant across the group. */\n total: number\n /** The slice of the original envelope JSON. */\n data: string\n}\n\nexport type MeshChunkSplitResult =\n | { ok: true; chunks: MeshChunkEnvelope[] }\n | { ok: false; reason: 'too_many_chunks' | 'chunk_too_large'; detail: string }\n\nexport type MeshChunkAcceptResult =\n /** Chunk stored; the frame is not complete yet. */\n | { status: 'partial'; received: number; total: number }\n /** Final chunk landed and the frame parsed cleanly. */\n | { status: 'complete'; frame: unknown }\n /** Explicitly rejected — the caller must surface this, never ignore it. */\n | { status: 'failed'; reason: MeshChunkFailureReason; detail: string; chunkId: string }\n\nexport type MeshChunkFailureReason =\n | 'malformed_chunk'\n | 'too_many_chunks'\n | 'inconsistent_total'\n | 'duplicate_chunk_mismatch'\n | 'budget_exceeded'\n | 'reassembled_parse_failed'\n\n/** UTF-8 byte length without assuming Buffer or TextEncoder is present. */\nexport function meshUtf8ByteLength(value: string): number {\n if (typeof TextEncoder !== 'undefined') return new TextEncoder().encode(value).byteLength\n let bytes = 0\n for (let i = 0; i < value.length; i += 1) {\n const code = value.charCodeAt(i)\n if (code < 0x80) bytes += 1\n else if (code < 0x800) bytes += 2\n else if (code >= 0xd800 && code <= 0xdbff) { bytes += 4; i += 1 }\n else bytes += 3\n }\n return bytes\n}\n\n/**\n * Worst-case size of one chunk envelope at the current constants.\n *\n * Exported so the safety margin documented on MESH_CHUNK_PAYLOAD_CHARS is a CHECKED\n * invariant rather than a comment that rots. The densest slice the splitter can produce\n * is 3-byte unescaped text (JSON.stringify leaves non-ASCII as-is), so that is what this\n * measures. If someone raises MESH_CHUNK_PAYLOAD_CHARS or lowers the frame ceiling past\n * the safe point, the accompanying test fails loudly instead of the overflow only\n * showing up as dropped frames on a live mesh.\n */\nexport function measureWorstCaseChunkEnvelopeBytes(): number {\n const densest = '한'.repeat(MESH_CHUNK_PAYLOAD_CHARS)\n return meshUtf8ByteLength(JSON.stringify(\n buildChunkEnvelope(Number.MAX_SAFE_INTEGER, 'x'.repeat(64), MESH_MAX_CHUNKS, MESH_MAX_CHUNKS, densest),\n ))\n}\n\n/** True when the serialized frame must be chunked rather than sent inline. */\nexport function meshFrameNeedsChunking(json: string): boolean {\n return meshUtf8ByteLength(json) > MESH_MAX_INLINE_FRAME_BYTES\n}\n\nfunction buildChunkEnvelope(\n version: number, chunkId: string, index: number, total: number, data: string,\n): MeshChunkEnvelope {\n return { v: version, kind: MESH_CHUNK_KIND, chunkId, index, total, data }\n}\n\n/**\n * Split a serialized mesh envelope into chunk envelopes.\n *\n * Each slice is measured AS ITS FINAL SERIALIZED ENVELOPE and shrunk (×0.8, as in the\n * dashboard implementation) until it fits the inline ceiling — so multi-byte UTF-8 and\n * the envelope overhead are both accounted for rather than assumed away. `total` is\n * stamped only after the full split is known, so every chunk in a group agrees.\n */\nexport function splitMeshFrame(json: string, chunkId: string, version: number): MeshChunkSplitResult {\n const slices: string[] = []\n let offset = 0\n while (offset < json.length) {\n let end = Math.min(json.length, offset + MESH_CHUNK_PAYLOAD_CHARS)\n // Measure against MESH_MAX_CHUNKS as the `total` placeholder: it is the widest the\n // field can serialize to, so a slice that fits here still fits once the real (never\n // larger) total is stamped in below.\n while (end > offset) {\n const candidate = json.slice(offset, end)\n const probe = JSON.stringify(buildChunkEnvelope(version, chunkId, slices.length, MESH_MAX_CHUNKS, candidate))\n if (meshUtf8ByteLength(probe) <= MESH_MAX_INLINE_FRAME_BYTES) break\n const shrunk = Math.max(1, Math.floor((end - offset) * 0.8))\n if (offset + shrunk >= end) { end -= 1; continue }\n end = offset + shrunk\n }\n if (end <= offset) {\n return { ok: false, reason: 'chunk_too_large', detail: 'a single character did not fit the chunk envelope budget' }\n }\n slices.push(json.slice(offset, end))\n if (slices.length > MESH_MAX_CHUNKS) {\n return {\n ok: false,\n reason: 'too_many_chunks',\n detail: `frame needs more than ${MESH_MAX_CHUNKS} chunks (${meshUtf8ByteLength(json)} bytes)`,\n }\n }\n offset = end\n }\n if (slices.length === 0) {\n return { ok: false, reason: 'chunk_too_large', detail: 'refusing to chunk an empty frame' }\n }\n const total = slices.length\n return { ok: true, chunks: slices.map((data, index) => buildChunkEnvelope(version, chunkId, index, total, data)) }\n}\n\ninterface MeshChunkBuffer {\n total: number\n chunks: string[]\n received: number\n bytesReceived: number\n createdAt: number\n}\n\n/**\n * Receiver-side reassembly buffer, one per peer connection.\n *\n * Keyed by chunkId only — callers construct one assembler per peer, so chunk groups\n * from different peers can never collide in the same map.\n */\nexport class MeshChunkAssembler {\n private readonly buffers = new Map<string, MeshChunkBuffer>()\n\n constructor(private readonly now: () => number = () => Date.now()) {}\n\n /** True when the frame is a chunk envelope this assembler should handle. */\n static isChunkFrame(frame: unknown): boolean {\n return !!frame && typeof frame === 'object' && (frame as { kind?: unknown }).kind === MESH_CHUNK_KIND\n }\n\n /** Drop partials older than the TTL so a dead sender cannot pin memory. */\n private sweep(): void {\n const now = this.now()\n for (const [key, entry] of Array.from(this.buffers.entries())) {\n if (now - entry.createdAt > MESH_CHUNK_TTL_MS) this.buffers.delete(key)\n }\n }\n\n /** Discard any partial state for a peer (call on disconnect). */\n reset(): void {\n this.buffers.clear()\n }\n\n /** Number of frames currently mid-reassembly — for tests and diagnostics. */\n get pendingCount(): number {\n return this.buffers.size\n }\n\n /**\n * Accept one chunk envelope.\n *\n * Never throws and never returns a partially-applied frame: the result is exactly one\n * of partial / complete / failed, and `failed` carries a typed reason the transport\n * turns into an explicit RPC error.\n */\n accept(frame: unknown): MeshChunkAcceptResult {\n this.sweep()\n const raw = frame as Partial<MeshChunkEnvelope> | null\n const chunkId = typeof raw?.chunkId === 'string' ? raw.chunkId : ''\n const index = Number(raw?.index)\n const total = Number(raw?.total)\n const data = typeof raw?.data === 'string' ? raw.data : ''\n\n if (!chunkId || !Number.isInteger(index) || !Number.isInteger(total)\n || index < 0 || total <= 0 || index >= total || !data) {\n return {\n status: 'failed',\n reason: 'malformed_chunk',\n detail: `malformed chunk envelope (chunkId=${chunkId || '-'} index=${raw?.index} total=${raw?.total})`,\n chunkId,\n }\n }\n if (total > MESH_MAX_CHUNKS) {\n this.buffers.delete(chunkId)\n return {\n status: 'failed',\n reason: 'too_many_chunks',\n detail: `chunk total ${total} exceeds the ${MESH_MAX_CHUNKS} cap`,\n chunkId,\n }\n }\n\n let entry = this.buffers.get(chunkId)\n if (!entry) {\n entry = { total, chunks: new Array(total).fill(''), received: 0, bytesReceived: 0, createdAt: this.now() }\n this.buffers.set(chunkId, entry)\n } else if (entry.total !== total) {\n // The sender disagrees with itself about the frame's shape — the stream is\n // corrupt; drop it loudly rather than reassembling a mixed frame.\n this.buffers.delete(chunkId)\n return {\n status: 'failed',\n reason: 'inconsistent_total',\n detail: `chunk ${index} declares total ${total} but the group was opened with ${entry.total}`,\n chunkId,\n }\n }\n\n const existing = entry.chunks[index]\n if (existing) {\n // A benign retransmit repeats identical bytes. Different bytes for the same slot\n // means the ordering/identity guarantee is broken — refuse instead of picking one.\n if (existing === data) return { status: 'partial', received: entry.received, total: entry.total }\n this.buffers.delete(chunkId)\n return {\n status: 'failed',\n reason: 'duplicate_chunk_mismatch',\n detail: `chunk ${index} arrived twice with different content`,\n chunkId,\n }\n }\n\n const chunkBytes = meshUtf8ByteLength(data)\n if (entry.bytesReceived + chunkBytes > MESH_MAX_REASSEMBLED_BYTES) {\n this.buffers.delete(chunkId)\n return {\n status: 'failed',\n reason: 'budget_exceeded',\n detail: `reassembled frame would exceed ${MESH_MAX_REASSEMBLED_BYTES} bytes`,\n chunkId,\n }\n }\n\n entry.chunks[index] = data\n entry.received += 1\n entry.bytesReceived += chunkBytes\n if (entry.received < entry.total) {\n return { status: 'partial', received: entry.received, total: entry.total }\n }\n\n this.buffers.delete(chunkId)\n try {\n return { status: 'complete', frame: JSON.parse(entry.chunks.join('')) }\n } catch (error) {\n // Every slot is filled yet the join is not valid JSON — the frame is unusable.\n // Explicit failure, never a silent drop.\n return {\n status: 'failed',\n reason: 'reassembled_parse_failed',\n detail: `reassembled frame is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,\n chunkId,\n }\n }\n }\n}\n","/**\n * Semver precedence comparison — the single version-ordering primitive for the\n * daemon's upgrade paths.\n *\n * Why this exists: the upgrade path used to decide \"is this a no-op?\" with a\n * raw string equality check (`currentInstalled === latest`) and nothing else.\n * Equality answers \"is it the same version?\" but never \"which one is newer?\",\n * so any target that merely differed from the running build was installed —\n * including one that is OLDER. That is how a node running `1.0.49-rc.2`\n * silently got rolled back to `1.0.48`.\n *\n * String comparison cannot fix it either: `'1.0.49-rc.2' < '1.0.48'` is TRUE\n * lexicographically (the '4' in \"-rc.2\"'s prefix never gets that far — '9' vs\n * '8' at index 4 decides it, and even where it works `rc.10` sorts below\n * `rc.9`). Only field-wise numeric comparison with semver §11 prerelease rules\n * gives the right answer.\n *\n * This module is a PURE LEAF: zero imports, no I/O. It lives in mesh-shared\n * (fragmentation audit) so BOTH the OSS daemon and the proprietary Workers\n * server (`packages/server/src/utils/version-policy.ts`, previously a\n * byte-identical independent copy) can consume ONE implementation — the two\n * gate the same auto-update decision from opposite ends, and a drift between\n * them can produce an unbreakable update-nag loop (server says behind, daemon\n * gate refuses the \"upgrade\" as a rollback). daemon-core re-exports this from\n * its original `version-compare.ts` path, so existing imports keep working.\n *\n * NOTE ON PRERELEASE SEMANTICS: this is STRICT semver §11 — `1.0.49-rc.2` is\n * BELOW `1.0.49`, because a prerelease precedes its own release. That is the\n * correct rule for \"would installing this move me backwards?\", which is the\n * only question this module is used to answer. It deliberately differs from\n * `oss/packages/web-core/src/utils/version-update.ts`, whose\n * `isDaemonBehindTarget` treats an rc as up-to-date against its own base\n * release so the dashboard does not nag preview users with an update banner.\n * Those are two different questions; do not collapse them into one helper.\n */\n\n/** Parsed semver fields. Build metadata (`+…`) is discarded: it never affects precedence (§10). */\nexport interface ParsedSemver {\n readonly major: number;\n readonly minor: number;\n readonly patch: number;\n /** Dot-separated prerelease identifiers; empty for a release build. */\n readonly prerelease: readonly string[];\n}\n\nconst SEMVER_PATTERN = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/;\nconst NUMERIC_IDENTIFIER = /^\\d+$/;\n\n/**\n * Parse a semver string, tolerating a leading `v` (npm/CLI output carries it\n * inconsistently). Returns null for anything unparsable so callers can fail\n * closed rather than guess.\n */\nexport function parseSemver(version: unknown): ParsedSemver | null {\n if (typeof version !== 'string') return null;\n const match = version.trim().replace(/^v/, '').match(SEMVER_PATTERN);\n if (!match) return null;\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n prerelease: match[4] ? match[4].split('.') : [],\n };\n}\n\n/**\n * Semver §11 prerelease precedence: a release outranks its own prereleases;\n * numeric identifiers compare numerically (so rc.10 > rc.9) and rank below\n * alphanumeric ones; alphanumerics compare lexically; a shorter identifier\n * list ranks below an otherwise-equal longer one.\n */\nfunction comparePrerelease(a: readonly string[], b: readonly string[]): number {\n if (a.length === 0 && b.length === 0) return 0;\n // An empty prerelease list means \"release build\", which outranks any prerelease.\n if (a.length === 0) return 1;\n if (b.length === 0) return -1;\n for (let i = 0; i < Math.min(a.length, b.length); i += 1) {\n const idA = a[i];\n const idB = b[i];\n if (idA === idB) continue;\n const numA = NUMERIC_IDENTIFIER.test(idA);\n const numB = NUMERIC_IDENTIFIER.test(idB);\n if (numA && numB) return Number(idA) < Number(idB) ? -1 : 1;\n if (numA) return -1;\n if (numB) return 1;\n return idA < idB ? -1 : 1;\n }\n return a.length === b.length ? 0 : (a.length < b.length ? -1 : 1);\n}\n\n/**\n * Compare two versions by semver precedence.\n *\n * @returns -1 when `a` precedes `b`, 0 when equal, 1 when `a` succeeds `b`, and\n * **null when either side is unparsable** — callers MUST treat null as\n * \"direction unknown\" and fail closed rather than coercing it to a number\n * (`null` compares as `0` in JS numeric contexts, which would read as \"equal\").\n */\nexport function compareSemver(a: unknown, b: unknown): number | null {\n const pa = parseSemver(a);\n const pb = parseSemver(b);\n if (!pa || !pb) return null;\n if (pa.major !== pb.major) return pa.major < pb.major ? -1 : 1;\n if (pa.minor !== pb.minor) return pa.minor < pb.minor ? -1 : 1;\n if (pa.patch !== pb.patch) return pa.patch < pb.patch ? -1 : 1;\n return comparePrerelease(pa.prerelease, pb.prerelease);\n}\n\n/**\n * Would installing `target` move a daemon currently on `current` BACKWARDS?\n *\n * Returns false when the direction cannot be established (either version\n * unparsable) — an unknown direction must never block an upgrade, because the\n * cost of a false block (the whole fleet can no longer be upgraded) is far\n * higher than the cost of a missed downgrade guard. Equal versions are NOT a\n * downgrade, so a same-version reinstall stays allowed.\n */\nexport function isDowngrade(current: unknown, target: unknown): boolean {\n const direction = compareSemver(target, current);\n if (direction === null) return false;\n return direction < 0;\n}\n","/**\n * protocol/envelope — helpers shared by the three link protocols.\n *\n * Wiring-unification Phase A2 (docs/design/2026-09-23-wiring-unification.md).\n *\n * Every link (daemon↔server WS, dashboard↔UserSession WS, dashboard↔daemon\n * P2P DataChannel) is described the same way:\n *\n * - a `const` tuple of message-kind names per direction;\n * - a discriminated union of `{ type, ... }` frames derived from it;\n * - a `decode<Link><Direction>(raw)` parse-boundary function that checks the\n * `type` is a member and the frame carries the MINIMAL shape the union\n * promises (an object payload where one is required, the top-level fields\n * a payload-less frame is keyed by). Semantic validation — is this session\n * id known, is the SDP well formed — stays with the handler that owns it.\n *\n * mesh-shared is a dependency-free leaf, so payload types here are STRUCTURAL\n * mirrors of the richer daemon-core types (`RoutingSessionEntry`,\n * `DaemonStatusEventPayload`, ...): daemon-core, the server and the web assign\n * their richer types into these, never the other way round. A type-only import\n * of daemon-core would make the published `.d.ts` of this package reference a\n * package that depends on it — a cycle a leaf must not create.\n */\n\nexport type MessageId = string\n\n/** `{ type, payload }` frame with the optional correlation/ordering fields every link uses. */\nexport type Envelope<T extends string, P> = {\n type: T\n payload: P\n id?: MessageId\n timestamp?: number\n}\n\n/** Genuinely dynamic payloads (command arguments and results). Allowed by design; the union stays exhaustive on `type`. */\nexport type CommandPayload = Record<string, unknown>\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport function isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0\n}\n\nexport function isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n\nexport function makeTypeGuard<T extends readonly string[]>(names: T): (value: unknown) => value is T[number] {\n const set: ReadonlySet<string> = new Set(names)\n return (value: unknown): value is T[number] => typeof value === 'string' && set.has(value)\n}\n\n/**\n * Compile-time proof that a name tuple and a union have exactly the same\n * members. Used as `const _: AssertSameMembers<typeof NAMES, Union> = true`.\n */\nexport type AssertSameMembers<Tuple extends readonly string[], Union extends string> =\n [Exclude<Union, Tuple[number]>, Exclude<Tuple[number], Union>] extends [never, never] ? true : never\n\n/** Narrow a frame's `type` to a union member, or null. */\nexport function decodeTypeField<T extends string>(raw: unknown, isType: (value: unknown) => value is T): { type: T; frame: Record<string, unknown> } | null {\n if (!isRecord(raw)) return null\n if (!isType(raw.type)) return null\n return { type: raw.type, frame: raw }\n}\n\n/** Read the optional envelope fields a frame may carry, dropping malformed ones. */\nexport function readEnvelopeFields(frame: Record<string, unknown>): { id?: MessageId; timestamp?: number } {\n return {\n ...(isNonEmptyString(frame.id) ? { id: frame.id } : {}),\n ...(isFiniteNumber(frame.timestamp) ? { timestamp: frame.timestamp } : {}),\n }\n}\n","/**\n * protocol/daemon-server — the daemon ↔ Workers-server WebSocket link.\n *\n * Wiring-unification Phase A2 (docs/design/2026-09-23-wiring-unification.md §3 A2).\n *\n * Before this file the link shared NAME lists only (`ws-protocol.ts`), payloads\n * were `any` on both ends, `daemon_mesh_command` was sent by a raw `ws.send`\n * outside the typed funnel, and the P2P signaling names in the shared list\n * (`offer|answer|ice`) had drifted from the wire (`p2p_offer|p2p_answer|p2p_ice`)\n * without anything noticing, because nothing imported them.\n *\n * Two directions:\n * - `DaemonToServerMsg` — every frame the daemon writes to the server WS.\n * - `ServerToDaemonMsg` — every frame the server writes to a daemon WS. This\n * is a CLOSED control set plus one OPEN namespace: the public REST API\n * (`POST /api/v1/daemons/:id/command`, `daemonCommandSchema` = any string)\n * relays a caller-chosen command name as the frame `type`, so that member is\n * typed with a branded string rather than a literal list. The brand is what\n * keeps `msg.type === 'auth_ok'` narrowing to the control member instead of\n * collapsing into \"some string\".\n *\n * Payloads are structural mirrors of the daemon-core types the two ends assign\n * into them (see ./envelope.ts for why mesh-shared cannot import daemon-core).\n */\n\nimport type { AuthOkPlanLimits } from '../ws-protocol'\nimport type { SessionStatus } from '../session-status'\nimport {\n type CommandPayload,\n type Envelope,\n type MessageId,\n type AssertSameMembers,\n isRecord,\n isNonEmptyString,\n makeTypeGuard,\n readEnvelopeFields,\n} from './envelope'\n\n// ─── Status events (mirror of daemon-core `DaemonStatusEventName`) ─────────\n\n/**\n * Daemon-originated status events. The daemon relays these to the server\n * (push notifications, webhooks) AND over P2P (dashboard). Mirror of\n * daemon-core `DaemonStatusEventName`; the server pins the two equal at compile\n * time (UserSession.ts), so adding a member here without adding it there — or\n * vice versa — fails `tsc`.\n */\nexport const DAEMON_STATUS_EVENT_NAMES = [\n 'agent:generating_started',\n 'agent:waiting_approval',\n 'agent:waiting_choice',\n 'agent:generating_completed',\n 'agent:stopped',\n 'monitor:no_progress',\n] as const\nexport type DaemonStatusEventName = typeof DAEMON_STATUS_EVENT_NAMES[number]\nexport const isDaemonStatusEventName = makeTypeGuard(DAEMON_STATUS_EVENT_NAMES)\n\n/**\n * Server-bound status event. Content boundary: identifiers, enums, counters\n * and booleans only — plus the approved approval-modal exception\n * (`modalMessage`/`modalButtons`, CLAUDE.md \"Push notification exception\").\n * Mirror of daemon-core `DaemonStatusEventPayload`.\n */\nexport type DaemonStatusEventWirePayload = {\n event: DaemonStatusEventName\n timestamp: number\n targetSessionId?: string\n providerType?: string\n providerSessionId?: string\n workspaceName?: string\n duration?: number\n elapsedSec?: number\n modalMessage?: string\n modalButtons?: string[]\n surfaceHidden?: boolean\n muted?: boolean\n}\n\n// ─── Status report (mirror of daemon-core `CloudStatusReportPayload`) ──────\n\n/** Routing-only session entry the daemon reports over the server WS. Mirror of daemon-core `RoutingSessionEntry`. */\nexport type RoutingSessionWireEntry = {\n id: string\n parentId: string | null\n providerType: string\n providerName: string\n kind: string\n transport: string\n status: SessionStatus\n workspace: string | null\n cdpConnected?: boolean\n surfaceHidden?: boolean\n muted?: boolean\n}\n\n/** Counters and enums only — never a peer id or address. Mirror of daemon-core `P2PStatusSummary`. */\nexport type P2PStatusWireSummary = {\n available: boolean\n state: string\n peers: number\n screenshotActive?: boolean\n direct?: number\n relay?: number\n unknownTransport?: number\n directTotal?: number\n relayTotal?: number\n}\n\n/**\n * seqscribe replication health — pre-bucketed counters and booleans only,\n * never a topic name or peer id. Mirror of daemon-core `SeqscribeStatusSummary`\n * (which should derive from this once shared-types is on the protocol).\n */\nexport type SeqscribeStatusWireSummary = {\n topics: number\n peers: number\n peersReady: number\n pendingBucket: number\n consumerLagBucket: number\n queueBucket: number\n fgenAgeBucket: number\n quarantined: boolean\n authority: boolean\n transcriptPublish?: boolean\n transcriptPublishedBucket?: number\n transcriptPublishFailedBucket?: number\n transcriptDedupedBucket?: number\n transcriptOversizedBucket?: number\n transcriptDroppedBucket?: number\n}\n\nexport type CloudStatusReportWirePayload = {\n sessions: RoutingSessionWireEntry[]\n p2p?: P2PStatusWireSummary\n seqscribe?: SeqscribeStatusWireSummary\n timestamp: number\n}\n\n// ─── Release / update vocabulary (mirror of daemon-core shared-types) ──────\n\nexport const RELEASE_CHANNELS = ['stable', 'preview'] as const\nexport type ReleaseChannelWire = typeof RELEASE_CHANNELS[number]\nexport const NPM_UPDATE_TAGS = ['latest', 'next'] as const\nexport type NpmUpdateTagWire = typeof NPM_UPDATE_TAGS[number]\nexport const VERSION_UPDATE_REASONS = ['force_update_below', 'major_minor_mismatch', 'patch_mismatch', 'daemon_ahead'] as const\nexport type VersionUpdateReasonWire = typeof VERSION_UPDATE_REASONS[number]\n\n/** Mirror of daemon-core `VersionUpdatePolicy`. */\nexport type VersionUpdatePolicyWire = {\n channel: ReleaseChannelWire\n npmTag: NpmUpdateTagWire\n targetVersion: string\n minVersion?: string\n updateCommand: string\n}\n\nexport type StatusHeartbeatWirePayload = {\n timestamp?: number\n p2pPeers?: number\n}\n\n// ─── Auth ──────────────────────────────────────────────────────────────────\n\n/** What the daemon says about itself at auth time (`ServerConnectionOptions.cliInfo`). */\nexport type DaemonAuthIdentity = {\n type: string\n version: string\n platform: string\n hostname?: string\n machineId?: string\n /** Canonical mesh identity `daemon_<machineId>`; the server keys its DO and status by it. */\n instanceId: string\n}\n\nexport type DaemonAuthWirePayload = {\n token: string\n daemon: DaemonAuthIdentity\n}\n\nexport type IceServerWireEntry = {\n urls: string | string[]\n username?: string\n credential?: string\n}\n\nexport type AuthOkWirePayload = {\n message?: string\n plan: string\n iceServers: IceServerWireEntry[]\n turnenabled: boolean\n serverVersion: string\n releaseChannel?: ReleaseChannelWire\n updatePolicy?: VersionUpdatePolicyWire\n machineNickname: string | null\n seqscribeFleetSecret?: string\n seqscribeFleetSecretVersion?: number\n limits: AuthOkPlanLimits\n}\n\nexport type AuthErrorWirePayload = {\n reason: string\n message: string\n limit?: number\n current?: number\n}\n\n/** `machine_evicted` / `force_disconnect` / `token_revoked` — a reason token plus human text, then the socket closes. */\nexport type DisconnectNoticeWirePayload = {\n reason: string\n message: string\n}\n\nexport type VersionMismatchWirePayload = {\n current: string\n latest: string\n required: false\n reason: VersionUpdateReasonWire\n channel: ReleaseChannelWire\n npmTag: NpmUpdateTagWire\n updatePolicy: VersionUpdatePolicyWire\n updateCommand: string\n}\n\nexport type ForceUpdateRequiredWirePayload = {\n current: string\n latest: string\n minVersion: string\n required: true\n reason: VersionUpdateReasonWire\n channel: ReleaseChannelWire\n npmTag: NpmUpdateTagWire\n updatePolicy: VersionUpdatePolicyWire\n updateCommand: string\n forceUpdateBelow?: string\n message: string\n}\n\n// ─── Commands and results ──────────────────────────────────────────────────\n\nexport type CommandResultWirePayload = {\n requestId: MessageId\n success: boolean\n source?: string\n} & Record<string, unknown>\n\nexport type DaemonErrorWirePayload = {\n message?: string\n detail?: unknown\n}\n\n// ─── P2P signaling (dashboard ↔ daemon through the server) ─────────────────\n\nexport const P2P_SIGNAL_TYPES = ['p2p_ready', 'p2p_offer', 'p2p_answer', 'p2p_ice'] as const\nexport type P2PSignalType = typeof P2P_SIGNAL_TYPES[number]\nexport const isP2PSignalType = makeTypeGuard(P2P_SIGNAL_TYPES)\n\n/** Signals the daemon originates (it is the WebRTC offerer). */\nexport const DAEMON_P2P_SIGNAL_TYPES = ['p2p_offer', 'p2p_ice'] as const\nexport type DaemonP2PSignalType = typeof DAEMON_P2P_SIGNAL_TYPES[number]\nexport const isDaemonP2PSignalType = makeTypeGuard(DAEMON_P2P_SIGNAL_TYPES)\n\nexport type P2POfferWirePayload = { sdp: string; type: string; peerId: string }\nexport type P2PIceWirePayload = { candidate: string; mid: string; peerId: string }\n\n/**\n * A dashboard-originated signal as relayed to the daemon. `peerId` is stamped\n * by UserSession/SharedSession, `sharePermission` and `shareTargetSessionId`\n * (the one session a share link may see) only by SharedSession (server\n * authority, never the client). Field names follow the browser/node-datachannel\n * spellings both ends already read.\n */\nexport type RelayedP2PSignalWirePayload = {\n peerId?: string\n daemonId?: string\n sharePermission?: string\n shareTargetSessionId?: string\n sdp?: string\n type?: string\n candidate?: string\n mid?: string\n sdpMid?: string | null\n sdpMLineIndex?: number | null\n}\n\nexport const MESH_P2P_SIGNAL_TYPES = ['mesh_p2p_ready', 'mesh_p2p_offer', 'mesh_p2p_answer', 'mesh_p2p_ice'] as const\nexport type MeshP2PSignalType = typeof MESH_P2P_SIGNAL_TYPES[number]\nexport const isMeshP2PSignalType = makeTypeGuard(MESH_P2P_SIGNAL_TYPES)\n\n/** Daemon→daemon signal as delivered to the target daemon: the sender's args plus the server-stamped canonical sender id. */\nexport type MeshP2PSignalWirePayload = { senderDaemonId: string } & Record<string, unknown>\n\n// ─── Daemon → Server ───────────────────────────────────────────────────────\n\nexport const DAEMON_TO_SERVER_TYPES = [\n 'auth',\n 'status_report',\n 'status_heartbeat',\n 'status_event',\n 'command_result',\n 'error',\n 'agent_event',\n 'daemon_mesh_command',\n 'p2p_offer',\n 'p2p_ice',\n] as const\nexport type DaemonToServerType = typeof DAEMON_TO_SERVER_TYPES[number]\nexport const isDaemonToServerType = makeTypeGuard(DAEMON_TO_SERVER_TYPES)\n\nexport type DaemonAuthMsg = Envelope<'auth', DaemonAuthWirePayload>\nexport type StatusReportMsg = Envelope<'status_report', CloudStatusReportWirePayload>\nexport type StatusHeartbeatMsg = Envelope<'status_heartbeat', StatusHeartbeatWirePayload>\nexport type DaemonStatusEventMsg = Envelope<'status_event', DaemonStatusEventWirePayload>\nexport type CommandResultMsg = Envelope<'command_result', CommandResultWirePayload>\nexport type DaemonErrorMsg = Envelope<'error', DaemonErrorWirePayload>\n/** Agent-level event forwarded verbatim to the `agent:status` webhook (throttled server-side). Dynamic by design. */\nexport type AgentEventMsg = Envelope<'agent_event', CommandPayload>\nexport type DaemonP2POfferMsg = Envelope<'p2p_offer', P2POfferWirePayload>\nexport type DaemonP2PIceMsg = Envelope<'p2p_ice', P2PIceWirePayload>\n/**\n * Daemon→daemon signaling relay request. Fields are TOP-LEVEL (no `payload`):\n * this is the wire shape the live fleet speaks, kept as-is so mixed-version\n * daemons and servers keep interoperating during a rollout.\n */\nexport type DaemonMeshCommandMsg = {\n type: 'daemon_mesh_command'\n requestId: string\n targetDaemonId: string\n command: MeshP2PSignalType\n args: Record<string, unknown>\n timestamp: number\n}\n\nexport type DaemonToServerMsg =\n | DaemonAuthMsg\n | StatusReportMsg\n | StatusHeartbeatMsg\n | DaemonStatusEventMsg\n | CommandResultMsg\n | DaemonErrorMsg\n | AgentEventMsg\n | DaemonMeshCommandMsg\n | DaemonP2POfferMsg\n | DaemonP2PIceMsg\n\nconst _daemonToServerNamesCoverUnion: AssertSameMembers<typeof DAEMON_TO_SERVER_TYPES, DaemonToServerMsg['type']> = true\nvoid _daemonToServerNamesCoverUnion\n\n/** Members that carry a `payload` object (everything except `daemon_mesh_command`). */\nexport type DaemonToServerPayloadType = Exclude<DaemonToServerMsg, DaemonMeshCommandMsg>['type']\nexport type DaemonToServerPayloadOf<T extends DaemonToServerPayloadType> = Extract<DaemonToServerMsg, { type: T }>['payload']\n\n/**\n * Parse boundary for the server: is `raw` a frame this link accepts from a daemon?\n * Checks membership and the minimal envelope shape; `auth` additionally needs a\n * token string because nothing downstream can proceed without one.\n */\nexport function decodeDaemonToServer(raw: unknown): DaemonToServerMsg | null {\n if (!isRecord(raw) || !isDaemonToServerType(raw.type)) return null\n if (raw.type === 'daemon_mesh_command') {\n // Handler-side validation replies with a correlated `daemon_mesh_result`\n // error, so only the discriminant is checked here.\n return {\n type: 'daemon_mesh_command',\n requestId: typeof raw.requestId === 'string' ? raw.requestId : String(raw.requestId ?? ''),\n targetDaemonId: typeof raw.targetDaemonId === 'string' ? raw.targetDaemonId : '',\n command: raw.command as MeshP2PSignalType,\n args: isRecord(raw.args) ? raw.args : {},\n timestamp: typeof raw.timestamp === 'number' ? raw.timestamp : Date.now(),\n }\n }\n if (!isRecord(raw.payload)) return null\n if (raw.type === 'auth' && !isNonEmptyString(raw.payload.token)) return null\n return { type: raw.type, payload: raw.payload, ...readEnvelopeFields(raw) } as DaemonToServerMsg\n}\n\n// ─── Server → Daemon ───────────────────────────────────────────────────────\n\nexport const SERVER_TO_DAEMON_CONTROL_TYPES = [\n 'auth_ok',\n 'auth_error',\n 'machine_evicted',\n 'force_disconnect',\n 'token_revoked',\n 'version_mismatch',\n 'force_update_required',\n 'command',\n 'agent_command',\n 'resolve_action',\n 'daemon_mesh_result',\n 'p2p_ready',\n 'p2p_offer',\n 'p2p_answer',\n 'p2p_ice',\n 'mesh_p2p_ready',\n 'mesh_p2p_offer',\n 'mesh_p2p_answer',\n 'mesh_p2p_ice',\n] as const\nexport type ServerToDaemonControlType = typeof SERVER_TO_DAEMON_CONTROL_TYPES[number]\nexport const isServerToDaemonControlType = makeTypeGuard(SERVER_TO_DAEMON_CONTROL_TYPES)\n\n/** Optional routing fields the server stamps on relayed commands. */\ntype ServerRelayFields = { id?: MessageId; source?: string; timestamp?: number }\n\nexport type AuthOkMsg = Envelope<'auth_ok', AuthOkWirePayload>\nexport type AuthErrorMsg = Envelope<'auth_error', AuthErrorWirePayload>\nexport type MachineEvictedMsg = Envelope<'machine_evicted', DisconnectNoticeWirePayload>\nexport type ForceDisconnectMsg = Envelope<'force_disconnect', DisconnectNoticeWirePayload>\nexport type TokenRevokedMsg = Envelope<'token_revoked', DisconnectNoticeWirePayload>\nexport type VersionMismatchMsg = Envelope<'version_mismatch', VersionMismatchWirePayload>\nexport type ForceUpdateRequiredMsg = Envelope<'force_update_required', ForceUpdateRequiredWirePayload>\n/** Wrapped command: `payload.command` names the command, `payload.args` carries it. */\nexport type ServerCommandMsg = Envelope<'command', { command: string; args?: CommandPayload } & Record<string, unknown>> & ServerRelayFields\nexport type ServerAgentCommandMsg = Envelope<'agent_command', { action: string } & Record<string, unknown>> & ServerRelayFields\nexport type ServerResolveActionMsg = Envelope<'resolve_action', CommandPayload> & ServerRelayFields\nexport type ServerP2PSignalMsg = Envelope<P2PSignalType, RelayedP2PSignalWirePayload> & ServerRelayFields\nexport type ServerMeshP2PSignalMsg = Envelope<MeshP2PSignalType, MeshP2PSignalWirePayload> & ServerRelayFields\n/** Correlated ack/nack of a `daemon_mesh_command` (top-level, no payload). */\nexport type DaemonMeshResultMsg = {\n type: 'daemon_mesh_result'\n requestId: string\n success: boolean\n result?: unknown\n error?: string\n}\n\nexport type ServerToDaemonControlMsg =\n | AuthOkMsg\n | AuthErrorMsg\n | MachineEvictedMsg\n | ForceDisconnectMsg\n | TokenRevokedMsg\n | VersionMismatchMsg\n | ForceUpdateRequiredMsg\n | ServerCommandMsg\n | ServerAgentCommandMsg\n | ServerResolveActionMsg\n | DaemonMeshResultMsg\n | ServerP2PSignalMsg\n | ServerMeshP2PSignalMsg\n\nconst _serverToDaemonControlNamesCoverUnion: AssertSameMembers<typeof SERVER_TO_DAEMON_CONTROL_TYPES, ServerToDaemonControlMsg['type']> = true\nvoid _serverToDaemonControlNamesCoverUnion\n\ndeclare const directCommandBrand: unique symbol\n/**\n * A command name relayed as the frame `type` — the OPEN namespace the REST API\n * and `shortcuts` routes feed (`read_chat`, `send_chat`, `stop_cli`, `git_*`,\n * `clone_mesh_node`, `terminal_exec`, ...). The daemon routes it by name\n * through its command router. Branded so it cannot be confused with a control\n * member at the type level; `decodeServerToDaemon` is the only producer.\n */\nexport type DaemonDirectCommandType = string & { readonly [directCommandBrand]?: true }\n\nexport type ServerDirectCommandMsg = {\n type: DaemonDirectCommandType\n payload: CommandPayload\n id?: MessageId\n source?: string\n timestamp?: number\n}\n\nexport type ServerToDaemonMsg = ServerToDaemonControlMsg | ServerDirectCommandMsg\nexport type ServerToDaemonType = ServerToDaemonMsg['type']\n\nexport function isServerDirectCommandMsg(msg: ServerToDaemonMsg): msg is ServerDirectCommandMsg {\n return !isServerToDaemonControlType(msg.type)\n}\n\n/** Members of the control set that carry a `payload` object. */\nexport type ServerToDaemonPayloadType = Exclude<ServerToDaemonControlMsg, DaemonMeshResultMsg>['type']\nexport type ServerToDaemonPayloadOf<T extends ServerToDaemonPayloadType> = Extract<ServerToDaemonControlMsg, { type: T }>['payload']\n\n/** Command types a daemon must never receive as a direct command: they are daemon→server frames or reserved envelope words. */\nconst DIRECT_COMMAND_TYPE_PATTERN = /^[a-z][a-z0-9_:.-]{0,63}$/\n\nexport function isDaemonDirectCommandType(value: unknown): value is DaemonDirectCommandType {\n return typeof value === 'string' && DIRECT_COMMAND_TYPE_PATTERN.test(value) && !isServerToDaemonControlType(value)\n}\n\n/**\n * Parse boundary for the daemon: is `raw` a frame this link accepts from the server?\n * Control members are checked for their discriminant and envelope shape; the\n * payload-less `daemon_mesh_result` reply needs its `requestId`; any other well-formed\n * command name becomes a `ServerDirectCommandMsg`.\n */\nexport function decodeServerToDaemon(raw: unknown): ServerToDaemonMsg | null {\n if (!isRecord(raw) || typeof raw.type !== 'string') return null\n const relay = {\n ...readEnvelopeFields(raw),\n ...(isNonEmptyString(raw.source) ? { source: raw.source } : {}),\n }\n if (raw.type === 'daemon_mesh_result') {\n if (!isNonEmptyString(raw.requestId)) return null\n const base = { requestId: raw.requestId, success: raw.success === true }\n return {\n type: 'daemon_mesh_result',\n ...base,\n ...('result' in raw ? { result: raw.result } : {}),\n ...(typeof raw.error === 'string' ? { error: raw.error } : {}),\n }\n }\n if (!isRecord(raw.payload)) return null\n if (isServerToDaemonControlType(raw.type)) {\n return { type: raw.type, payload: raw.payload, ...relay } as ServerToDaemonControlMsg\n }\n if (!isDaemonDirectCommandType(raw.type)) return null\n return { type: raw.type, payload: raw.payload, ...relay }\n}\n","/**\n * protocol/dashboard-server — the dashboard ↔ UserSessionDO WebSocket link,\n * plus the share-viewer ↔ SharedSessionDO link the same dashboard bundle speaks.\n *\n * Wiring-unification Phase A2 (docs/design/2026-09-23-wiring-unification.md §3 A2).\n *\n * Before this file web-cloud `ws.ts` declared its own `IncomingWSMessage`\n * union and `WSEventType`, the server built every outbound frame as an object\n * literal, and the two disagreed: the server's `connected` frame was missing\n * from the dashboard's type, while the dashboard typed `plan_limit_error`,\n * `plan_limit_warning`, `daemon_screenshot` and `agent_event` that no server\n * path has emitted since the dashboard WS command relay was removed. Those four\n * are gone; `connected` is in.\n *\n * Content boundary: this link is server WS. It carries routing metadata,\n * signaling and the approved approval-modal text only (`modalMessage` /\n * `modalButtons`). Chat content rides the P2P link (./dashboard-daemon-p2p.ts).\n */\n\nimport {\n type Envelope,\n type AssertSameMembers,\n isRecord,\n makeTypeGuard,\n readEnvelopeFields,\n} from './envelope'\nimport {\n DAEMON_STATUS_EVENT_NAMES,\n type DaemonStatusEventName,\n type P2PIceWirePayload,\n type P2POfferWirePayload,\n type P2PStatusWireSummary,\n type SeqscribeStatusWireSummary,\n type ReleaseChannelWire,\n type VersionUpdatePolicyWire,\n type VersionUpdateReasonWire,\n} from './daemon-server'\n\n// ─── Status events as delivered to a dashboard ─────────────────────────────\n\n/** Server-originated events the dashboard receives in addition to the daemon set. */\nexport const SERVER_STATUS_EVENT_NAMES = [\n 'daemon:disconnect',\n 'team:session_viewed',\n 'team:view_request',\n 'team:view_request_approved',\n 'team:view_request_rejected',\n] as const\n\n/** Mirror of daemon-core `DashboardStatusEventName`; pinned equal by the server at compile time. */\nexport const DASHBOARD_STATUS_EVENT_NAMES = [...DAEMON_STATUS_EVENT_NAMES, ...SERVER_STATUS_EVENT_NAMES] as const\nexport type DashboardStatusEventName = DaemonStatusEventName | typeof SERVER_STATUS_EVENT_NAMES[number]\nexport const isDashboardStatusEventName = makeTypeGuard(DASHBOARD_STATUS_EVENT_NAMES)\n\nconst _dashboardStatusEventNamesCoverUnion: AssertSameMembers<typeof DASHBOARD_STATUS_EVENT_NAMES, DashboardStatusEventName> = true\nvoid _dashboardStatusEventNamesCoverUnion\n\n/**\n * Sanitized status event as the server relays it (UserSession\n * `buildDashboardStatusEvent`). Mirror of daemon-core\n * `DashboardStatusEventPayload` minus the P2P-only structured prompt fields\n * (`interactivePrompt`/`promptId`/`multiSelect`), which the WS relay never\n * carries — they are agent-authored content.\n */\nexport type DashboardStatusEventWirePayload = {\n event: DashboardStatusEventName\n timestamp: number\n daemonId?: string\n providerType?: string\n targetSessionId?: string\n duration?: number\n elapsedSec?: number\n modalMessage?: string\n modalButtons?: string[]\n requestId?: string\n requesterName?: string\n targetName?: string\n orgId?: string\n permission?: string\n shareUrl?: string\n shareToken?: string\n viewerName?: string\n}\n\n// ─── Bootstrap ─────────────────────────────────────────────────────────────\n\n/**\n * Cold-start machine card. Mirror of daemon-core `DashboardBootstrapDaemonEntry`\n * (which extends `Partial<CloudDaemonSummaryEntry>`), field for field, so the\n * server's entry assigns in and the dashboard's daemon-core-typed consumer\n * assigns out without a cast.\n */\nexport type BootstrapDaemonWireEntry = {\n id: string\n type?: string\n machineId?: string\n platform?: string\n hostname?: string\n nickname?: string\n version?: string\n p2p?: P2PStatusWireSummary\n seqscribe?: SeqscribeStatusWireSummary\n cdpConnected?: boolean\n serverVersion?: string\n releaseChannel?: ReleaseChannelWire\n updateChannel?: ReleaseChannelWire\n updatePolicy?: VersionUpdatePolicyWire\n updateCommand?: string\n versionMismatch?: boolean\n versionUpdateRequired?: boolean\n versionUpdateReason?: VersionUpdateReasonWire\n timestamp?: number\n}\n\nexport const SYSTEM_ANNOUNCEMENT_TYPES = ['info', 'warning', 'critical'] as const\nexport type SystemAnnouncementTypeWire = typeof SYSTEM_ANNOUNCEMENT_TYPES[number]\n\n/** Admin-authored banner; `null` clears it. Mirror of server `ActiveSystemAnnouncement` / web-cloud `SystemAnnouncement`. */\nexport type SystemAnnouncementWire = {\n id: string\n message: string\n type: SystemAnnouncementTypeWire\n createdAt: string | null\n expiresAt: string | null\n}\n\nexport type DashboardBootstrapWirePayload = {\n daemons: BootstrapDaemonWireEntry[]\n announcement?: SystemAnnouncementWire | null\n}\n\nexport type DashboardConnectedWirePayload = {\n message?: string\n peerId: string\n plan: string\n dashboardCount: number\n}\n\n/** Daemon auth rejection relayed to the owner's dashboards — enum reason and counters only (no server-authored sentence). */\nexport type DashboardAuthErrorWirePayload = {\n reason: string\n limit?: number\n current?: number\n}\n\nexport type SystemAnnouncementWirePayload = {\n announcement: SystemAnnouncementWire | null\n}\n\n// ─── Signaling payloads (server → dashboard, from the daemon offerer) ───────\n\nexport type DashboardP2POfferWirePayload = {\n daemonId: string\n peerId?: string\n sdp: string\n type: string\n}\n\nexport type DashboardP2PIceWirePayload = {\n daemonId: string\n peerId?: string\n candidate: string\n mid?: string\n sdpMid?: string | null\n sdpMLineIndex?: number | null\n}\n\n// ─── UserSession → Dashboard ───────────────────────────────────────────────\n\nexport const USER_SESSION_TO_DASHBOARD_TYPES = [\n 'connected',\n 'initial_state',\n 'daemon_status',\n 'status_event',\n 'system_announcement',\n 'auth_error',\n 'heartbeat',\n 'p2p_offer',\n 'p2p_ice',\n] as const\nexport type UserSessionToDashboardType = typeof USER_SESSION_TO_DASHBOARD_TYPES[number]\nexport const isUserSessionToDashboardType = makeTypeGuard(USER_SESSION_TO_DASHBOARD_TYPES)\n\nexport type DashboardConnectedMsg = Envelope<'connected', DashboardConnectedWirePayload>\nexport type DashboardInitialStateMsg = Envelope<'initial_state', DashboardBootstrapWirePayload>\nexport type DashboardDaemonStatusMsg = Envelope<'daemon_status', DashboardBootstrapWirePayload>\nexport type DashboardStatusEventMsg = Envelope<'status_event', DashboardStatusEventWirePayload>\nexport type DashboardSystemAnnouncementMsg = Envelope<'system_announcement', SystemAnnouncementWirePayload>\nexport type DashboardAuthErrorMsg = Envelope<'auth_error', DashboardAuthErrorWirePayload>\n/**\n * Reply to the dashboard's heartbeat. Carries the cached announcement so a\n * stale banner self-corrects; the field is optional because the reply is first\n * of all a liveness signal and must not be dropped by an older server's\n * payload-less spelling.\n */\nexport type DashboardHeartbeatReplyMsg = Envelope<'heartbeat', Partial<SystemAnnouncementWirePayload>>\nexport type DashboardP2POfferMsg = Envelope<'p2p_offer', DashboardP2POfferWirePayload>\nexport type DashboardP2PIceMsg = Envelope<'p2p_ice', DashboardP2PIceWirePayload>\n\nexport type UserSessionToDashboardMsg =\n | DashboardConnectedMsg\n | DashboardInitialStateMsg\n | DashboardDaemonStatusMsg\n | DashboardStatusEventMsg\n | DashboardSystemAnnouncementMsg\n | DashboardAuthErrorMsg\n | DashboardHeartbeatReplyMsg\n | DashboardP2POfferMsg\n | DashboardP2PIceMsg\n\nconst _userSessionToDashboardNamesCoverUnion: AssertSameMembers<typeof USER_SESSION_TO_DASHBOARD_TYPES, UserSessionToDashboardMsg['type']> = true\nvoid _userSessionToDashboardNamesCoverUnion\n\nexport type UserSessionToDashboardPayloadOf<T extends UserSessionToDashboardType> = Extract<UserSessionToDashboardMsg, { type: T }>['payload']\n\n/** Parse boundary for the dashboard. A heartbeat reply is accepted without a payload (liveness first). */\nexport function decodeUserSessionToDashboard(raw: unknown): UserSessionToDashboardMsg | null {\n if (!isRecord(raw) || !isUserSessionToDashboardType(raw.type)) return null\n if (raw.type === 'heartbeat') {\n return { type: 'heartbeat', payload: isRecord(raw.payload) ? raw.payload : {}, ...readEnvelopeFields(raw) }\n }\n if (!isRecord(raw.payload)) return null\n return { type: raw.type, payload: raw.payload, ...readEnvelopeFields(raw) } as UserSessionToDashboardMsg\n}\n\n// ─── Dashboard → UserSession ───────────────────────────────────────────────\n\nexport const DASHBOARD_TO_USER_SESSION_TYPES = ['heartbeat', 'refresh', 'p2p_ready', 'p2p_answer', 'p2p_ice'] as const\nexport type DashboardToUserSessionType = typeof DASHBOARD_TO_USER_SESSION_TYPES[number]\nexport const isDashboardToUserSessionType = makeTypeGuard(DASHBOARD_TO_USER_SESSION_TYPES)\n\n/** Signals a dashboard (answerer) sends toward a daemon; `daemonId` routes, `peerId` identifies the tab. */\nexport const DASHBOARD_P2P_SIGNAL_TYPES = ['p2p_ready', 'p2p_answer', 'p2p_ice'] as const\nexport type DashboardP2PSignalType = typeof DASHBOARD_P2P_SIGNAL_TYPES[number]\nexport const isDashboardP2PSignalType = makeTypeGuard(DASHBOARD_P2P_SIGNAL_TYPES)\n\nexport type DashboardP2PReadyWirePayload = { daemonId: string; peerId: string }\nexport type DashboardP2PAnswerWirePayload = { daemonId: string; peerId: string; sdp: string; type: string }\nexport type DashboardP2PLocalIceWirePayload = {\n daemonId: string\n peerId: string\n candidate: string\n sdpMid: string | null\n sdpMLineIndex: number | null\n}\n\nexport type DashboardHeartbeatMsg = { type: 'heartbeat'; timestamp?: number }\nexport type DashboardRefreshMsg = { type: 'refresh' }\nexport type DashboardP2PReadyMsg = Envelope<'p2p_ready', DashboardP2PReadyWirePayload>\nexport type DashboardP2PAnswerMsg = Envelope<'p2p_answer', DashboardP2PAnswerWirePayload>\nexport type DashboardP2PLocalIceMsg = Envelope<'p2p_ice', DashboardP2PLocalIceWirePayload>\n\nexport type DashboardToUserSessionMsg =\n | DashboardHeartbeatMsg\n | DashboardRefreshMsg\n | DashboardP2PReadyMsg\n | DashboardP2PAnswerMsg\n | DashboardP2PLocalIceMsg\n\nconst _dashboardToUserSessionNamesCoverUnion: AssertSameMembers<typeof DASHBOARD_TO_USER_SESSION_TYPES, DashboardToUserSessionMsg['type']> = true\nvoid _dashboardToUserSessionNamesCoverUnion\n\nexport type DashboardToUserSessionPayloadOf<T extends DashboardP2PSignalType> = Extract<DashboardToUserSessionMsg, { type: T }>['payload']\n\n/** Parse boundary for UserSessionDO. Signals need a `daemonId` to route; without one there is nothing to do. */\nexport function decodeDashboardToUserSession(raw: unknown): DashboardToUserSessionMsg | null {\n if (!isRecord(raw) || !isDashboardToUserSessionType(raw.type)) return null\n if (raw.type === 'heartbeat') return { type: 'heartbeat', ...readEnvelopeFields(raw) }\n if (raw.type === 'refresh') return { type: 'refresh' }\n if (!isRecord(raw.payload) || typeof raw.payload.daemonId !== 'string') return null\n return { type: raw.type, payload: raw.payload, ...readEnvelopeFields(raw) } as DashboardToUserSessionMsg\n}\n\n// ─── SharedSession ↔ share viewer ──────────────────────────────────────────\n\nexport const SHARED_SESSION_TO_VIEWER_TYPES = [\n 'share:connected',\n 'share:revoked',\n 'share:expired',\n 'share:error',\n 'share:viewer_count',\n 'p2p_offer',\n 'p2p_ice',\n] as const\nexport type SharedSessionToViewerType = typeof SHARED_SESSION_TO_VIEWER_TYPES[number]\nexport const isSharedSessionToViewerType = makeTypeGuard(SHARED_SESSION_TO_VIEWER_TYPES)\n\n/** Frames on this link are FLAT (no `payload`), except the relayed signals. Kept as the viewer page reads them. */\nexport type ShareConnectedMsg = {\n type: 'share:connected'\n viewerId: string\n viewerName: string\n permission: string\n mode: string\n providerType: string\n targetSessionId?: string\n ownerName: string\n daemonId: string\n iceServers: unknown[]\n requiresAuth: boolean\n}\nexport type ShareRevokedMsg = { type: 'share:revoked' }\nexport type ShareExpiredMsg = { type: 'share:expired' }\nexport type ShareErrorMsg = { type: 'share:error'; error: string }\nexport type ShareViewerCountMsg = { type: 'share:viewer_count'; count: number; maxViewers: number }\n/**\n * Daemon signal relayed to the addressed viewer, payload as the daemon sent it;\n * `from` is the daemon DO id, which the viewer page folds in as `daemonId`.\n */\nexport type ShareRelayedP2POfferMsg = { type: 'p2p_offer'; payload: P2POfferWirePayload; from: string }\nexport type ShareRelayedP2PIceMsg = { type: 'p2p_ice'; payload: P2PIceWirePayload; from: string }\n\nexport type SharedSessionToViewerMsg =\n | ShareConnectedMsg\n | ShareRevokedMsg\n | ShareExpiredMsg\n | ShareErrorMsg\n | ShareViewerCountMsg\n | ShareRelayedP2POfferMsg\n | ShareRelayedP2PIceMsg\n\nconst _sharedSessionToViewerNamesCoverUnion: AssertSameMembers<typeof SHARED_SESSION_TO_VIEWER_TYPES, SharedSessionToViewerMsg['type']> = true\nvoid _sharedSessionToViewerNamesCoverUnion\n\nexport const VIEWER_TO_SHARED_SESSION_TYPES = ['p2p_ready', 'p2p_offer', 'p2p_answer', 'p2p_ice'] as const\nexport type ViewerToSharedSessionType = typeof VIEWER_TO_SHARED_SESSION_TYPES[number]\nexport const isViewerToSharedSessionType = makeTypeGuard(VIEWER_TO_SHARED_SESSION_TYPES)\n\n/** The viewer's signal as sent; the DO stamps `daemonId`/`peerId`/`sharePermission` before relaying. */\nexport type ViewerToSharedSessionMsg = Envelope<ViewerToSharedSessionType, Record<string, unknown>>\n\nconst _viewerToSharedSessionNamesCoverUnion: AssertSameMembers<typeof VIEWER_TO_SHARED_SESSION_TYPES, ViewerToSharedSessionMsg['type']> = true\nvoid _viewerToSharedSessionNamesCoverUnion\n\n/** Parse boundary for SharedSessionDO: signaling frames only. */\nexport function decodeViewerToSharedSession(raw: unknown): ViewerToSharedSessionMsg | null {\n if (!isRecord(raw) || !isViewerToSharedSessionType(raw.type)) return null\n const payload = isRecord(raw.payload) ? raw.payload : {}\n return { type: raw.type, payload, ...readEnvelopeFields(raw) }\n}\n","/**\n * protocol/dashboard-daemon-p2p — the dashboard ↔ daemon WebRTC DataChannel\n * link (`data` channel, JSON frames; screenshots ride the same channel as\n * binary and are not frames).\n *\n * Wiring-unification Phase A2 (docs/design/2026-09-23-wiring-unification.md §3 A2).\n *\n * Before this file ~20 kinds were matched as bare string literals on both ends\n * (web-cloud `p2p.ts`, daemon-cloud `data-channel-router.ts`), the shared\n * `DashboardP2PMessageKind` listed 12 of them and was imported by nothing, and\n * the daemon's file-operation replies carried no `type` at all — the browser\n * matched them by `id` as a fallthrough. They are now `response` frames.\n *\n * Chunking: any request frame may be split by the sender into\n * `<kind>_chunk` frames (`id`, `chunkId`, `index`, `total`, `data`) when it\n * exceeds `MESH_MAX_INLINE_FRAME_BYTES` (../rpc-chunking.ts). Each direction\n * reassembles BEFORE decoding, so the decoders see whole frames; the chunk\n * envelope is typed here so the splitter and the reassembler agree.\n *\n * Content boundary: this is the P2P plane — rich session data (chat, prompts,\n * transcripts, PTY output) is CORRECT here and must not be reduced.\n */\n\nimport {\n type CommandPayload,\n type MessageId,\n type AssertSameMembers,\n isRecord,\n isNonEmptyString,\n makeTypeGuard,\n} from './envelope'\nimport type { DaemonStatusEventWirePayload } from './daemon-server'\n\n// ─── Chunk envelope (both directions) ──────────────────────────────────────\n\nexport type ChunkFrame<T extends string> = {\n type: T\n /** Request id of the frame being split, when it has one. */\n id?: MessageId\n chunkId: string\n index: number\n total: number\n data: string\n}\n\nexport function isChunkType(value: unknown): value is `${string}_chunk` {\n return typeof value === 'string' && value.endsWith('_chunk') && value.length > '_chunk'.length\n}\n\nfunction readChunkFields(frame: Record<string, unknown>): Omit<ChunkFrame<string>, 'type'> | null {\n if (!isNonEmptyString(frame.chunkId)) return null\n if (!Number.isInteger(frame.index) || !Number.isInteger(frame.total)) return null\n if (typeof frame.data !== 'string') return null\n return {\n ...(isNonEmptyString(frame.id) ? { id: frame.id } : {}),\n chunkId: frame.chunkId,\n index: frame.index as number,\n total: frame.total as number,\n data: frame.data,\n }\n}\n\n// ─── Dashboard → Daemon ────────────────────────────────────────────────────\n\nexport const DASHBOARD_TO_DAEMON_P2P_TYPES = [\n 'ping',\n 'pong',\n 'command',\n 'input',\n 'pty_input',\n 'pty_resize',\n 'screenshot_start',\n 'screenshot_stop',\n 'subscribe',\n 'unsubscribe',\n 'seqscribe_session_interest',\n 'read',\n 'write',\n 'list',\n] as const\nexport type DashboardToDaemonP2PType = typeof DASHBOARD_TO_DAEMON_P2P_TYPES[number]\nexport const isDashboardToDaemonP2PType = makeTypeGuard(DASHBOARD_TO_DAEMON_P2P_TYPES)\n\nexport type DashboardToDaemonChunkType = `${DashboardToDaemonP2PType}_chunk`\nexport function isDashboardToDaemonChunkType(value: unknown): value is DashboardToDaemonChunkType {\n return isChunkType(value) && isDashboardToDaemonP2PType(value.slice(0, -'_chunk'.length))\n}\n\nexport type P2PPingMsg = { type: 'ping'; ts: number }\nexport type P2PPongMsg = { type: 'pong'; ts: number }\n/** A command routed through the daemon's command router; `commandType`/`data` are dynamic by design. */\nexport type P2PCommandMsg = { type: 'command'; id: MessageId; commandType: string; data: CommandPayload }\n/** Remote-desktop input (click/type/key) for the target session's IDE surface. */\nexport type P2PInputMsg = { type: 'input'; id: MessageId; action: string; params: CommandPayload; targetSessionId?: string }\n/** Raw PTY input. `sessionId` is canonical; `targetSessionId` is the accepted alias. */\nexport type P2PPtyInputMsg = { type: 'pty_input'; sessionId?: string; targetSessionId?: string; data: string }\nexport type P2PPtyResizeMsg = { type: 'pty_resize'; sessionId: string; cols: number; rows: number }\nexport type P2PScreenshotStartMsg = { type: 'screenshot_start'; targetSessionId: string }\nexport type P2PScreenshotStopMsg = { type: 'screenshot_stop'; targetSessionId?: string }\n/**\n * Topic subscription. `params` is topic-specific (daemon-core `SubscribeRequestMap`); `object` keeps every topic's interface assignable.\n * `wireVersion` is the dashboard wire version the page speaks (./dashboard-wire-version.ts).\n */\nexport type P2PSubscribeMsg = { type: 'subscribe'; topic: string; key: string; params: object; wireVersion?: number }\nexport type P2PUnsubscribeMsg = { type: 'unsubscribe'; topic: string; key: string }\n/** Which sessions this peer wants replicated over the seqscribe lane; also the peer's responder proof. */\nexport type P2PSessionInterestMsg = { type: 'seqscribe_session_interest'; sessionIds: readonly string[] }\nexport type P2PFileReadMsg = { type: 'read'; id: MessageId; path: string }\nexport type P2PFileWriteMsg = { type: 'write'; id: MessageId; path: string; content: string }\nexport type P2PFileListMsg = { type: 'list'; id: MessageId; path: string }\nexport type DashboardToDaemonChunkMsg = ChunkFrame<DashboardToDaemonChunkType>\n\nexport type DashboardToDaemonP2PMsg =\n | P2PPingMsg\n | P2PPongMsg\n | P2PCommandMsg\n | P2PInputMsg\n | P2PPtyInputMsg\n | P2PPtyResizeMsg\n | P2PScreenshotStartMsg\n | P2PScreenshotStopMsg\n | P2PSubscribeMsg\n | P2PUnsubscribeMsg\n | P2PSessionInterestMsg\n | P2PFileReadMsg\n | P2PFileWriteMsg\n | P2PFileListMsg\n\nconst _dashboardToDaemonNamesCoverUnion: AssertSameMembers<typeof DASHBOARD_TO_DAEMON_P2P_TYPES, DashboardToDaemonP2PMsg['type']> = true\nvoid _dashboardToDaemonNamesCoverUnion\n\n/** Request kinds the daemon answers by `id`; a frame without one cannot be answered and is dropped at the boundary. */\nconst DASHBOARD_REQUEST_TYPES = new Set<DashboardToDaemonP2PType>(['command', 'input', 'read', 'write', 'list'])\n\n/** Parse boundary for the daemon's chunk reassembler: one `<kind>_chunk` piece of a split request. */\nexport function decodeDashboardToDaemonP2PChunk(raw: unknown): DashboardToDaemonChunkMsg | null {\n if (!isRecord(raw) || !isDashboardToDaemonChunkType(raw.type)) return null\n const fields = readChunkFields(raw)\n return fields ? { type: raw.type, ...fields } : null\n}\n\n/**\n * Parse boundary for the daemon (after chunk reassembly): a whole request.\n * Chunk pieces are not requests and decode to null here; see\n * `decodeDashboardToDaemonP2PChunk`.\n */\nexport function decodeDashboardToDaemonP2P(raw: unknown): DashboardToDaemonP2PMsg | null {\n if (!isRecord(raw) || !isDashboardToDaemonP2PType(raw.type)) return null\n if (DASHBOARD_REQUEST_TYPES.has(raw.type) && !isNonEmptyString(raw.id)) return null\n return raw as DashboardToDaemonP2PMsg\n}\n\n// ─── Daemon → Dashboard ────────────────────────────────────────────────────\n\nexport const DAEMON_TO_DASHBOARD_P2P_TYPES = [\n 'ping',\n 'pong',\n 'p2p_evicted',\n 'status_event',\n 'topic_update',\n 'topic_update_chunk',\n 'session_output',\n 'session_output_chunk',\n 'session_io_error',\n 'command_result',\n 'command_result_chunk',\n 'response',\n 'transcript_topics_available',\n] as const\nexport type DaemonToDashboardP2PType = typeof DAEMON_TO_DASHBOARD_P2P_TYPES[number]\nexport const isDaemonToDashboardP2PType = makeTypeGuard(DAEMON_TO_DASHBOARD_P2P_TYPES)\n\n/** The server-bound event plus the P2P-only structured prompt (daemon-core `P2PStatusEventPayload`). */\nexport type P2PStatusEventWirePayload = DaemonStatusEventWirePayload & {\n interactivePrompt?: unknown\n promptId?: string\n multiSelect?: boolean\n}\n\n/** One topic update (daemon-core `TopicUpdateEnvelope`); consumers narrow by `topic`. */\nexport type TopicUpdateWireEnvelope = { topic: string; key: string }\n\nexport type P2PFileEntry = { name: string; type: string; size?: number }\n\nexport type P2PEvictedMsg = { type: 'p2p_evicted'; reason: string; maxconnections: number }\nexport type P2PStatusEventMsg = { type: 'status_event'; payload: P2PStatusEventWirePayload; timestamp: number }\nexport type P2PTopicUpdateMsg = { type: 'topic_update'; update: TopicUpdateWireEnvelope }\nexport type P2PTopicUpdateChunkMsg = ChunkFrame<'topic_update_chunk'>\nexport type P2PSessionOutputMsg = { type: 'session_output'; sessionId: string; data: string }\nexport type P2PSessionOutputChunkMsg = ChunkFrame<'session_output_chunk'> & { sessionId: string }\nexport type P2PSessionIoErrorMsg = { type: 'session_io_error'; sessionId: string; reason: string; error?: string }\n/** Result of a `command` frame. The router spreads the handler result in; `resultId` preserves a result-side `id`. */\nexport type P2PCommandResultMsg = { type: 'command_result'; id: MessageId; success: boolean; error?: string; resultId?: unknown } & Record<string, unknown>\nexport type P2PCommandResultChunkMsg = ChunkFrame<'command_result_chunk'>\n/** Result of an `input` or file (`read`/`write`/`list`) frame. */\nexport type P2PResponseMsg = {\n type: 'response'\n id: MessageId\n success: boolean\n result?: unknown\n error?: string\n content?: string\n entries?: P2PFileEntry[]\n}\n\n/**\n * `session.<id>.chat` topics that just became SUB-able for THIS peer (the\n * topic was defined, or the peer's declared session interest widened to it).\n * Sent only after the grant is in place, so a seqscribe SUB issued on receipt\n * is accepted; without it the browser can only guess when to re-SUB a refused\n * subscription. Topic names only — the P2P plane already carries the ids.\n */\nexport type P2PTranscriptTopicsAvailableMsg = { type: 'transcript_topics_available'; topics: string[] }\n\nexport type DaemonToDashboardP2PMsg =\n | P2PPingMsg\n | P2PPongMsg\n | P2PEvictedMsg\n | P2PStatusEventMsg\n | P2PTopicUpdateMsg\n | P2PTopicUpdateChunkMsg\n | P2PSessionOutputMsg\n | P2PSessionOutputChunkMsg\n | P2PSessionIoErrorMsg\n | P2PCommandResultMsg\n | P2PCommandResultChunkMsg\n | P2PResponseMsg\n | P2PTranscriptTopicsAvailableMsg\n\nconst _daemonToDashboardNamesCoverUnion: AssertSameMembers<typeof DAEMON_TO_DASHBOARD_P2P_TYPES, DaemonToDashboardP2PMsg['type']> = true\nvoid _daemonToDashboardNamesCoverUnion\n\n/** Parse boundary for the dashboard (after chunk reassembly). */\nexport function decodeDaemonToDashboardP2P(raw: unknown): DaemonToDashboardP2PMsg | null {\n if (!isRecord(raw)) return null\n if (!isDaemonToDashboardP2PType(raw.type)) return null\n switch (raw.type) {\n case 'ping':\n case 'pong':\n case 'p2p_evicted':\n return raw as DaemonToDashboardP2PMsg\n case 'status_event':\n return isRecord(raw.payload) ? (raw as DaemonToDashboardP2PMsg) : null\n case 'topic_update':\n return isRecord(raw.update) ? (raw as P2PTopicUpdateMsg) : null\n case 'topic_update_chunk':\n case 'command_result_chunk':\n case 'session_output_chunk': {\n const fields = readChunkFields(raw)\n if (!fields) return null\n if (raw.type === 'session_output_chunk') {\n return isNonEmptyString(raw.sessionId) ? { type: raw.type, sessionId: raw.sessionId, ...fields } : null\n }\n return { type: raw.type, ...fields }\n }\n case 'session_output':\n return isNonEmptyString(raw.sessionId) && typeof raw.data === 'string' ? (raw as P2PSessionOutputMsg) : null\n case 'session_io_error':\n return isNonEmptyString(raw.sessionId) ? (raw as P2PSessionIoErrorMsg) : null\n case 'command_result':\n case 'response':\n return isNonEmptyString(raw.id) ? (raw as DaemonToDashboardP2PMsg) : null\n case 'transcript_topics_available':\n return Array.isArray(raw.topics) && raw.topics.every((topic) => typeof topic === 'string')\n ? { type: raw.type, topics: raw.topics as string[] }\n : null\n }\n}\n\n/** Both directions, for the legacy `DashboardP2PMessageKind` name and the drift gate. */\nexport const DASHBOARD_P2P_MESSAGE_KINDS = [\n ...new Set<string>([...DASHBOARD_TO_DAEMON_P2P_TYPES, ...DAEMON_TO_DASHBOARD_P2P_TYPES]),\n] as ReadonlyArray<DashboardToDaemonP2PType | DaemonToDashboardP2PType>\n","/**\n * protocol/dashboard-wire-version — the dashboard ↔ daemon wire version.\n *\n * Both dashboards (cloud over P2P, standalone over WS) state the version they\n * speak on every topic subscribe; the daemon states its own on the standalone\n * hello, on every keyed snapshot frame, and in the `protocol_mismatch` reply it\n * sends INSTEAD of state when the two differ. There is no dual-format serving:\n * a mismatched pair renders no state at all —\n * - the page is older than the daemon → the page must reload (its bundle\n * cannot read the daemon's frames);\n * - the daemon is older than the page → the daemon must be updated.\n *\n * Bump this whenever a frame shape changes incompatibly; one release carries\n * the same value on both ends.\n * 1 — implicit (frames before versioning).\n * 2 — daemon.metadata deltas on the keyed-doc engine (2026-09-29).\n */\nexport const DASHBOARD_WIRE_VERSION = 2\n\nexport type DashboardWireCompat = 'ok' | 'reload_required' | 'daemon_update_required'\n\n/** How a page speaking `pageVersion` relates to a daemon speaking `daemonVersion` (absent = 1). */\nexport function compareDashboardWireVersion(pageVersion: number, daemonVersion: number | null | undefined): DashboardWireCompat {\n const daemon = typeof daemonVersion === 'number' && Number.isFinite(daemonVersion) ? daemonVersion : 1\n if (daemon === pageVersion) return 'ok'\n return daemon > pageVersion ? 'reload_required' : 'daemon_update_required'\n}\n","/**\n * ws-protocol — name-only aliases for the daemon↔server WS surface and the\n * daemon↔dashboard P2P DataChannel surface, plus the `auth_ok.payload.limits`\n * contract.\n *\n * Wiring-unification Phase A2: the typed frame unions now live in ./protocol\n * (one file per link, payloads included). This file keeps the symbols that\n * pre-dated them — `DaemonToServerWsMsg`, `ServerToDaemonWsMsg`,\n * `P2PSignalingWsMsg`, `DashboardP2PMessageKind` and the two name arrays —\n * DERIVED from the protocol unions rather than re-declared, so they cannot\n * drift again. Before this derivation the list here said `offer|answer|ice`\n * while the wire said `p2p_offer|p2p_answer|p2p_ice`, declared a `log` frame\n * nothing sent or handled, omitted `daemon_mesh_command` (sent by a raw\n * `ws.send`), and listed 12 of the ~27 P2P kinds — and nothing imported the\n * drifted members, so nothing noticed.\n */\n\nimport {\n DAEMON_TO_SERVER_TYPES,\n SERVER_TO_DAEMON_CONTROL_TYPES,\n type DaemonToServerType,\n type ServerToDaemonControlType,\n type P2PSignalType,\n type MeshP2PSignalType,\n type DashboardToDaemonP2PType,\n type DaemonToDashboardP2PType,\n} from './protocol';\n\n/** Messages the daemon sends UP to the Workers server over the WS bridge (see protocol/daemon-server.ts). */\nexport type DaemonToServerWsMsg = DaemonToServerType;\n\n/**\n * Server→daemon CONTROL messages (see protocol/daemon-server.ts). The server\n * additionally relays an open command namespace as the frame `type`\n * (`ServerDirectCommandMsg`), which is deliberately not a member here.\n */\nexport type ServerToDaemonWsMsg = ServerToDaemonControlType;\n\n/** P2P signaling relayed through the server WS — the `p2p_`/`mesh_p2p_` spellings the wire actually uses. */\nexport type P2PSignalingWsMsg = P2PSignalType | MeshP2PSignalType;\n\n/** Every dashboard↔daemon P2P DataChannel JSON kind, both directions (see protocol/dashboard-daemon-p2p.ts). */\nexport type DashboardP2PMessageKind = DashboardToDaemonP2PType | DaemonToDashboardP2PType;\n\nexport const DAEMON_TO_SERVER_WS_MSGS: readonly DaemonToServerWsMsg[] = DAEMON_TO_SERVER_TYPES;\n\nexport const SERVER_TO_DAEMON_WS_MSGS: readonly ServerToDaemonWsMsg[] = SERVER_TO_DAEMON_CONTROL_TYPES;\n\n\n\n/**\n * `auth_ok.payload.limits` — the plan-limit contract the server sends DOWN to\n * the daemon for client-side enforcement.\n *\n * WHY THIS EXISTS: the wire spelling is `maxP2Pconnections` (lowercase `c`),\n * inherited from `PlanLimits` in the proprietary server's plan-limits.ts. The\n * daemon-cloud consumer independently declared the same field as\n * `maxP2PConnections` (capital `C`) and assigned it from a `payload as any`\n * cast — so the two spellings NEVER met under a type, TypeScript had nothing\n * to compare, and the limit arrived as `undefined` at every comparison site.\n * `undefined !== -1` passes the \"is it unlimited?\" guard, then every\n * `count >= undefined` is false: enforcement silently degraded to unlimited on\n * all plans, in production, for months.\n *\n * The lesson is NOT \"pick a spelling\" — it is that a cross-package wire\n * contract asserted by hand on both ends with an `any` in between cannot fail\n * loudly. Both producer (server) and consumer (daemon-cloud) must now import\n * THIS symbol, so a rename breaks the build on both sides instead of silently\n * disabling a paid-plan limit. Use `normalizeAuthOkLimits()` at the parse\n * boundary; never re-spell these fields locally.\n */\nexport interface AuthOkPlanLimits {\n /** P2P concurrent connection count (-1 = unlimited). WIRE SPELLING — lowercase `c`. */\n maxP2Pconnections: number;\n /** Screenshot send interval floor (seconds). 0 = real-time. */\n screenshotIntervalSeconds: number;\n /** Daily screenshot usage budget (minutes). -1 = unlimited. */\n dailyScreenshotMinutes: number;\n /** Max connectable machines/daemons (-1 = unlimited). */\n maxMachines: number;\n}\n\n/**\n * Parse-boundary normalizer for `auth_ok.payload.limits`.\n *\n * Returns `null` when the payload carries no usable limits object, so callers\n * keep their existing \"no limits known yet\" branch. Individual non-numeric or\n * missing fields fall back to the UNLIMITED sentinel (-1) for count-style\n * limits and 0 for the interval floor, matching how each consumer already\n * treats \"no constraint\" — a malformed field must never be coerced to a\n * MORE restrictive value than the server intended, or a server-side schema\n * change would start throttling paying users.\n *\n * Accepts the capital-`C` misspelling as an input alias ONLY so a daemon\n * talking to a mixed-version fleet cannot regress; output is always the\n * canonical wire spelling.\n */\nexport function normalizeAuthOkLimits(raw: unknown): AuthOkPlanLimits | null {\n if (!raw || typeof raw !== 'object') return null;\n const src = raw as Record<string, unknown>;\n const num = (value: unknown, fallback: number): number =>\n typeof value === 'number' && Number.isFinite(value) ? value : fallback;\n return {\n maxP2Pconnections: num(\n src.maxP2Pconnections !== undefined ? src.maxP2Pconnections : src.maxP2PConnections,\n -1,\n ),\n screenshotIntervalSeconds: num(src.screenshotIntervalSeconds, 0),\n dailyScreenshotMinutes: num(src.dailyScreenshotMinutes, -1),\n maxMachines: num(src.maxMachines, -1),\n };\n}\n","export const CLAUDE_TUI_REVIEW_PAGE_NOT_FOCUSED_PREFIX = 'Claude TUI review page is not focused';\n\n/**\n * The answer keystrokes reached the terminal, but the daemon could not CONFIRM\n * the review page before its settle budget expired — the picker was still\n * showing our own bound question, not a foreign widget.\n *\n * This is deliberately a separate class from\n * CLAUDE_TUI_REVIEW_PAGE_NOT_FOCUSED_PREFIX, which means \"the screen is\n * something we do not own, so we refuse to press Enter into it\". Here the\n * screen IS ours and the input WAS delivered; only the confirmation is\n * missing. Resending would replay the whole keystroke sequence into a picker\n * that may have advanced in the meantime, so the UI for this class must NOT\n * invite a retry. See the daemon-side gate in\n * `providers/spec/cli-adapter.ts` (assertFocusedClaudeTuiReview) and the web\n * mapping in `web-core/src/hooks/useInteractivePrompt.ts`.\n */\nexport const CLAUDE_TUI_REVIEW_UNCONFIRMED_PREFIX = 'Claude TUI answer delivered but not confirmed';\n","/**\n * session-status — the ONE session status vocabulary.\n *\n * Wiring-unification Phase A1 (docs/design/2026-09-23-wiring-unification.md).\n *\n * Before this file, the same eleven-member union was declared three times in\n * daemon-core (`SessionStatus`, `ManagedStatus`, and a stale `AgentStatus`) and\n * five independent \"is it busy?\" sets disagreed with each other — for example\n * `waiting_approval` counted as busy in three of them and idle in the other\n * two. Every consumer now derives from here:\n *\n * - the canonical union `SessionStatus` and its member list `SESSION_STATUSES`;\n * - a behavioural CLASS per status (`SESSION_STATUS_CLASS`) — the only thing\n * send / dispatch / UI logic may branch on;\n * - an alias table for the raw spellings providers and status lanes still\n * emit (`running`, `streaming`, `no_progress`, …) so classification is total.\n *\n * This lives in mesh-shared (a dependency-free leaf) because web-core must not\n * value-import the daemon-core barrel, and the server has no daemon-core at all.\n */\n\nexport const SESSION_STATUSES = [\n 'idle',\n 'generating',\n 'waiting_approval',\n 'waiting_choice',\n 'finalizing',\n 'error',\n 'stopped',\n 'starting',\n 'panel_hidden',\n 'not_monitored',\n 'disconnected',\n] as const\n\nexport type SessionStatus = typeof SESSION_STATUSES[number]\n\nexport const RECENT_SESSION_BUCKETS = ['needs_attention', 'working', 'task_complete', 'idle'] as const\n\nexport type RecentSessionBucket = typeof RECENT_SESSION_BUCKETS[number]\n\n/**\n * Behavioural class of a status.\n *\n * working — the agent owns the turn; input is queued, not delivered.\n * blocked — the agent is waiting on a human decision (approval / choice);\n * alive, and the turn is not over.\n * ready — the agent will accept input now.\n * dead — the session will never accept input again.\n * unknown — the spelling is not one we classify (callers must fail safe).\n */\nexport type SessionStatusClass = 'working' | 'blocked' | 'ready' | 'dead' | 'unknown'\n\nexport const SESSION_STATUS_CLASS: Record<SessionStatus, Exclude<SessionStatusClass, 'unknown'>> = {\n generating: 'working',\n finalizing: 'working',\n starting: 'working',\n waiting_approval: 'blocked',\n waiting_choice: 'blocked',\n idle: 'ready',\n panel_hidden: 'ready',\n not_monitored: 'ready',\n error: 'dead',\n stopped: 'dead',\n disconnected: 'dead',\n}\n\n/**\n * Raw spellings that still reach status consumers from IDE/CDP providers, the\n * chat-tail status lane and legacy adapters, mapped onto the canonical member\n * that carries the same behavioural meaning. Keep this table exhaustive over\n * what the five pre-unification busy sets accepted; a spelling missing here\n * classifies as `unknown`, which every consumer must treat as \"do not assume\n * idle\".\n */\nexport const SESSION_STATUS_ALIASES: Readonly<Record<string, SessionStatus>> = {\n running: 'generating',\n streaming: 'generating',\n busy: 'generating',\n working: 'generating',\n loading: 'generating',\n loading_reference: 'generating',\n thinking: 'generating',\n active: 'generating',\n // Status-lane refinements of a turn that is still owned by the agent.\n no_progress: 'generating',\n long_generating: 'generating',\n initializing: 'starting',\n waiting: 'waiting_approval',\n}\n\nconst SESSION_STATUS_SET: ReadonlySet<string> = new Set(SESSION_STATUSES)\n\nexport function isSessionStatus(value: unknown): value is SessionStatus {\n return typeof value === 'string' && SESSION_STATUS_SET.has(value)\n}\n\n/** Canonical member for a raw status spelling, or null when unrecognised. */\nexport function normalizeSessionStatus(raw: unknown): SessionStatus | null {\n if (typeof raw !== 'string') return null\n const value = raw.trim().toLowerCase()\n if (SESSION_STATUS_SET.has(value)) return value as SessionStatus\n return SESSION_STATUS_ALIASES[value] ?? null\n}\n\nexport function classifySessionStatus(raw: unknown): SessionStatusClass {\n const status = normalizeSessionStatus(raw)\n return status ? SESSION_STATUS_CLASS[status] : 'unknown'\n}\n\nexport function isWorkingStatus(raw: unknown): boolean {\n return classifySessionStatus(raw) === 'working'\n}\n\nexport function isBlockedStatus(raw: unknown): boolean {\n return classifySessionStatus(raw) === 'blocked'\n}\n\nexport function isReadyStatus(raw: unknown): boolean {\n return classifySessionStatus(raw) === 'ready'\n}\n\nexport function isDeadStatus(raw: unknown): boolean {\n return classifySessionStatus(raw) === 'dead'\n}\n\n/**\n * \"Busy\" in the sense every pre-unification set meant: the agent cannot take a\n * new instruction right now, whether because it is working or because it is\n * blocked on a human. Dead sessions are NOT busy — they are gone, and callers\n * that need to distinguish must check `isDeadStatus` first.\n */\nexport function isBusyStatus(raw: unknown): boolean {\n const cls = classifySessionStatus(raw)\n return cls === 'working' || cls === 'blocked'\n}\n\nexport function statusesOfClass(cls: Exclude<SessionStatusClass, 'unknown'>): SessionStatus[] {\n return SESSION_STATUSES.filter((status) => SESSION_STATUS_CLASS[status] === cls)\n}\n\n/**\n * Mesh-record terminal spellings: a session RECORD in one of these is gone\n * (the vocabulary's `dead` class covers the canonical members; records also\n * carry `failed` / `terminated` / `exited` / `closed`).\n */\nexport const TERMINAL_SESSION_RECORD_STATUSES = ['stopped', 'failed', 'terminated', 'exited', 'closed'] as const\n\nexport function isTerminalSessionRecordStatus(raw: unknown): boolean {\n return typeof raw === 'string' && (TERMINAL_SESSION_RECORD_STATUSES as readonly string[]).includes(raw.trim().toLowerCase())\n}\n\n/**\n * THE \"idle — can take a task now\" predicate over a session state/record (its\n * top-level `status` and chat lane). Every idle-candidate check (queue drain,\n * auto-launch orphan sweep, dispatch pick) uses this one, so they cannot\n * disagree about which sessions are candidates.\n */\nexport function isIdleSessionState(state: unknown): boolean {\n const record = state && typeof state === 'object' ? state as { status?: unknown; activeChat?: { status?: unknown } } : {}\n const status = typeof record.status === 'string' ? record.status.trim().toLowerCase() : ''\n if (isTerminalSessionRecordStatus(status) || isDeadStatus(status)) return false\n return isReadyStatus(status) || record.activeChat?.status === 'waiting_input'\n}\n","/**\n * mesh-vocabulary — the ONE declaration of every mesh enum.\n *\n * Wiring-unification Phase A3 (docs/design/2026-09-23-wiring-unification.md).\n *\n * Before this file `MeshTaskStatus` was declared twice in daemon-core with\n * different members (one carried `in_progress`, which no task row ever held),\n * a third time in `repo-mesh-types.ts`, and loosened to `| string` in web-core;\n * the MCP tool schemas hand-copied the task-mode list six times. Every enum a\n * mesh tool, ledger row, queue entry or dashboard view branches on is declared\n * here once, as a `const` tuple, and the type is derived from it. JSON-schema\n * producers use `enumOf()` so the published schema cannot drift from the code.\n *\n * `MeshTaskDifficulty` / `MESH_TASK_DIFFICULTIES` already live in\n * ./brain-routing.ts and are re-exported here for one-stop discovery.\n */\n\nexport { MESH_TASK_DIFFICULTIES, type MeshTaskDifficulty } from './brain-routing'\n\nexport const MESH_TASK_STATUSES = ['pending', 'assigned', 'completed', 'failed', 'cancelled'] as const\nexport type MeshTaskStatus = typeof MESH_TASK_STATUSES[number]\n\nexport const MESH_TERMINAL_TASK_STATUSES = ['completed', 'failed', 'cancelled'] as const\nexport type MeshTerminalTaskStatus = typeof MESH_TERMINAL_TASK_STATUSES[number]\n\nexport const MESH_TASK_MODES = ['code_change', 'validation', 'live_debug_readonly', 'launch_app', 'convergence'] as const\nexport type MeshTaskMode = typeof MESH_TASK_MODES[number]\n\nexport const MESH_TASK_PRIORITIES = ['low', 'normal', 'high'] as const\nexport type MeshTaskPriority = typeof MESH_TASK_PRIORITIES[number]\n\nexport const MESH_THINKING_LEVELS = ['low', 'medium', 'high'] as const\nexport type MeshThinkingLevel = typeof MESH_THINKING_LEVELS[number]\n\n/**\n * How a message is delivered to a session that may be busy.\n *\n * 'when_idle' — DEFAULT. Never disturbs a running turn; a busy session's task\n * is queued and auto-delivered on its next idle transition.\n * 'interrupt' — Abort the in-flight turn (the provider's own stop control),\n * then deliver once the session settles to idle. The name is\n * deliberately blunt: the unfinished work is LOST. `immediate`\n * was rejected as a name because it reads like a gentle overlay.\n */\nexport const MESH_DELIVERY_MODES = ['when_idle', 'interrupt'] as const\nexport type MeshDeliveryMode = typeof MESH_DELIVERY_MODES[number]\n\n/**\n * What to do with a node's sessions when the node is removed. Declared here so daemon-core (`RepoMeshSessionCleanupMode`), the\n * web dashboard picker and the MCP schemas all read one list.\n */\nexport const MESH_SESSION_CLEANUP_MODES = ['preserve', 'stop', 'delete_stopped', 'stop_and_delete'] as const\nexport type MeshSessionCleanupMode = typeof MESH_SESSION_CLEANUP_MODES[number]\n\n/** Outcome a delegated worker may report through `report_completion`. */\nexport const WORKER_REPORT_OUTCOMES = ['completed', 'blocked', 'failed'] as const\nexport type WorkerReportOutcome = typeof WORKER_REPORT_OUTCOMES[number]\n\n/** Final branch state a worker reports (see coordinator convergence rules). */\nexport const WORKER_BRANCH_STATES = [\n 'merged_to_main',\n 'pushed_feature_branch_needs_merge',\n 'blocked_review',\n 'cleanup_candidate',\n 'not_mergeable',\n] as const\nexport type WorkerBranchState = typeof WORKER_BRANCH_STATES[number]\n\nfunction makeGuard<T extends readonly string[]>(values: T): (value: unknown) => value is T[number] {\n const set: ReadonlySet<string> = new Set(values)\n return (value: unknown): value is T[number] => typeof value === 'string' && set.has(value)\n}\n\nexport const isMeshTaskStatus = makeGuard(MESH_TASK_STATUSES)\nexport const isMeshTerminalTaskStatus = makeGuard(MESH_TERMINAL_TASK_STATUSES)\nexport const isMeshTaskMode = makeGuard(MESH_TASK_MODES)\nexport const isMeshTaskPriority = makeGuard(MESH_TASK_PRIORITIES)\nexport const isMeshDeliveryMode = makeGuard(MESH_DELIVERY_MODES)\nexport const isWorkerReportOutcome = makeGuard(WORKER_REPORT_OUTCOMES)\n\n/**\n * JSON-schema fragment for a string enum, derived from the tuple. Use this in\n * every MCP tool schema instead of spelling the member list again.\n */\nexport function enumOf<T extends readonly string[]>(\n values: T,\n description?: string,\n): { type: 'string'; enum: T[number][]; description?: string } {\n return {\n type: 'string',\n enum: [...values] as T[number][],\n ...(description ? { description } : {}),\n }\n}\n","/**\n * outbound-message — the one send-side unit crossing every transport.\n *\n * Wiring-unification Phase D (docs/design/2026-09-23-wiring-unification.md §6,\n * D1) / workstream D-web. Full type derivation in the scratchpad\n * `phase-D-plan.md` §1.1-§1.2 (`OutboundMessage`/`SendPolicy`/`SubmitOutcome`/\n * `SendRefusal`). `SendRefusal` is imported from here by Phase C1's\n * `turn-evidence.ts` (`RECLAIMING_SEND_REFUSALS`) — this file owns the type,\n * C1 owns which of its members reclaim a mesh dispatch attempt.\n *\n * Before this type, a chat send was represented by twelve different loose\n * request shapes (`{message, sendNow?, interrupt?}`, `{message, input}`,\n * mesh `agent_command` args, MCP tool args, ...) and parked messages had no\n * identity at all — the driver queue was keyed by exact text, so send-now,\n * cancel, interrupt and the web echo-retirement all recovered identity by\n * string matching. `OutboundMessage.messageId` is minted once, at the\n * ORIGIN, and is the identity every layer keys on afterwards: the wire\n * field in the `send_chat` command payload, the driver's queue key (daemon\n * side, Phase D-daemon), the web pending-store key (`pendingQueuedMessages.ts`)\n * and the echo-retirement key (`conversation-message-snapshot.ts`).\n *\n * This file is dependency-free by construction (mesh-shared leaf rule):\n * `InputEnvelopeWire`/`InputPartWire` are STRUCTURAL MIRRORS of daemon-core's\n * `InputEnvelope`/`InputPart` (`oss/packages/daemon-core/src/providers/\n * io-contracts.ts`), not re-exports — daemon-core assigns its richer type\n * into this one, never the other way round, so this package's published\n * `.d.ts` never references a package that depends on it.\n */\n\n// ─── Input envelope (structural mirror of daemon-core's InputEnvelope) ─────\n\nexport interface ContentAnnotationsWire {\n audience?: ('user' | 'assistant')[]\n priority?: number\n}\n\nexport interface TextInputPartWire {\n type: 'text'\n text: string\n}\n\nexport interface ImageInputPartWire {\n type: 'image'\n mimeType: string\n uri?: string\n data?: string\n alt?: string\n}\n\nexport interface AudioInputPartWire {\n type: 'audio'\n mimeType: string\n uri?: string\n data?: string\n transcript?: string\n}\n\nexport interface VideoInputPartWire {\n type: 'video'\n mimeType: string\n uri?: string\n data?: string\n transcript?: string\n posterUri?: string\n}\n\nexport interface ResourceInputPartWire {\n type: 'resource'\n uri: string\n mimeType?: string\n name?: string\n text?: string\n data?: string\n}\n\nexport interface ResourceLinkInputPartWire {\n type: 'resource_link'\n uri: string\n name: string\n title?: string\n description?: string\n mimeType?: string\n size?: number\n annotations?: ContentAnnotationsWire\n}\n\nexport type InputPartWire =\n | TextInputPartWire\n | ImageInputPartWire\n | AudioInputPartWire\n | VideoInputPartWire\n | ResourceLinkInputPartWire\n | ResourceInputPartWire\n\nexport interface InputEnvelopeWire {\n parts: InputPartWire[]\n textFallback: string\n metadata?: {\n source?: 'dashboard' | 'shortcut_api' | 'provider_script' | 'session_replay'\n clientTimestamp?: number\n }\n}\n\n// ─── OutboundMessage ────────────────────────────────────────────────────────\n\n/**\n * Who minted this `OutboundMessage`. Determines default policy and refusal\n * surface — 'mesh' origins get the mesh-specific `SendRefusal` reasons,\n * interactive origins get the interactive ones.\n *\n * `'api'`/`'cli'` are carried per the design doc's D1 type even though no\n * current call site produces them distinct from `'dashboard'`/`'mcp'`/\n * `'mesh'` (flagged as an open question in phase-D-plan.md §7.3 risk 5) —\n * kept here unchanged pending an owner decision; dropping a union member is\n * a decision for whoever lands D-daemon/D2, not this workstream.\n *\n * `'assistant'`: the assistant layer's `project_send` into a project\n * coordinator (docs/design/2026-10-07-assistant-layer.md §4.3 step 4). A label\n * only — it is not an auth signal and selects no policy of its own.\n */\nexport type OutboundMessageOrigin = 'dashboard' | 'mcp' | 'mesh' | 'api' | 'cli' | 'assistant'\n\n/**\n * How this message should be admitted when the session is not idle.\n * Replaces the loose `sendNow`/`interrupt`/`force`/`forceSend` booleans (and\n * mesh `delivery_mode`) with one closed union. `'queue'` is the default for\n * every origin.\n */\nexport type SendPolicy =\n | { mode: 'queue' }\n | { mode: 'send_now' }\n | { mode: 'interrupt' }\n\n/**\n * Every reason `submit()` can refuse a message, closed so callers branch on it\n * instead of matching free text.\n *\n * ★ This is THE `SendRefusal` (docs/design/2026-09-23-wiring-unification.md\n * §6 D1) — Phase C1's `turn-evidence.ts` imports `SendRefusal`/\n * `SEND_REFUSAL_REASONS` from this file (`RECLAIMING_SEND_REFUSALS`, the\n * subset that means a mesh dispatch attempt must be reclaimed rather than\n * retried) rather than declaring its own copy. Do not fork this vocabulary —\n * a member renamed or removed here must be re-checked against\n * `RECLAIMING_SEND_REFUSALS`'s three members (`session_exited`, `no_target`,\n * `unsupported_input`), which `satisfies readonly SendRefusal[]` there keeps\n * honest at compile time.\n */\nexport type SendRefusal =\n | 'not_ready'\n | 'send_in_flight'\n | 'not_generating'\n | 'not_supported'\n | 'platform_unsupported'\n | 'modal_parked'\n | 'interrupt_not_implemented'\n | 'interrupt_refused'\n | 'idle_timeout'\n | 'session_exited'\n | 'unsupported_input'\n | 'no_target'\n | 'bootstrap_pending'\n | 'duplicate_dispatch'\n | 'internal_error'\n\n/**\n * Which write path carried a delivered/queued message (Phase D2, additive\n * detail — callers branch on `kind`; `route` only refines the report):\n *\n * `pty` — the ordinary composer write (or the driver FIFO for `queued`);\n * `agent_queue` — the POSIX split write the CLI's OWN input queue takes while\n * a turn is generating (`send_now`). Written, not yet answered;\n * `interrupt` — the turn in flight was stopped first, then this body was\n * written (or re-parked) as a new turn;\n */\nexport type SubmitRoute = 'pty' | 'agent_queue' | 'interrupt'\n\n/** The stop key pressed by an `interrupt` submit (logs / operator display). */\nexport interface SubmitInterruptDetail {\n keyName: string\n /** 'declared' = spec-declared stop key whose busy→idle effect was never observed live. */\n confidence: 'proven' | 'declared'\n}\n\n/**\n * The one closed outcome shape every caller receives from `submit()`.\n *\n * The optional fields are additive DETAIL (Phase D2): `route`/`interrupt` say\n * how a message was written, `message` is a human-readable refusal line and\n * `restored` says whether a parked body that an out-of-band submit had claimed\n * is back in the driver queue (`false` = nothing holds it any more). None of\n * them changes what `kind` means.\n */\nexport type SubmitOutcome =\n | { kind: 'delivered'; route?: SubmitRoute; interrupt?: SubmitInterruptDetail }\n | { kind: 'queued'; position: number; route?: SubmitRoute; interrupt?: SubmitInterruptDetail }\n | { kind: 'duplicate'; of: string /* messageId */ }\n | { kind: 'refused'; reason: SendRefusal; message?: string; restored?: boolean }\n\n/**\n * The one send-side unit crossing every transport. `messageId` is minted at\n * the ORIGIN (never by the daemon) — this is what makes cross-transport\n * dedupe and identity-based claim/cancel/send-now possible.\n */\nexport interface OutboundMessage {\n messageId: string\n sessionId: string\n input: InputEnvelopeWire\n origin: OutboundMessageOrigin\n policy: SendPolicy\n createdAt: number\n /**\n * Present only for a mesh-dispatched message; lets the turn ledger\n * (Phase C) bind the send to the attempt without the sender needing to\n * know what an \"attempt\" is. Optional and inert until C lands.\n */\n meshAttemptRef?: string\n}\n\n// ─── Identity ───────────────────────────────────────────────────────────────\n\n/**\n * Mint a new `messageId`. `crypto.randomUUID` where available (browser and\n * modern Node); a counter fallback otherwise, since the only requirement is\n * uniqueness within one process/tab, not cryptographic strength.\n */\nlet outboundMessageIdCounter = 0\nexport function mintMessageId(now: number = Date.now()): string {\n try {\n // `globalThis.crypto` is not in the ES2022 lib (mesh-shared is DOM-free), so read it structurally.\n const cryptoRef = (typeof globalThis !== 'undefined'\n ? (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n : undefined)\n if (typeof cryptoRef?.randomUUID === 'function') return `msg_${cryptoRef.randomUUID()}`\n } catch {\n /* fall through to the counter fallback */\n }\n outboundMessageIdCounter += 1\n return `msg_${now}_${outboundMessageIdCounter}`\n}\n\n/** `messageId`s minted by this module always carry this prefix; used by the guard below. */\nconst MESSAGE_ID_PREFIX = 'msg_'\n\nexport function isMessageId(value: unknown): value is string {\n return typeof value === 'string' && value.length > MESSAGE_ID_PREFIX.length && value.startsWith(MESSAGE_ID_PREFIX)\n}\n\n// ─── Guards ─────────────────────────────────────────────────────────────────\n\nexport const OUTBOUND_MESSAGE_ORIGINS = ['dashboard', 'mcp', 'mesh', 'api', 'cli', 'assistant'] as const satisfies readonly OutboundMessageOrigin[]\n\nexport function isOutboundMessageOrigin(value: unknown): value is OutboundMessageOrigin {\n return typeof value === 'string' && (OUTBOUND_MESSAGE_ORIGINS as readonly string[]).includes(value)\n}\n\nexport const SEND_POLICY_MODES = ['queue', 'send_now', 'interrupt'] as const satisfies readonly SendPolicy['mode'][]\n\nexport function isSendPolicyMode(value: unknown): value is SendPolicy['mode'] {\n return typeof value === 'string' && (SEND_POLICY_MODES as readonly string[]).includes(value)\n}\n\nexport function isSendPolicy(value: unknown): value is SendPolicy {\n return !!value && typeof value === 'object' && isSendPolicyMode((value as { mode?: unknown }).mode)\n}\n\nexport const SEND_REFUSAL_REASONS = [\n 'not_ready',\n 'send_in_flight',\n 'not_generating',\n 'not_supported',\n 'platform_unsupported',\n 'modal_parked',\n 'interrupt_not_implemented',\n 'interrupt_refused',\n 'idle_timeout',\n 'session_exited',\n 'unsupported_input',\n 'no_target',\n 'bootstrap_pending',\n 'duplicate_dispatch',\n 'internal_error',\n] as const satisfies readonly SendRefusal[]\n\nexport function isSendRefusal(value: unknown): value is SendRefusal {\n return typeof value === 'string' && (SEND_REFUSAL_REASONS as readonly string[]).includes(value)\n}\n\nconst SUBMIT_OUTCOME_KINDS = ['delivered', 'queued', 'duplicate', 'refused'] as const\n\nexport function isSubmitOutcome(value: unknown): value is SubmitOutcome {\n if (!value || typeof value !== 'object') return false\n const kind = (value as { kind?: unknown }).kind\n if (typeof kind !== 'string' || !(SUBMIT_OUTCOME_KINDS as readonly string[]).includes(kind)) return false\n if (kind === 'queued') return typeof (value as { position?: unknown }).position === 'number'\n if (kind === 'duplicate') return typeof (value as { of?: unknown }).of === 'string'\n if (kind === 'refused') return isSendRefusal((value as { reason?: unknown }).reason)\n return true\n}\n\nfunction isInputPartWire(value: unknown): value is InputPartWire {\n if (!value || typeof value !== 'object') return false\n const type = (value as { type?: unknown }).type\n return type === 'text' || type === 'image' || type === 'audio' || type === 'video' || type === 'resource' || type === 'resource_link'\n}\n\nexport function isInputEnvelopeWire(value: unknown): value is InputEnvelopeWire {\n if (!value || typeof value !== 'object') return false\n const parts = (value as { parts?: unknown }).parts\n const textFallback = (value as { textFallback?: unknown }).textFallback\n return Array.isArray(parts) && parts.every(isInputPartWire) && typeof textFallback === 'string'\n}\n\n/** Minimal structural check for the wire boundary — not a full decoder (mesh-shared stays a pure leaf; semantic validation stays with the handler that owns it). */\nexport function isOutboundMessage(value: unknown): value is OutboundMessage {\n if (!value || typeof value !== 'object') return false\n const candidate = value as Partial<OutboundMessage>\n return isMessageId(candidate.messageId)\n && typeof candidate.sessionId === 'string' && candidate.sessionId.length > 0\n && isInputEnvelopeWire(candidate.input)\n && isOutboundMessageOrigin(candidate.origin)\n && isSendPolicy(candidate.policy)\n && typeof candidate.createdAt === 'number'\n}\n","/**\n * mission-brief — the goal/constraints/done-criteria/handoff a coordinator\n * attaches to a mission at `mesh_mission_upsert` time, and the deterministic\n * rendering of that brief into a dispatched task's worker-protocol footer\n * (wiring-unification Phase H2, `docs/design/2026-09-23-wiring-unification.md`\n * §7c).\n *\n * `mesh_mission_upsert` today carries only a free-text `goal` string — no\n * structured constraints, done-criteria or handoff notes, and nothing from a\n * mission ever reaches a dispatched worker's task body. This module is the\n * pure, dependency-free core: a normalized `MissionBrief` shape with length\n * caps (mirrors `report_completion.summary`'s \"prefer specifics\" discipline —\n * a brief is meant to be read by a worker mid-task, not skimmed by a human),\n * and a deterministic Markdown renderer capped at 1,200 chars so a mission\n * with many/long fields cannot blow a dispatched task's token budget.\n *\n * This module does NOT decide where the rendered block is inserted (that is\n * `worker-protocol.ts`'s `renderWorkerProtocolFooter`, which places it above\n * the marker line — see that file), and does NOT touch storage (H2's proposal\n * keeps `mesh_missions` as the row source; this is the shape callers upsert\n * into/read out of that row's `goal`/new `brief` columns).\n */\n\n/** Per-field caps. Generous enough for real content, small enough that four\n * arrays of them cannot silently balloon a rendered block past the render cap. */\nconst GOAL_MAX = 500\nconst LIST_ITEM_MAX = 200\nconst LIST_MAX_ITEMS = 12\n\n/** Total rendered-block cap (design doc H2 \"bounded payload\" discipline, mirrored from `listMeshMissionsForTool`). */\nexport const MISSION_BRIEF_RENDER_MAX_CHARS = 1200\n\nexport interface MissionBrief {\n /** What this mission is trying to accomplish. Required — an empty brief is not meaningful. */\n goal: string\n /** Hard constraints a worker must respect (e.g. \"do not touch daemon-core\", \"no npm install\"). */\n constraints?: string[]\n /** How to know the mission is actually done. */\n doneCriteria?: string[]\n /** Standing notes for whoever picks up mission work next. */\n handoffNotes?: string[]\n /** Paths this mission's tasks collectively own (H1 integration point — surfaced, not enforced here). */\n ownedPaths?: string[]\n}\n\nexport interface NormalizeMissionBriefResult {\n /** `null` when the input had no usable `goal` — callers should treat this as \"no brief\", not an empty one. */\n readonly brief: MissionBrief | null\n /** What was trimmed/dropped, for a caller that wants to warn (never thrown). */\n readonly truncated: ReadonlyArray<{ field: string; reason: 'field_too_long' | 'list_too_long' | 'item_too_long' }>\n}\n\nfunction truncateString(value: string, max: number): string {\n if (value.length <= max) return value\n return `${value.slice(0, max - 1).trimEnd()}…`\n}\n\nfunction normalizeStringList(\n value: unknown,\n field: string,\n truncated: Array<{ field: string; reason: 'field_too_long' | 'list_too_long' | 'item_too_long' }>,\n): string[] | undefined {\n if (value === undefined || value === null) return undefined\n if (!Array.isArray(value)) return undefined\n const items: string[] = []\n let itemTruncated = false\n for (const raw of value) {\n if (typeof raw !== 'string') continue\n const trimmed = raw.trim()\n if (!trimmed) continue\n if (trimmed.length > LIST_ITEM_MAX) itemTruncated = true\n items.push(truncateString(trimmed, LIST_ITEM_MAX))\n }\n if (itemTruncated) truncated.push({ field, reason: 'item_too_long' })\n if (items.length > LIST_MAX_ITEMS) {\n truncated.push({ field, reason: 'list_too_long' })\n return items.slice(0, LIST_MAX_ITEMS)\n }\n return items.length > 0 ? items : undefined\n}\n\n/**\n * Normalize a caller-supplied brief. Never throws. Returns `brief: null` when\n * there is no non-empty `goal` — the caller (e.g. `mesh_mission_upsert`'s\n * handler) decides whether that means \"reject\" or \"no brief attached\", this\n * module only normalizes shape.\n */\nexport function normalizeMissionBrief(input: unknown): NormalizeMissionBriefResult {\n const truncated: Array<{ field: string; reason: 'field_too_long' | 'list_too_long' | 'item_too_long' }> = []\n if (!input || typeof input !== 'object') {\n return { brief: null, truncated }\n }\n const raw = input as Record<string, unknown>\n\n const rawGoal = typeof raw.goal === 'string' ? raw.goal.trim() : ''\n if (!rawGoal) {\n return { brief: null, truncated }\n }\n if (rawGoal.length > GOAL_MAX) truncated.push({ field: 'goal', reason: 'field_too_long' })\n const goal = truncateString(rawGoal, GOAL_MAX)\n\n const constraints = normalizeStringList(raw.constraints, 'constraints', truncated)\n const doneCriteria = normalizeStringList(raw.doneCriteria ?? raw.done_criteria, 'doneCriteria', truncated)\n const handoffNotes = normalizeStringList(raw.handoffNotes ?? raw.handoff_notes, 'handoffNotes', truncated)\n const ownedPaths = normalizeStringList(raw.ownedPaths ?? raw.owned_paths, 'ownedPaths', truncated)\n\n const brief: MissionBrief = { goal }\n if (constraints) brief.constraints = constraints\n if (doneCriteria) brief.doneCriteria = doneCriteria\n if (handoffNotes) brief.handoffNotes = handoffNotes\n if (ownedPaths) brief.ownedPaths = ownedPaths\n\n return { brief, truncated }\n}\n\nfunction renderList(heading: string, items: readonly string[] | undefined): string[] {\n if (!items || items.length === 0) return []\n return [`${heading}:`, ...items.map(item => `- ${item}`)]\n}\n\n/**\n * Deterministic Markdown rendering of a brief, capped at\n * `MISSION_BRIEF_RENDER_MAX_CHARS`. Same field order every call (goal,\n * constraints, done criteria, owned paths, handoff notes) so a snapshot test\n * or a worker reading two renders of the same brief sees no drift. If the\n * assembled text exceeds the cap, trailing sections are dropped whole (never\n * mid-line) until it fits, and a final `(brief truncated)` marker is appended\n * — a worker should never receive a block cut off mid-sentence.\n */\nexport function renderMissionBriefBlock(brief: MissionBrief): string {\n const sections: string[] = [`Mission goal: ${brief.goal}`]\n sections.push(...renderList('Constraints', brief.constraints))\n sections.push(...renderList('Done when', brief.doneCriteria))\n sections.push(...renderList('Owned paths', brief.ownedPaths))\n sections.push(...renderList('Handoff notes', brief.handoffNotes))\n\n const full = sections.join('\\n')\n if (full.length <= MISSION_BRIEF_RENDER_MAX_CHARS) return full\n\n // Drop whole lines from the end until it fits, then append the marker\n // (itself budgeted into the cap so the final string never exceeds it).\n const marker = '\\n(brief truncated)'\n const budget = MISSION_BRIEF_RENDER_MAX_CHARS - marker.length\n const lines = full.split('\\n')\n let acc = ''\n for (const line of lines) {\n const next = acc ? `${acc}\\n${line}` : line\n if (next.length > budget) break\n acc = next\n }\n if (!acc) acc = truncateString(lines[0] ?? '', Math.max(budget, 0))\n return `${acc}${marker}`\n}\n","/**\n * worker-protocol — what a delegated worker is told, and what it may call.\n *\n * Wiring-unification Phase F1 (docs/design/2026-09-23-wiring-unification.md §7b).\n *\n * Measured 2026-09-23 on the live preview ledger: 635 worker attempts in 14\n * days, 3 `report_completion` calls. The worker MCP was delivered to every\n * provider and never used, because nothing ever told the worker it existed —\n * the dispatched task body carried no instruction and the coordinator prompt\n * did not mention the worker tools at all. The only text a worker saw about\n * its tools was the tool description.\n *\n * This module is the single source for BOTH sides of that contract:\n * - `WORKER_TOOLS` — exactly what `adhdev mcp --mode worker` advertises\n * (a parity test in mcp-server pins ListTools to this tuple);\n * - `renderWorkerProtocolFooter()` — the block appended to EVERY dispatched\n * task body, so a worker learns the protocol from the task itself;\n * - `renderCoordinatorWorkerSection()` — the matching paragraph the\n * coordinator prompt carries, so the coordinator expects structured reports\n * and stops polling for them.\n *\n * Wiring-unification Phase H2 adds an optional mission-brief block: when a\n * dispatched task belongs to a mission that carries a `MissionBrief`\n * (`./mission-brief.ts`), `renderWorkerProtocolFooter` renders it ABOVE the\n * `WORKER_PROTOCOL_FOOTER_MARKER` line. This is deliberate placement, not an\n * accident of insertion order: `hasWorkerProtocolFooter` / `stripWorkerProtocolFooter`\n * both key off the marker line alone, so a body with a brief block strips\n * identically to one without — the brief is authored content from the\n * coordinator's point of view (like the task message itself), never part of\n * the protocol contract the marker demarcates.\n */\n\nimport { renderMissionBriefBlock, type MissionBrief } from './mission-brief'\nimport { isMeshTaskDifficulty } from './brain-routing'\n\nexport const WORKER_TOOLS = [\n 'report_completion',\n 'progress_update',\n 'peer_context_pull',\n 'git_status',\n 'git_log',\n 'git_diff',\n] as const\n\nexport type WorkerTool = typeof WORKER_TOOLS[number]\n\nconst WORKER_TOOL_SET: ReadonlySet<string> = new Set(WORKER_TOOLS)\n\nexport function isWorkerTool(value: unknown): value is WorkerTool {\n return typeof value === 'string' && WORKER_TOOL_SET.has(value)\n}\n\n/** Stable marker line so a body is never footered twice and tests can find it. */\nexport const WORKER_PROTOCOL_FOOTER_MARKER = '--- adhdev worker protocol ---'\n\nexport interface WorkerProtocolFooterInput {\n taskId?: string\n taskMode?: string\n difficulty?: string\n readonly?: boolean\n /** Number of handoff notes enclosed above the footer, when any. */\n enclosedHandoffNotes?: number\n /** H2: the owning mission's brief, when this task belongs to one. Rendered above the marker line — see module doc. */\n missionBrief?: MissionBrief\n /**\n * Whether the worker MCP (the `WORKER_TOOLS` surface) was actually delivered\n * to the receiving session — the launch-time `deriveWorkerMcpDeliveryStatus`\n * outcome. `false` renders the no-tools variant: the worker is told to end\n * with a plain final summary instead of being sent hunting for tools it does\n * not hold. Absent = unknown (e.g. a remote session) — the tool variant,\n * which is what every worker launched with the default gate receives.\n */\n workerMcp?: boolean\n}\n\nexport function hasWorkerProtocolFooter(body: string): boolean {\n return typeof body === 'string' && body.includes(WORKER_PROTOCOL_FOOTER_MARKER)\n}\n\n/**\n * The protocol block appended to a dispatched task. Written for the model that\n * receives it: imperative, short, and explicit about what is NOT available so\n * the worker does not go looking for coordinator tools.\n */\nexport function renderWorkerProtocolFooter(input: WorkerProtocolFooterInput = {}): string {\n const briefBlock = input.missionBrief ? renderMissionBriefBlock(input.missionBrief) : null\n const lines: string[] = briefBlock ? [briefBlock, '', WORKER_PROTOCOL_FOOTER_MARKER] : [WORKER_PROTOCOL_FOOTER_MARKER]\n const scope: string[] = []\n if (input.taskId) scope.push(`task ${input.taskId}`)\n if (input.taskMode) scope.push(`mode ${input.taskMode}`)\n // MCP-usage-audit item 2: validate against the canonical difficulty set\n // (this package's own brain-routing vocabulary — never duplicated here)\n // rather than rendering an internal caller's typo or stale value verbatim.\n // The MCP tool-schema enum already blocks a bad value AT THE TOOLS; this\n // covers internal callers that can still construct a task with one.\n if (input.difficulty) {\n if (isMeshTaskDifficulty(input.difficulty)) {\n scope.push(`difficulty ${input.difficulty}`)\n } else {\n // eslint-disable-next-line no-console -- mesh-shared is a dependency-free\n // leaf with no logger abstraction; this is the one place that matters.\n console.warn(\n `[worker-protocol] task ${input.taskId ?? '(unknown)'}: dropping invalid difficulty '${input.difficulty}' `\n + `from the worker footer (expected one of easy, medium, difficult, freeform)`,\n )\n }\n }\n if (input.readonly) scope.push('read-only')\n if (scope.length) lines.push(`You are a delegated worker (${scope.join(', ')}).`)\n else lines.push('You are a delegated worker.')\n if (input.workerMcp === false) {\n lines.push(\n 'This session has NO adhdev worker tools (`report_completion`, `progress_update`, `peer_context_pull`, '\n + '`git_*`) — do not look for them. When your work is finished, blocked, or has failed, end your turn '\n + 'with a plain final summary: what you did, what you found, which files you changed, and where you '\n + 'left the branch. That final message is what the coordinator receives.',\n 'You have no coordinator tools (no `mesh_*`) by design: do not enqueue, dispatch, or restart anything. '\n + 'If you need a decision from the coordinator, say so plainly in your final summary — what is blocked '\n + 'and what you need — and stop.',\n )\n if (input.enclosedHandoffNotes && input.enclosedHandoffNotes > 0) {\n lines.push(\n `The ${input.enclosedHandoffNotes} handoff note(s) above were written by agents who touched this code before you; `\n + 'honour their conflict guidance and mention anything the next agent should know in your final summary.',\n )\n }\n return lines.join('\\n')\n }\n lines.push(\n 'When your work is finished, blocked, or has failed, call `report_completion` exactly once. '\n + 'Its `summary` is recorded verbatim as the authoritative record of this task — your terminal is not '\n + 'scraped for it — so state what you did, what you found, and where you left the branch.',\n 'For work that runs longer than a few minutes, call `progress_update` at natural checkpoints so the '\n + 'coordinator can see you are alive without polling.',\n '`peer_context_pull` shows what sibling tasks in this mission have reported; `git_status` / `git_diff` / '\n + '`git_log` inspect your own workspace — all three REQUIRE the absolute path to it as `workspace`.',\n 'Memos from the coordinator arrive appended to the response of whichever worker tool you call next; '\n + 'read them and follow them.',\n 'You have no coordinator tools (no `mesh_*`) by design: do not enqueue, dispatch, or restart anything. '\n + 'If you need a decision from the coordinator, finish with `report_completion` and outcome `blocked`, '\n + 'listing what you need in `blockers`.',\n 'On a code-changing task, `report_completion` with outcome `completed` requires `touched_files` — send '\n + '`[]` if you changed nothing, omitting the field is what gets refused. `blocked`/`failed` never need it, '\n + 'and a read-only task should omit it or send `[]`.',\n 'If `report_completion` is refused, the response carries `validationErrors` (or a `hint`) naming exactly '\n + 'what to fix — correct that field and call it again; a refusal records nothing.',\n )\n if (input.enclosedHandoffNotes && input.enclosedHandoffNotes > 0) {\n lines.push(\n `The ${input.enclosedHandoffNotes} handoff note(s) above were written by agents who touched this code before you; `\n + 'honour their conflict guidance and add your own in `handoff_notes` when you report.',\n )\n }\n return lines.join('\\n')\n}\n\n/**\n * The authored text of a dispatched body: everything before the footer marker.\n * Ledger descriptors, replay fixtures and tests compare authored text, never\n * the protocol block.\n */\nexport function stripWorkerProtocolFooter(body: string): string {\n if (typeof body !== 'string') return body\n const at = body.indexOf(WORKER_PROTOCOL_FOOTER_MARKER)\n if (at < 0) return body\n return body.slice(0, at).replace(/\\s+$/, '')\n}\n\n/**\n * Append the footer to a body that does not carry one yet. Idempotent.\n */\nexport function appendWorkerProtocolFooter(body: string, input: WorkerProtocolFooterInput = {}): string {\n if (hasWorkerProtocolFooter(body)) return body\n const trimmed = body.replace(/\\s+$/, '')\n return `${trimmed}\\n\\n${renderWorkerProtocolFooter(input)}`\n}\n\n/**\n * The paragraph the COORDINATOR prompt carries about its workers. Kept next to\n * the footer so the two halves of the protocol cannot drift apart.\n */\nexport function renderCoordinatorWorkerSection(): string {\n return [\n '## Workers',\n '',\n `Every task you dispatch is delivered with a worker protocol footer. Workers hold exactly these tools: ${WORKER_TOOLS.map((tool) => `\\`${tool}\\``).join(', ')} — and no \\`mesh_*\\` tools.`,\n '- A worker finishes by calling `report_completion`; its structured report (outcome, summary, touched files, branch state, handoff notes) is what reaches you as the completion event. Read that report — do not re-derive the outcome from `mesh_read_chat` or the terminal unless the report is missing.',\n '- `progress_update` from a worker arrives as a lightweight progress note. Do NOT poll `mesh_status`, `mesh_view_queue` or `mesh_read_chat` to check on a running worker; completion, progress, blocked and failure all arrive as events.',\n '- To reach a busy worker mid-task use `mesh_notify_worker`: the memo is delivered on the worker\\'s next tool call (or when it becomes idle). A worker that reports `blocked` is asking you for a decision — answer it with `mesh_send_task` to the same session.',\n '- `mesh_status` is for node health and capacity before delegating, never for progress.',\n '- A `code_change` task\\'s declared `owned_paths` (H1) is enforced at claim time: a second `code_change` task whose `owned_paths` overlaps an already-claimed task\\'s is refused rather than silently racing it. A worker\\'s `report_completion.touched_files` is compared against its own task\\'s declaration afterward and any mismatch is surfaced back to you as evidence — it is never a validation failure, since a worker often cannot know its exact final file list at enqueue time.',\n ].join('\\n')\n}\n","/**\n * assistant-protocol — the assistant layer's tool and daemon-verb names\n * (docs/design/2026-10-07-assistant-layer.md §4.4).\n *\n * The single source for both halves of the assistant contract, like\n * `WORKER_TOOLS` is for workers:\n * - `ASSISTANT_TOOLS` — exactly what `adhdev mcp --assistant` will advertise\n * (an mcp-server parity test pins ListTools to this tuple once that mode\n * lands);\n * - `ASSISTANT_TOOL_VERBS` — the daemon command each tool calls;\n * - the daemon-only verbs (launch / MCP-only pull / owner actions) that have\n * no tool.\n *\n * Assistant tools are a separate set from the mesh tools: none of these names\n * belongs in `CANONICAL_MESH_TOOL_NAMES`, and the coordinator/worker MCP modes\n * never publish them.\n */\n\nexport const ASSISTANT_TOOLS = [\n 'projects',\n 'project_status',\n 'project_send',\n 'project_read',\n 'project_add',\n 'discover_repos',\n 'memory',\n 'skill_view',\n 'skill_manage',\n 'project_note',\n] as const\n\nexport type AssistantTool = typeof ASSISTANT_TOOLS[number]\n\nconst ASSISTANT_TOOL_SET: ReadonlySet<string> = new Set(ASSISTANT_TOOLS)\n\nexport function isAssistantTool(value: unknown): value is AssistantTool {\n return typeof value === 'string' && ASSISTANT_TOOL_SET.has(value)\n}\n\n/** Daemon verb names (§4.4 table + the five verbs below it). */\nexport const ASSISTANT_VERB = {\n // tool verbs\n projects: 'assistant_projects',\n projectStatus: 'assistant_project_status',\n projectSend: 'assistant_project_send',\n projectRead: 'assistant_project_read',\n projectAdd: 'assistant_project_add',\n discoverRepos: 'assistant_discover_repos',\n memory: 'assistant_memory',\n skillView: 'assistant_skill_view',\n skillManage: 'assistant_skill_manage',\n projectNote: 'assistant_project_note',\n // assistant-side daemon verbs without a tool of the same name\n launch: 'launch_assistant',\n pendingRelays: 'assistant_pending_relays',\n // owner verbs (dashboard only)\n stagedResolve: 'assistant_staged_resolve',\n storeAdmin: 'assistant_store_admin',\n importSkills: 'assistant_import_skills',\n} as const\n\nexport type AssistantVerb = typeof ASSISTANT_VERB[keyof typeof ASSISTANT_VERB]\n\n/** The daemon verb each assistant tool calls. */\nexport const ASSISTANT_TOOL_VERBS: Readonly<Record<AssistantTool, AssistantVerb>> = {\n projects: ASSISTANT_VERB.projects,\n project_status: ASSISTANT_VERB.projectStatus,\n project_send: ASSISTANT_VERB.projectSend,\n project_read: ASSISTANT_VERB.projectRead,\n project_add: ASSISTANT_VERB.projectAdd,\n discover_repos: ASSISTANT_VERB.discoverRepos,\n memory: ASSISTANT_VERB.memory,\n skill_view: ASSISTANT_VERB.skillView,\n skill_manage: ASSISTANT_VERB.skillManage,\n project_note: ASSISTANT_VERB.projectNote,\n}\n\n/**\n * Tools annotated as writes; every other assistant tool is read-only. §4.4\n * lists the three store writes; project_send and project_add are here too\n * because they cause effects (a coordinator message or launch, a new\n * project), and MCP clients use readOnlyHint to skip confirmation.\n */\nexport const ASSISTANT_WRITE_TOOLS: readonly AssistantTool[] = ['memory', 'skill_manage', 'project_note', 'project_send', 'project_add']\n\n/** Owner-only verbs: never reachable from the assistant's MCP server (no `ipc`). */\nexport const ASSISTANT_OWNER_VERBS: readonly AssistantVerb[] = [\n ASSISTANT_VERB.stagedResolve,\n ASSISTANT_VERB.storeAdmin,\n ASSISTANT_VERB.importSkills,\n]\n\n/** The only assistant verbs accepted while an idle review turn is open (§4.10.7). */\nexport const ASSISTANT_REVIEW_TURN_VERBS: readonly AssistantVerb[] = [\n ASSISTANT_VERB.memory,\n ASSISTANT_VERB.skillView,\n ASSISTANT_VERB.skillManage,\n ASSISTANT_VERB.projectNote,\n]\n\n/**\n * Env var the daemon sets on the assistant CLI's process (§4.5), read by the\n * assistant MCP server and forwarded on every verb as\n * `ASSISTANT_SESSION_ID_ARG`. Routing / ownership only — never an auth gate.\n */\nexport const ASSISTANT_SESSION_ID_ENV = 'ADHDEV_ASSISTANT_SESSION_ID'\n\n/** Request arg carrying the calling assistant session id. */\nexport const ASSISTANT_SESSION_ID_ARG = 'assistantSessionId'\n","/**\n * turn-evidence — the ONE vocabulary for \"what happened to a turn\".\n *\n * Wiring-unification Phase C1 (docs/design/2026-09-23-wiring-unification.md §5).\n *\n * Every producer that today decides \"done\" on its own (completion flush, stall\n * rescue, reconcile synthesis, MCP probes, worker report tools, …) instead\n * submits one of these evidence records to the turn ledger, whose pure reducer\n * is the only authority for a turn's state. Worker daemons and the MCP server\n * build them, so the types live here (a dependency-free leaf).\n *\n * CONTENT-FREE BY CONSTRUCTION\n * ----------------------------\n * Evidence crosses machines (seqscribe `mesh.<id>.events` replication) and must\n * never carry anything a user or an agent wrote. Every field is one of: an\n * identifier, a closed enum, a boolean, a number, or a `SummaryRef` — a pointer\n * `{topic, writer, seq}` to a content-class topic entry (`mesh.<id>.handoff`)\n * where the text actually lives. `TURN_EVIDENCE_FIELD_SPECS` declares the class\n * of every field of every member (the compiler forces it to stay total and\n * exact), the runtime guard validates against it, and a test walks it to prove\n * no free-text field exists.\n */\n\nimport { WORKER_BRANCH_STATES, WORKER_REPORT_OUTCOMES, type WorkerBranchState, type WorkerReportOutcome } from './mesh-vocabulary'\nimport { SESSION_STATUSES, type SessionStatus } from './session-status'\nimport { SEND_REFUSAL_REASONS, type SendRefusal } from './outbound-message'\n\n// ─── closed vocabularies ─────────────────────────────────────────────────\n\n/** Protocol version stamped on every `mesh.<id>.events` entry written by the turn ledger. */\nexport const MESH_TOPIC_PROTOCOL_VERSION = 2 as const\n\nexport const EVIDENCE_SOURCE_IDS = [\n 'fsm_edge', 'short_gen_inline', 'completion_flush_genuine', 'completion_flush_weak',\n 'monitor_final_summary', 'pre_cleanup_transcript', 'stall_transcript', 'startup_grace_collapse',\n 'acp_prompt_response', 'cdp_state', 'approval_gate', 'modal_button',\n 'mesh_stall_watchdog', 'status_monitor', 'pty_exit', 'provider_error',\n 'coordinator_probe', 'mcp_probe', 'worker_tool', 'dispatch', 'input_service',\n 'operator', 'intentional_cleanup', 'scheduler', 'git_probe', 'session_registry',\n] as const\nexport type EvidenceSourceId = typeof EVIDENCE_SOURCE_IDS[number]\n\nexport const TURN_SCOPES = ['mesh_queue', 'mesh_direct', 'plain'] as const\nexport type TurnScope = typeof TURN_SCOPES[number]\n\n/**\n * Refusals (D1 `SendRefusal`, owned by ./outbound-message) that mean the target\n * can never take this dispatch, so the attempt is reclaimed (R3). Every other\n * refusal is retried by the sender and only recorded.\n */\nexport const RECLAIMING_SEND_REFUSALS = ['session_exited', 'no_target', 'unsupported_input'] as const satisfies readonly SendRefusal[]\nexport type ReclaimingSendRefusal = typeof RECLAIMING_SEND_REFUSALS[number]\n\nexport const DELIVERY_OUTCOMES = ['delivered', 'queued'] as const\nexport type DeliveryOutcome = typeof DELIVERY_OUTCOMES[number]\nexport const DELIVERY_VIAS = ['local', 'p2p'] as const\nexport type DeliveryVia = typeof DELIVERY_VIAS[number]\n\nexport const DISPATCH_FAILURE_REASONS = ['worker_absent', 'transport_error', 'spawn_failed', 'rejected_by_worker', 'timeout'] as const\nexport type DispatchFailureReason = typeof DISPATCH_FAILURE_REASONS[number]\n\n/**\n * Normalize a worker's own refusal code (e.g. `session_busy_with_task`,\n * `mesh_sender_not_on_roster`, `provider_quota_exhausted`) into the shape\n * `dispatch_failed.refusalCode` accepts: lowercase ascii + underscore, capped\n * at 64 chars. Returns undefined for anything that yields no usable token, so\n * a malformed/foreign code degrades to \"no refusalCode\" rather than smuggling\n * arbitrary text through what must stay a closed-enum-like identifier slot\n * (see the field's doc comment — this evidence replicates cross-machine).\n */\nexport function sanitizeRefusalCode(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined\n const normalized = value.trim().toLowerCase().replace(/[^a-z_]/g, '_').replace(/_+/g, '_').replace(/^_+|_+$/g, '')\n if (!normalized) return undefined\n return normalized.slice(0, 64)\n}\n\nexport const CONSUME_PROFILES = ['default', 'native_source'] as const\nexport type ConsumeProfile = typeof CONSUME_PROFILES[number]\n\nexport const SESSION_REBOUND_REASONS = ['restart', 'live_holder'] as const\nexport type SessionReboundReason = typeof SESSION_REBOUND_REASONS[number]\n\nexport const SUSPENSION_MODALS = ['approval', 'choice'] as const\nexport type SuspensionModal = typeof SUSPENSION_MODALS[number]\nexport const SUSPENSION_RESOLUTIONS = ['approved', 'rejected', 'answered'] as const\nexport type SuspensionResolution = typeof SUSPENSION_RESOLUTIONS[number]\nexport const SUSPENSION_RESOLUTION_VIAS = ['modal_button', 'auto_approve', 'prompt_answer'] as const\nexport type SuspensionResolutionVia = typeof SUSPENSION_RESOLUTION_VIAS[number]\n\nexport const TURN_END_STRENGTHS = ['genuine', 'weak'] as const\nexport type TurnEndStrength = typeof TURN_END_STRENGTHS[number]\n\n/** Why a provider-side weak end was released (was free text `blockReason`). */\nexport const TURN_END_BLOCK_REASONS = [\n 'missing_final_assistant', 'finalization_timeout', 'terminal_block_hard_cap', 'decoupled_completion',\n] as const\nexport type TurnEndBlockReason = typeof TURN_END_BLOCK_REASONS[number]\n\nexport const NATIVE_TURN_OUTCOMES = ['completed', 'aborted'] as const\nexport type NativeTurnOutcome = typeof NATIVE_TURN_OUTCOMES[number]\n\nexport const LIVENESS_RESULTS = ['alive', 'unknown', 'read_failed', 'dead'] as const\nexport type LivenessResult = typeof LIVENESS_RESULTS[number]\n\nexport const PROVIDER_FAILURES = ['auth_failed', 'billing_failed'] as const\nexport type ProviderFailure = typeof PROVIDER_FAILURES[number]\n\n/**\n * `daemon_restart` (wiring-unification follow-up, design §5): boot-time\n * reconciliation observes this for a plain attempt that was open when the\n * daemon restarted — either its session is gone, or the session was restored\n * live but the turn in flight was cut by the restart. The daemon never saw\n * the session's own exit or commit, so it is not `provider_error` /\n * `adapter_error` / etc.; it is the daemon itself closing a turn it can no\n * longer follow.\n */\nexport const SESSION_ERROR_REASONS = ['provider_error', 'adapter_error', 'spawn_failed', 'auth_failed', 'billing_failed', 'unknown', 'daemon_restart'] as const\nexport type SessionErrorReason = typeof SESSION_ERROR_REASONS[number]\n\nexport const CANCEL_REASONS = ['operator_cancel', 'intentional_cleanup', 'task_removed', 'mission_abandoned', 'superseded'] as const\nexport type CancelReason = typeof CANCEL_REASONS[number]\n\nexport const OPERATOR_STATUSES = ['completed', 'failed'] as const\nexport type OperatorStatus = typeof OPERATOR_STATUSES[number]\nexport const OPERATOR_STATUS_REASONS = ['operator_update', 'refine_terminal', 'validation_terminal'] as const\nexport type OperatorStatusReason = typeof OPERATOR_STATUS_REASONS[number]\n\nexport const COORDINATOR_ACK_OUTCOMES = ['delivered', 'queued', 'duplicate'] as const\nexport type CoordinatorAckOutcome = typeof COORDINATOR_ACK_OUTCOMES[number]\n\n/** Observed status as a no-progress monitor saw it (canonical session status or `unknown`). */\nexport const NO_PROGRESS_OBSERVED_STATUSES = [...SESSION_STATUSES, 'unknown'] as const\nexport type NoProgressObservedStatus = SessionStatus | 'unknown'\n\n/**\n * Reasons a turn hold exists. Holds are attempt-scoped only (C2: delivery-side\n * waits are consumer deferral on the `turn.deliver` cursor, not hold rows).\n */\nexport const HOLD_REASONS = [\n 'await_delivery', 'await_consume', 'await_turn', 'liveness', 'hard_ceiling',\n 'live_pending', 'transcript_quiet', 'weak_candidate', 'suspension_before_consumed',\n // A genuine FSM end of a mesh turn whose worker holds a live worker-MCP bind:\n // the structured report is the primary evidence (design §F2), so the idle edge\n // only opens this hold (R9r) — a report commits (R17), a new busy edge cancels\n // it as a false idle (R12r), expiry commits weak (R13r).\n 'await_report',\n // A worker report recorded while the session is still generating (R17g):\n // the report is the verdict, the idle edge is only awaited as corroboration\n // — a turn_end commits the report (R9t), expiry commits it anyway (R13t) so\n // a session whose FSM never shows the idle edge again does not wait for\n // liveness / hard_ceiling.\n 'await_end',\n] as const\nexport type HoldReason = typeof HOLD_REASONS[number]\n\nexport const TURN_OUTCOMES = ['completed', 'failed', 'cancelled'] as const\nexport type TurnOutcome = typeof TURN_OUTCOMES[number]\n\nexport const COMMIT_STRENGTHS = ['genuine', 'weak', 'tool_report', 'operator'] as const\nexport type CommitStrength = typeof COMMIT_STRENGTHS[number]\n\n/** Every terminal or reclaim reason the ledger writes. Closed: no free-text reasons. */\nexport const TURN_REASONS = [\n // commits\n 'turn_end', 'weak_end_confirmed', 'transcript_final', 'worker_reported',\n 'finalization_timeout_no_response', 'session_error', 'provider_auth_failed', 'provider_billing_failed',\n 'operator_cancel', 'intentional_cleanup', 'task_removed', 'mission_abandoned', 'superseded',\n 'operator_update', 'refine_terminal', 'validation_terminal',\n 'hard_ceiling', 'reclaim_budget_exhausted', 'hollow_max_retries', 'migration_orphan',\n // reclaims (generation + 1)\n 'dispatch_refused_session_exited', 'dispatch_refused_no_target', 'dispatch_refused_unsupported_input', 'dispatch_failed',\n 'session_exit', 'session_exit_before_turn', 'session_dead', 'hollow_completion',\n 'assigned_stranded_dispatch_unconfirmed', 'delivered_not_consumed_redrive', 'delivered_no_turn_deadline',\n] as const\nexport type TurnReason = typeof TURN_REASONS[number]\n\n/**\n * What a `turn.notify` entry tells a coordinator.\n *\n * `late_completion` (C1 R27, owner revision 2026-09-23): a superseded\n * generation finished while the current one was already running; the\n * coordinator decides whether to salvage it (the entry carries the g−1\n * summary as its append `ref`). `mesh_event`: a non-turn coordinator notice\n * (refine terminal, worktree bootstrap, …) whose text lives only in the\n * owner's local `turn_events.payload_json` and is rendered at deliver time.\n */\nexport const NOTIFY_KINDS = [\n 'completed', 'failed', 'cancelled', 'stopped', 'approval', 'choice', 'approval_resolved',\n 'candidate', 'no_progress', 'progress', 'late_completion', 'mesh_event',\n] as const\nexport type NotifyKind = typeof NOTIFY_KINDS[number]\n\n// ─── shared shapes ───────────────────────────────────────────────────────\n\nexport interface TurnAttemptRef { attemptId: string; generation: number }\n\n/**\n * Pointer to text that lives in a content-class topic entry (`mesh.<id>.handoff`).\n * Text never travels inside evidence; the deliver side renders it from the ref.\n */\nexport interface SummaryRef { topic: string; writer: string; seq: number }\n\n/** Live-state observations that make a transcript end premature (admission input). */\nexport interface LiveTurnPending { modal: boolean; adapterPending: boolean; trailingTool: boolean; newestActivityAt?: number }\n\n/** Structural copy of daemon-core's `CoordinatorIdentity` (this package cannot import daemon-core). */\nexport interface EvidenceCoordinatorIdentity { daemonId: string; coordinatorRunId: string; sessionId?: string }\n\nexport interface NativeTurnMarkerRef { outcome: NativeTurnOutcome; turnId?: string }\n\nexport interface EvidenceEnvelope {\n /** Stable id of this observation; dedupe key across republish/replication. */\n eventId: string\n /** Producer clock, epoch ms. */\n at: number\n source: EvidenceSourceId\n /** The session that produced / is the subject of the observation. */\n sessionId: string\n attemptRef?: TurnAttemptRef\n /** Only when attemptRef is absent (legacy relay / MCP probe). */\n taskId?: string\n /** Daemon id that observed it. */\n observedBy: string\n}\n\n/** Kind-specific bodies. `TurnEvidence = EvidenceEnvelope & TurnEvidenceBody`. */\nexport type TurnEvidenceBody =\n // ── dispatch / delivery ──\n | { kind: 'dispatch_accepted'; scope: TurnScope; messageId: string; meshId?: string; nodeId?: string; providerType?: string\n attemptNo?: number; dispatchNonce?: number; consumeProfile?: ConsumeProfile; maxTaskRetries?: number\n coordinator?: EvidenceCoordinatorIdentity }\n | { kind: 'delivered'; messageId: string; outcome: DeliveryOutcome; via: DeliveryVia }\n | { kind: 'delivery_refused'; messageId: string; reason: SendRefusal }\n /**\n * `refusalCode` (wiring-unification live-gap fix, 2026-09-25): the worker's own\n * refusal code for an application-level `{success:false}` answer (e.g.\n * `session_busy_with_task`, `mesh_sender_not_on_roster`,\n * `mesh_node_bootstrap_pending`, `provider_quota_exhausted`) — optional and\n * ONLY ever populated for `reason: 'rejected_by_worker'`. Deliberately an `id`\n * (short enum-like token), never free text: this evidence replicates across\n * machines over `mesh.<id>.events` (CONTENT-FREE BY CONSTRUCTION above), so a\n * human-readable detail string must NOT travel here — it stays local (owner\n * WARN log, MCP tool JSON response). Producers sanitize to `[a-z_]{1,64}`\n * before emitting so a stray free-text code can never smuggle prose through\n * this slot.\n */\n | { kind: 'dispatch_failed'; workerAbsent: boolean; reason: DispatchFailureReason; refusalCode?: string }\n | { kind: 'duplicate_dispatch_refusal'; holderSessionId: string; holderAttemptId?: string }\n | { kind: 'session_rebound'; toSessionId: string; reason: SessionReboundReason }\n // ── worker turn lifecycle ──\n | { kind: 'turn_started'; retro: boolean }\n | { kind: 'suspension'; modal: SuspensionModal; modalKey?: string }\n | { kind: 'suspension_resolved'; resolution: SuspensionResolution; via: SuspensionResolutionVia }\n | { kind: 'turn_end'; strength: TurnEndStrength; afterFinalizationTimeout?: boolean; hollow?: boolean; summary?: SummaryRef\n blockReason?: TurnEndBlockReason; releasedByHardCap?: boolean; nativeOutcome?: NativeTurnOutcome; live?: LiveTurnPending\n /**\n * Stamped (true only) by the WORKER's daemon when the session holds a live\n * worker-MCP session bind, i.e. the worker can call report_completion. The\n * owner then treats a genuine end as a report-awaiting candidate (R9r), not\n * a commit. Absent = no reporting surface = today's genuine-end commit.\n */\n reportExpected?: boolean\n /**\n * Stamped by the WORKER's daemon when the turn's whole reply is a provider\n * auth/billing failure banner (claude-cli \"Login expired · Please run\n * /login\", 2026-10-06 preview incident). The owner commits the attempt\n * `failed / provider_auth_failed` (R9f) instead of reading the idle edge\n * as a completion. Closed enum — the banner text itself never travels.\n */\n providerFailure?: ProviderFailure }\n | { kind: 'transcript_final'; selfAttributing: boolean; nativeRead: boolean; nativeMarker?: NativeTurnMarkerRef\n live: LiveTurnPending; summary?: SummaryRef; messageAt?: number }\n | { kind: 'transcript_activity'; newestActivityAt: number }\n | { kind: 'no_progress'; stalledMs: number; observedStatus: NoProgressObservedStatus; finalAssistantPresent: boolean }\n | { kind: 'liveness'; result: LivenessResult }\n | { kind: 'process_exit'; exitCode: number | null; providerFailure?: ProviderFailure }\n | { kind: 'session_error'; reason: SessionErrorReason }\n // ── worker MCP (F2) ──\n /**\n * `summary` is the handoff-topic pointer when the report's text was published;\n * a report the owner daemon accepted itself carries its text in the evidence\n * row's local envelope instead (never published), so the pointer is optional.\n */\n | { kind: 'worker_report'; outcome: WorkerReportOutcome; summary?: SummaryRef; hasHandoffNotes: boolean\n branchState?: WorkerBranchState; touchedFileCount?: number }\n | { kind: 'worker_progress'; note?: SummaryRef }\n // ── coordinator / operator ──\n | { kind: 'git_side_effect'; dirty: boolean; commitsSinceDispatch: number; attributable: boolean }\n | { kind: 'cancel'; reason: CancelReason }\n | { kind: 'operator_status'; status: OperatorStatus; reason: OperatorStatusReason }\n | { kind: 'coordinator_ack'; notify: NotifyKind; outcome: CoordinatorAckOutcome }\n // ── scheduler-generated ──\n | { kind: 'hold_expired'; holdId: string; reason: HoldReason }\n\nexport type TurnEvidence = EvidenceEnvelope & TurnEvidenceBody\nexport type TurnEvidenceKind = TurnEvidenceBody['kind']\nexport type TurnEvidenceOf<K extends TurnEvidenceKind> = EvidenceEnvelope & Extract<TurnEvidenceBody, { kind: K }>\n\n// ─── field-class registry (drives the guard and the content-free test) ────\n\n/**\n * The class of every declared field. There is deliberately NO free-text class:\n * `id` strings are length-bounded and whitespace-free, so prose cannot be\n * smuggled through an identifier slot either.\n */\nexport type EvidenceFieldSpec =\n | { t: 'id'; optional?: true }\n | { t: 'enum'; values: readonly string[]; optional?: true }\n | { t: 'bool'; optional?: true }\n | { t: 'int'; optional?: true; nullable?: true }\n | { t: 'ms'; optional?: true }\n | { t: 'summary_ref'; optional?: true }\n | { t: 'attempt_ref'; optional?: true }\n | { t: 'live'; optional?: true }\n | { t: 'native_marker'; optional?: true }\n | { t: 'coordinator'; optional?: true }\n\ntype FieldsOf<K extends TurnEvidenceKind> = Exclude<keyof Extract<TurnEvidenceBody, { kind: K }>, 'kind'>\n/** Exact per-kind registry: a missing or extra field fails to compile. */\nexport type TurnEvidenceFieldSpecs = { readonly [K in TurnEvidenceKind]: { readonly [F in FieldsOf<K>]-?: EvidenceFieldSpec } }\n\nconst id = { t: 'id' } as const\nconst idOpt = { t: 'id', optional: true } as const\nconst bool = { t: 'bool' } as const\nconst boolOpt = { t: 'bool', optional: true } as const\nconst ms = { t: 'ms' } as const\nconst msOpt = { t: 'ms', optional: true } as const\nconst intOpt = { t: 'int', optional: true } as const\nconst en = (values: readonly string[]) => ({ t: 'enum', values }) as const\nconst enOpt = (values: readonly string[]) => ({ t: 'enum', values, optional: true }) as const\n\nexport const EVIDENCE_ENVELOPE_FIELD_SPECS: { readonly [F in keyof EvidenceEnvelope]-?: EvidenceFieldSpec } = {\n eventId: id,\n at: ms,\n source: en(EVIDENCE_SOURCE_IDS),\n sessionId: id,\n attemptRef: { t: 'attempt_ref', optional: true },\n taskId: idOpt,\n observedBy: id,\n}\n\nexport const TURN_EVIDENCE_FIELD_SPECS: TurnEvidenceFieldSpecs = {\n dispatch_accepted: {\n scope: en(TURN_SCOPES), messageId: id, meshId: idOpt, nodeId: idOpt, providerType: idOpt,\n attemptNo: intOpt, dispatchNonce: intOpt, consumeProfile: enOpt(CONSUME_PROFILES), maxTaskRetries: intOpt,\n coordinator: { t: 'coordinator', optional: true },\n },\n delivered: { messageId: id, outcome: en(DELIVERY_OUTCOMES), via: en(DELIVERY_VIAS) },\n delivery_refused: { messageId: id, reason: en(SEND_REFUSAL_REASONS) },\n dispatch_failed: { workerAbsent: bool, reason: en(DISPATCH_FAILURE_REASONS), refusalCode: idOpt },\n duplicate_dispatch_refusal: { holderSessionId: id, holderAttemptId: idOpt },\n session_rebound: { toSessionId: id, reason: en(SESSION_REBOUND_REASONS) },\n turn_started: { retro: bool },\n suspension: { modal: en(SUSPENSION_MODALS), modalKey: idOpt },\n suspension_resolved: { resolution: en(SUSPENSION_RESOLUTIONS), via: en(SUSPENSION_RESOLUTION_VIAS) },\n turn_end: {\n strength: en(TURN_END_STRENGTHS), afterFinalizationTimeout: boolOpt, hollow: boolOpt,\n summary: { t: 'summary_ref', optional: true }, blockReason: enOpt(TURN_END_BLOCK_REASONS),\n releasedByHardCap: boolOpt, nativeOutcome: enOpt(NATIVE_TURN_OUTCOMES), live: { t: 'live', optional: true },\n reportExpected: boolOpt, providerFailure: enOpt(PROVIDER_FAILURES),\n },\n transcript_final: {\n selfAttributing: bool, nativeRead: bool, nativeMarker: { t: 'native_marker', optional: true },\n live: { t: 'live' }, summary: { t: 'summary_ref', optional: true }, messageAt: msOpt,\n },\n transcript_activity: { newestActivityAt: ms },\n no_progress: { stalledMs: ms, observedStatus: en(NO_PROGRESS_OBSERVED_STATUSES), finalAssistantPresent: bool },\n liveness: { result: en(LIVENESS_RESULTS) },\n process_exit: { exitCode: { t: 'int', nullable: true }, providerFailure: enOpt(PROVIDER_FAILURES) },\n session_error: { reason: en(SESSION_ERROR_REASONS) },\n worker_report: {\n outcome: en(WORKER_REPORT_OUTCOMES), summary: { t: 'summary_ref', optional: true }, hasHandoffNotes: bool,\n branchState: enOpt(WORKER_BRANCH_STATES), touchedFileCount: intOpt,\n },\n worker_progress: { note: { t: 'summary_ref', optional: true } },\n git_side_effect: { dirty: bool, commitsSinceDispatch: { t: 'int' }, attributable: bool },\n cancel: { reason: en(CANCEL_REASONS) },\n operator_status: { status: en(OPERATOR_STATUSES), reason: en(OPERATOR_STATUS_REASONS) },\n coordinator_ack: { notify: en(NOTIFY_KINDS), outcome: en(COORDINATOR_ACK_OUTCOMES) },\n hold_expired: { holdId: id, reason: en(HOLD_REASONS) },\n}\n\nexport const TURN_EVIDENCE_KINDS = Object.keys(TURN_EVIDENCE_FIELD_SPECS) as readonly TurnEvidenceKind[]\n\n/** Evidence kinds that, on their own, can end a turn (the ones R18/R19/R27 reason about). */\nexport const TERMINAL_CLASS_EVIDENCE_KINDS = [\n 'turn_end', 'transcript_final', 'no_progress', 'worker_report', 'session_error', 'process_exit', 'cancel', 'operator_status',\n] as const satisfies readonly TurnEvidenceKind[]\n\n// ─── guards ──────────────────────────────────────────────────────────────\n\n/** Identifier shape: 1..256 chars, no whitespace or control characters. */\nconst IDENTIFIER_RE = /^[^\\s\\u0000-\\u001f\\u007f]{1,256}$/\n\nfunction makeGuard<T extends readonly string[]>(values: T): (value: unknown) => value is T[number] {\n const set: ReadonlySet<string> = new Set(values)\n return (value: unknown): value is T[number] => typeof value === 'string' && set.has(value)\n}\n\nexport const isTurnEvidenceKind = makeGuard(TURN_EVIDENCE_KINDS as readonly TurnEvidenceKind[])\nexport const isTurnReason = makeGuard(TURN_REASONS)\nexport const isNotifyKind = makeGuard(NOTIFY_KINDS)\nexport const isTurnOutcome = makeGuard(TURN_OUTCOMES)\nexport const isCommitStrength = makeGuard(COMMIT_STRENGTHS)\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport function isEvidenceIdentifier(value: unknown): value is string {\n return typeof value === 'string' && IDENTIFIER_RE.test(value)\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n\nexport function isSummaryRef(value: unknown): value is SummaryRef {\n return isRecord(value)\n && hasOnlyKeys(value, ['topic', 'writer', 'seq'])\n && isEvidenceIdentifier(value.topic)\n && isEvidenceIdentifier(value.writer)\n && Number.isSafeInteger(value.seq) && (value.seq as number) >= 0\n}\n\nexport function isTurnAttemptRef(value: unknown): value is TurnAttemptRef {\n return isRecord(value)\n && hasOnlyKeys(value, ['attemptId', 'generation'])\n && isEvidenceIdentifier(value.attemptId)\n && Number.isSafeInteger(value.generation) && (value.generation as number) >= 0\n}\n\nfunction isLiveTurnPending(value: unknown): value is LiveTurnPending {\n return isRecord(value)\n && hasOnlyKeys(value, ['modal', 'adapterPending', 'trailingTool', 'newestActivityAt'])\n && typeof value.modal === 'boolean'\n && typeof value.adapterPending === 'boolean'\n && typeof value.trailingTool === 'boolean'\n && (value.newestActivityAt === undefined || isFiniteNumber(value.newestActivityAt))\n}\n\nfunction isNativeMarkerRef(value: unknown): value is NativeTurnMarkerRef {\n return isRecord(value)\n && hasOnlyKeys(value, ['outcome', 'turnId'])\n && (NATIVE_TURN_OUTCOMES as readonly string[]).includes(value.outcome as string)\n && (value.turnId === undefined || isEvidenceIdentifier(value.turnId))\n}\n\nfunction isCoordinatorIdentity(value: unknown): value is EvidenceCoordinatorIdentity {\n return isRecord(value)\n && hasOnlyKeys(value, ['daemonId', 'coordinatorRunId', 'sessionId'])\n && isEvidenceIdentifier(value.daemonId)\n && isEvidenceIdentifier(value.coordinatorRunId)\n && (value.sessionId === undefined || isEvidenceIdentifier(value.sessionId))\n}\n\nfunction hasOnlyKeys(value: Record<string, unknown>, allowed: readonly string[]): boolean {\n for (const key of Object.keys(value)) {\n if (!allowed.includes(key)) return false\n }\n return true\n}\n\nfunction fieldMatches(spec: EvidenceFieldSpec, value: unknown): boolean {\n if (value === undefined) return spec.optional === true\n switch (spec.t) {\n case 'id': return isEvidenceIdentifier(value)\n case 'enum': return typeof value === 'string' && spec.values.includes(value)\n case 'bool': return typeof value === 'boolean'\n case 'int': return (value === null && spec.nullable === true) || Number.isSafeInteger(value)\n case 'ms': return isFiniteNumber(value) && value >= 0\n case 'summary_ref': return isSummaryRef(value)\n case 'attempt_ref': return isTurnAttemptRef(value)\n case 'live': return isLiveTurnPending(value)\n case 'native_marker': return isNativeMarkerRef(value)\n case 'coordinator': return isCoordinatorIdentity(value)\n }\n}\n\n/**\n * Strict structural guard: known kind, every declared field of the right class,\n * and NO undeclared field (an unknown key is how free text would sneak in).\n */\nexport function isTurnEvidence(value: unknown): value is TurnEvidence {\n if (!isRecord(value) || !isTurnEvidenceKind(value.kind)) return false\n const bodySpecs = TURN_EVIDENCE_FIELD_SPECS[value.kind] as Record<string, EvidenceFieldSpec>\n const envelopeSpecs = EVIDENCE_ENVELOPE_FIELD_SPECS as Record<string, EvidenceFieldSpec>\n for (const key of Object.keys(value)) {\n if (key === 'kind') continue\n if (!(key in bodySpecs) && !(key in envelopeSpecs)) return false\n }\n for (const [key, spec] of Object.entries(envelopeSpecs)) {\n if (!fieldMatches(spec, value[key])) return false\n }\n for (const [key, spec] of Object.entries(bodySpecs)) {\n if (!fieldMatches(spec, value[key])) return false\n }\n return true\n}\n\n\n// ─── mesh.<id>.events topic entries (C2) ─────────────────────────────────\n\nexport const TURN_EVIDENCE_FLAGS = ['hollow', 'afterFinalizationTimeout', 'nativeMarker', 'selfAttributing'] as const\nexport type TurnEvidenceFlag = typeof TURN_EVIDENCE_FLAGS[number]\n\n/** Scalar-only payload for `mesh.record` (the existing allow-list projection's output). */\nexport type ProjectedScalars = Readonly<Record<string, string | number | boolean | null>>\n\nexport const MESH_TOPIC_ENTRY_KINDS = ['turn.evidence', 'turn.committed', 'turn.notify', 'mesh.record'] as const\nexport type MeshTopicEntryKind = typeof MESH_TOPIC_ENTRY_KINDS[number]\n\nexport type MeshTopicEntry = { v: typeof MESH_TOPIC_PROTOCOL_VERSION; eventId: string; at: number } & (\n | { k: 'turn.evidence'; attemptId: string; generation: number; ownerDaemonId: string; taskId?: string; sessionId: string\n ev: TurnEvidenceKind; strength?: TurnEndStrength; flags?: Partial<Record<TurnEvidenceFlag, boolean>>\n /** The full (content-free) evidence, so a foreign `turn.ingest` can re-observe it losslessly. */\n evidence?: TurnEvidence }\n | { k: 'turn.committed'; attemptId: string; generation: number; taskId?: string; outcome: TurnOutcome; strength: CommitStrength; reason: TurnReason }\n | { k: 'turn.notify'; attemptId?: string; notify: NotifyKind; targetDaemonId: string; targetSessionId?: string; taskId?: string }\n | { k: 'mesh.record'; ledgerKind: string; nodeId?: string; sessionId?: string; taskId?: string; payload: ProjectedScalars }\n)\n\n\nfunction isOptionalId(value: unknown): boolean {\n return value === undefined || isEvidenceIdentifier(value)\n}\n\nfunction isGeneration(value: unknown): boolean {\n return Number.isSafeInteger(value) && (value as number) >= 0\n}\n\nfunction isProjectedScalars(value: unknown): value is ProjectedScalars {\n if (!isRecord(value)) return false\n for (const v of Object.values(value)) {\n if (!(v === null || typeof v === 'number' || typeof v === 'boolean' || typeof v === 'string')) return false\n }\n return true\n}\n\nexport function isMeshTopicEntry(value: unknown): value is MeshTopicEntry {\n if (!isRecord(value)) return false\n if (value.v !== MESH_TOPIC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.eventId) || !isFiniteNumber(value.at)) return false\n switch (value.k) {\n case 'turn.evidence': {\n if (!isEvidenceIdentifier(value.attemptId) || !isGeneration(value.generation)) return false\n if (!isEvidenceIdentifier(value.ownerDaemonId) || !isEvidenceIdentifier(value.sessionId) || !isOptionalId(value.taskId)) return false\n if (!isTurnEvidenceKind(value.ev)) return false\n if (value.strength !== undefined && !(TURN_END_STRENGTHS as readonly string[]).includes(value.strength as string)) return false\n if (value.flags !== undefined) {\n if (!isRecord(value.flags)) return false\n for (const [flag, on] of Object.entries(value.flags)) {\n if (!(TURN_EVIDENCE_FLAGS as readonly string[]).includes(flag) || typeof on !== 'boolean') return false\n }\n }\n if (value.evidence !== undefined && !(isTurnEvidence(value.evidence) && value.evidence.kind === value.ev)) return false\n return true\n }\n case 'turn.committed':\n return isEvidenceIdentifier(value.attemptId) && isGeneration(value.generation) && isOptionalId(value.taskId)\n && isTurnOutcome(value.outcome) && isCommitStrength(value.strength) && isTurnReason(value.reason)\n case 'turn.notify':\n return isOptionalId(value.attemptId) && isNotifyKind(value.notify) && isEvidenceIdentifier(value.targetDaemonId)\n && isOptionalId(value.targetSessionId) && isOptionalId(value.taskId)\n case 'mesh.record':\n return isEvidenceIdentifier(value.ledgerKind) && isOptionalId(value.nodeId) && isOptionalId(value.sessionId)\n && isOptionalId(value.taskId) && isProjectedScalars(value.payload)\n default:\n return false\n }\n}\n\n/**\n * Project evidence onto its `turn.evidence` topic entry. Pure; the attempt\n * identity comes from the resolved attempt (the evidence may lack attemptRef).\n */\nexport function projectTurnEvidenceEntry(\n evidence: TurnEvidence,\n attempt: { attemptId: string; generation: number; ownerDaemonId: string },\n): Extract<MeshTopicEntry, { k: 'turn.evidence' }> {\n const flags: Partial<Record<TurnEvidenceFlag, boolean>> = {}\n if (evidence.kind === 'turn_end') {\n if (evidence.hollow) flags.hollow = true\n if (evidence.afterFinalizationTimeout) flags.afterFinalizationTimeout = true\n }\n if (evidence.kind === 'transcript_final') {\n if (evidence.nativeMarker) flags.nativeMarker = true\n if (evidence.selfAttributing) flags.selfAttributing = true\n }\n const taskId = evidence.taskId\n return {\n v: MESH_TOPIC_PROTOCOL_VERSION,\n eventId: evidence.eventId,\n at: evidence.at,\n k: 'turn.evidence',\n attemptId: attempt.attemptId,\n generation: attempt.generation,\n ownerDaemonId: attempt.ownerDaemonId,\n ...(taskId ? { taskId } : {}),\n sessionId: evidence.sessionId,\n ev: evidence.kind,\n ...(evidence.kind === 'turn_end' ? { strength: evidence.strength } : {}),\n ...(Object.keys(flags).length > 0 ? { flags } : {}),\n evidence,\n }\n}\n","/**\n * session-launch — how a session was launched: provider, model and thinking\n * level, and WHERE each value came from.\n *\n * Wiring-unification Phase E (docs/design/2026-09-23-wiring-unification.md §7,\n * RC5). Before this record the only trace of a session's model was a display\n * string in recent-activity (`buildLegacyModelModeSummaryMetadata`), so nobody\n * could answer \"did I pick this model, did the dashboard restore it from last\n * time, did a mesh slot choose it, or is it just the provider default?\" — and\n * after a daemon restart not even the value survived.\n *\n * The daemon owns the record (daemon-core `SessionRegistry`); this file holds the\n * shape and the pure readers so daemon-core, web-core, the server and the MCP\n * server all read one definition. It is a dependency-free leaf, like the rest of\n * mesh-shared.\n *\n * ★Server content boundary (CLAUDE.md): the full record rides P2P only. The\n * server path carries exactly two derived fields — `model` (an identifier,\n * passed through {@link sanitizeModelIdentifier}) and `modelSource` (an enum,\n * passed through {@link isModelAxisSource}). Never widen that to the record.\n */\n\n/**\n * Where a model / thinking-level value came from.\n *\n * `restore` is deliberately NOT a member: a hosted session re-attached after a\n * daemon restart keeps the ORIGINAL source (the user still picked that model);\n * only `SessionLaunchRecord.launchedBy` records that the session came back via\n * restore.\n */\nimport { readString } from './json'\n\nexport const MODEL_AXIS_SOURCES = [\n /** Picked explicitly for this launch (dashboard dropdown, coordinator dialog). */\n 'user',\n /** The dashboard dialog restored it from the last launch (browser-local memory). */\n 'remembered',\n /** A mesh capability slot supplied it (or a difficulty preset the slot outranked). */\n 'mesh_slot',\n /** An explicit per-task model / thinking level on a mesh queue task. */\n 'task_override',\n /** Nothing was requested; the provider's default is known (discovery / manifest). */\n 'provider_default',\n /** A value was requested without saying where it came from, or nothing is known. */\n 'unspecified',\n] as const\n\nexport type ModelAxisSource = typeof MODEL_AXIS_SOURCES[number]\n\nexport function isModelAxisSource(value: unknown): value is ModelAxisSource {\n return typeof value === 'string' && (MODEL_AXIS_SOURCES as readonly string[]).includes(value)\n}\n\n/**\n * Which surface started the session. `restore` means \"re-attached to a hosted\n * runtime that outlived a daemon restart\" — the axis sources are preserved.\n * `assistant` is the assistant layer's own session (`launch_assistant`,\n * docs/design/2026-10-07-assistant-layer.md §4.5).\n */\nexport const SESSION_LAUNCHED_BY = ['dashboard', 'mesh', 'cli', 'api', 'restore', 'assistant'] as const\n\nexport type SessionLaunchedBy = typeof SESSION_LAUNCHED_BY[number]\n\nexport function isSessionLaunchedBy(value: unknown): value is SessionLaunchedBy {\n return typeof value === 'string' && (SESSION_LAUNCHED_BY as readonly string[]).includes(value)\n}\n\n/** How a value entered the axis history. */\nexport type ModelSelectionVia = 'launch' | 'change_model' | 'observed'\n\nexport interface ModelSelectionHistoryEntry {\n at: number\n value: string\n via: ModelSelectionVia\n}\n\n/** One axis (model, or thinking level) of a session launch. */\nexport interface ModelSelection {\n /** What the caller asked for. Absent = nothing requested. */\n requested?: string\n source: ModelAxisSource\n /**\n * The value actually handed to the provider: after `modelLaunchValueMap`\n * (CLI `--model` template) or the ACP `setConfigOption` call. Absent when the\n * request was not applied (no template, the config call failed) or nothing\n * was requested.\n */\n launchValue?: string\n /**\n * The provider default this session is expected to run with when nothing was\n * requested (`source === 'provider_default'` only): discovery `models[0]`,\n * else the manifest's first option. Nothing was passed to the provider.\n */\n resolvedDefault?: string\n /** Last explicit runtime change (`change_model` / `set_thought_level`). */\n current?: string\n /** Last value the provider itself reported (statusline, native history). */\n observed?: string\n observedAt?: number\n /** Every value change in order. The last entry is the value in force. */\n history: ModelSelectionHistoryEntry[]\n}\n\nexport interface SessionLaunchRecord {\n sessionId: string\n providerType: string\n providerVersion?: string\n providerChannel?: 'stable' | 'preview'\n /** `restore` = re-attached after a daemon restart; the axis sources stay the original ones. */\n launchedBy: SessionLaunchedBy\n launchedAt: number\n workspace?: string\n model: ModelSelection\n thinkingLevel: ModelSelection\n autoApproveModeId?: string\n /**\n * Reserved by the design (§7 E1) for sanitized launch argv. Not populated:\n * argv carries coordinator system-prompt text and config paths, and the\n * session-host record already keeps the raw argv for restore.\n */\n cliArgs?: string[]\n}\n\n/** History is bounded; the first `launch` entry is always kept. */\nexport const MODEL_SELECTION_HISTORY_LIMIT = 20\n\n/** The value in force now: the latest change, else the launch-time value. */\nexport function effectiveModelSelectionValue(selection: ModelSelection | null | undefined): string | undefined {\n if (!selection) return undefined\n const last = Array.isArray(selection.history) ? selection.history[selection.history.length - 1] : undefined\n return last?.value\n ?? selection.current\n ?? selection.observed\n ?? launchModelSelectionValue(selection)\n}\n\n/** The value the session started with (what was passed, else asked for, else the default). */\nexport function launchModelSelectionValue(selection: ModelSelection | null | undefined): string | undefined {\n if (!selection) return undefined\n const launch = Array.isArray(selection.history)\n ? selection.history.find((entry) => entry.via === 'launch')\n : undefined\n return launch?.value ?? selection.launchValue ?? selection.requested ?? selection.resolvedDefault\n}\n\nexport interface ModelSelectionDisplay {\n /** The value in force now. */\n value: string\n /** The value the session launched with, when it differs from `value`. */\n changedFrom?: string\n source: ModelAxisSource\n}\n\n/** Pure projection for UI chips: \"sonnet · chosen\", \"sonnet → opus (changed)\". */\nexport function describeModelSelection(selection: ModelSelection | null | undefined): ModelSelectionDisplay | undefined {\n const value = effectiveModelSelectionValue(selection)\n if (!selection || !value) return undefined\n const launched = launchModelSelectionValue(selection)\n return {\n value,\n ...(launched && launched !== value ? { changedFrom: launched } : {}),\n source: isModelAxisSource(selection.source) ? selection.source : 'unspecified',\n }\n}\n\n/**\n * The only form a model / thinking value may take on the server path: an\n * identifier (`claude-opus-4-1`, `gpt-5.6-sol`, `openai/gpt-4o`, `opus[1m]`,\n * `high`). No whitespace, bounded length — a free-text sentence cannot pass.\n * Human labels (`Gemini 3.7 Flash (High)`) are P2P-only and are dropped here.\n */\nconst MODEL_IDENTIFIER_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:/@[\\]+-]{0,95}$/\n\nexport function sanitizeModelIdentifier(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n return MODEL_IDENTIFIER_PATTERN.test(trimmed) ? trimmed : undefined\n}\n\nfunction readFiniteNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n\nfunction parseModelSelection(raw: unknown): ModelSelection | undefined {\n if (!raw || typeof raw !== 'object') return undefined\n const record = raw as Record<string, unknown>\n const history: ModelSelectionHistoryEntry[] = []\n if (Array.isArray(record.history)) {\n for (const entry of record.history) {\n if (!entry || typeof entry !== 'object') continue\n const e = entry as Record<string, unknown>\n const value = readString(e.value)\n const at = readFiniteNumber(e.at)\n const via = e.via === 'launch' || e.via === 'change_model' || e.via === 'observed' ? e.via : undefined\n if (value && at !== undefined && via) history.push({ at, value, via })\n }\n }\n const requested = readString(record.requested)\n const launchValue = readString(record.launchValue)\n const resolvedDefault = readString(record.resolvedDefault)\n const current = readString(record.current)\n const observed = readString(record.observed)\n const observedAt = readFiniteNumber(record.observedAt)\n return {\n source: isModelAxisSource(record.source) ? record.source : 'unspecified',\n ...(requested ? { requested } : {}),\n ...(launchValue ? { launchValue } : {}),\n ...(resolvedDefault ? { resolvedDefault } : {}),\n ...(current ? { current } : {}),\n ...(observed ? { observed } : {}),\n ...(observedAt !== undefined ? { observedAt } : {}),\n history: history.slice(-MODEL_SELECTION_HISTORY_LIMIT),\n }\n}\n\n/**\n * Validate a record that crossed a process or storage boundary (session-host\n * record meta on restore, a P2P snapshot). Returns undefined for anything that\n * is not recognisably a launch record; unknown keys are dropped.\n */\nexport function parseSessionLaunchRecord(raw: unknown): SessionLaunchRecord | undefined {\n if (!raw || typeof raw !== 'object') return undefined\n const record = raw as Record<string, unknown>\n const sessionId = readString(record.sessionId)\n const providerType = readString(record.providerType)\n const launchedAt = readFiniteNumber(record.launchedAt)\n const model = parseModelSelection(record.model)\n const thinkingLevel = parseModelSelection(record.thinkingLevel)\n if (!sessionId || !providerType || launchedAt === undefined || !model || !thinkingLevel) return undefined\n const providerVersion = readString(record.providerVersion)\n const workspace = readString(record.workspace)\n const autoApproveModeId = readString(record.autoApproveModeId)\n return {\n sessionId,\n providerType,\n ...(providerVersion ? { providerVersion } : {}),\n ...(record.providerChannel === 'stable' || record.providerChannel === 'preview'\n ? { providerChannel: record.providerChannel }\n : {}),\n launchedBy: isSessionLaunchedBy(record.launchedBy) ? record.launchedBy : 'api',\n launchedAt,\n ...(workspace ? { workspace } : {}),\n model,\n thinkingLevel,\n ...(autoApproveModeId ? { autoApproveModeId } : {}),\n }\n}\n","/**\n * turn-ipc shared runtime-guard primitives (the protocol version stamp and the\n * small structural checks every command decoder composes). Part of the turn-ipc\n * wire contract (./turn-ipc.ts).\n */\n\nimport { isEvidenceIdentifier } from './turn-evidence';\nimport { isRecord } from './protocol/envelope';\n\n// ─── shared primitives ─────────────────────────────────────────────────────\n\n/** Every request in this file is versioned so a responder can reject a shape it predates. */\nexport const TURN_IPC_PROTOCOL_VERSION = 1 as const\n\nexport function isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n\nexport function isNonNegativeInt(value: unknown): value is number {\n return Number.isSafeInteger(value) && (value as number) >= 0\n}\n\nexport function isOptionalId(value: unknown): boolean {\n return value === undefined || isEvidenceIdentifier(value)\n}\n\nexport function hasOnlyKeys(value: Record<string, unknown>, allowed: readonly string[]): boolean {\n for (const key of Object.keys(value)) {\n if (!allowed.includes(key)) return false\n }\n return true\n}\n\nexport function makeGuard<T extends readonly string[]>(values: T): (value: unknown) => value is T[number] {\n const set: ReadonlySet<string> = new Set(values)\n return (value: unknown): value is T[number] => typeof value === 'string' && set.has(value)\n}\n\nexport function isStringArray(value: unknown): value is readonly string[] {\n return Array.isArray(value) && value.every((v) => typeof v === 'string')\n}\n\nexport function isOptionalShortString(value: unknown, max = 512): boolean {\n return value === undefined || (typeof value === 'string' && value.trim().length > 0 && value.length <= max)\n}\n\nexport function isRecordArray(value: unknown): value is readonly Record<string, unknown>[] {\n return Array.isArray(value) && value.every(isRecord)\n}\n\nexport function isOptionalRecord(value: unknown): boolean {\n return value === undefined || isRecord(value)\n}\n\nexport function isOptionalBoolean(value: unknown): boolean {\n return value === undefined || typeof value === 'boolean'\n}\n\nexport function isOptionalString(value: unknown): boolean {\n return value === undefined || typeof value === 'string'\n}\n","/**\n * turn-ipc — the turn-ledger commands: turn_observe, mesh_record, turn_cancel,\n * operator_status, turn_query, mesh_index_query. Part of the turn-ipc wire\n * contract (./turn-ipc.ts).\n */\n\nimport {\n makeGuard,\n TURN_IPC_PROTOCOL_VERSION,\n hasOnlyKeys,\n isNonNegativeInt,\n isOptionalId,\n isFiniteNumber,\n} from './turn-ipc-guards';\nimport {\n type TurnEvidence,\n type TurnAttemptRef,\n type TurnOutcome,\n isTurnEvidence,\n isEvidenceIdentifier,\n type ProjectedScalars,\n type TurnReason,\n isTurnReason,\n type TurnEvidenceKind,\n} from './turn-evidence';\nimport { isRecord } from './protocol/envelope';\n\n// ─── turn_observe ───────────────────────────────────────────────────────────\n\n/** Reducer verdict, mirrored from the C1 reducer's `reduce()` return shape. */\nexport const TURN_OBSERVE_VERDICTS = ['applied', 'recorded', 'rejected'] as const\nexport type TurnObserveVerdict = typeof TURN_OBSERVE_VERDICTS[number]\nconst isTurnObserveVerdict = makeGuard(TURN_OBSERVE_VERDICTS)\n\nexport interface TurnObserveRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n evidence: TurnEvidence\n}\n\nexport interface TurnObserveResponse {\n verdict: TurnObserveVerdict\n attemptRef: TurnAttemptRef\n /** Present only when the evidence committed the attempt (verdict 'applied' + a terminal-class kind). */\n outcome?: TurnOutcome\n}\n\nfunction isTurnObserveRequest(value: unknown): value is TurnObserveRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'evidence'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isTurnEvidence(value.evidence)\n}\n\nexport function decodeTurnObserveRequest(value: unknown): TurnObserveRequest | null {\n return isTurnObserveRequest(value) ? value : null\n}\n\nfunction isTurnAttemptRefValue(value: unknown): value is TurnAttemptRef {\n return isRecord(value) && hasOnlyKeys(value, ['attemptId', 'generation'])\n && isEvidenceIdentifier(value.attemptId) && isNonNegativeInt(value.generation)\n}\n\nfunction isTurnObserveResponse(value: unknown): value is TurnObserveResponse {\n return isRecord(value) && hasOnlyKeys(value, ['verdict', 'attemptRef', 'outcome'])\n && isTurnObserveVerdict(value.verdict)\n && isTurnAttemptRefValue(value.attemptRef)\n && (value.outcome === undefined || isTurnOutcomeValue(value.outcome))\n}\n\nconst TURN_OUTCOMES_LOCAL = ['completed', 'failed', 'cancelled'] as const\nfunction isTurnOutcomeValue(value: unknown): value is TurnOutcome {\n return typeof value === 'string' && (TURN_OUTCOMES_LOCAL as readonly string[]).includes(value)\n}\n\nexport function decodeTurnObserveResponse(value: unknown): TurnObserveResponse | null {\n return isTurnObserveResponse(value) ? value : null\n}\n\n// ─── mesh_record ────────────────────────────────────────────────────────────\n\n/**\n * Structural pin of `seqscribe/mesh-event-projection.ts` `PROJECTED_PAYLOAD_KEYS`\n * (daemon-core; this leaf cannot import it). A test in this package's test\n * suite AND a daemon-core test each assert their list equals this one — see\n * `mesh-shared/test/turn-ipc.test.ts` and the C-W6 report's break-once table.\n * Adding a key here is the SAME assertion as adding it there: non-content\n * (identifier, enum, boolean, or counter), never free text.\n */\nexport const MESH_RECORD_PAYLOAD_KEYS = [\n // Identifiers\n 'taskId', 'deliveryId', 'attemptId', 'missionId', 'checkpointId', 'promptId', 'providerSessionId', 'targetNoteId',\n // Routing / addressing\n 'nodeId', 'sessionId', 'providerType', 'transport', 'attemptedSessionId', 'holderSessionId',\n // Outcome enums\n 'reason', 'status', 'outcome', 'terminalKind', 'event',\n 'source', 'intentionalStopReason',\n // Booleans\n 'retryable', 'rebound', 'forced', 'fallback', 'membershipRemoved', 'requestedForce', 'removedByRemoteDaemon',\n 'completedViaReady', 'intentional', 'weak',\n // Counters\n 'attempt', 'attemptCount', 'count',\n] as const\n\nconst MESH_RECORD_PAYLOAD_KEY_SET: ReadonlySet<string> = new Set(MESH_RECORD_PAYLOAD_KEYS)\n\n/** Maximum length of any string value in a `mesh_record` payload (mirrors `MAX_PROJECTED_STRING`). */\nexport const MAX_MESH_RECORD_STRING = 200\n\nexport interface MeshRecordRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** The original ledger `kind` string (daemon-core `MeshLedgerKind`; mesh-shared cannot import that union, so it is an identifier here). */\n ledgerKind: string\n nodeId?: string\n sessionId?: string\n taskId?: string\n /** Restricted to `MESH_RECORD_PAYLOAD_KEYS` — an unknown key is a decode failure, not a silently dropped field. */\n payload: ProjectedScalars\n}\n\nexport interface MeshRecordResponse {\n /** `mesh.<id>.events` append coordinates, for callers that need to reference the entry (e.g. a `ref`'d handoff). */\n eventId: string\n seq: number\n}\n\nfunction isProjectedScalarsValue(value: unknown): value is ProjectedScalars {\n if (!isRecord(value)) return false\n for (const v of Object.values(value)) {\n if (v === null) continue\n if (typeof v === 'boolean' || typeof v === 'number') continue\n if (typeof v === 'string') { if (v.length > MAX_MESH_RECORD_STRING) return false; continue }\n return false\n }\n return true\n}\n\n/** Every payload key must be a member of `MESH_RECORD_PAYLOAD_KEYS` — the allow-list boundary at the wire. */\nexport function isMeshRecordPayload(value: unknown): value is ProjectedScalars {\n if (!isProjectedScalarsValue(value)) return false\n for (const key of Object.keys(value as Record<string, unknown>)) {\n if (!MESH_RECORD_PAYLOAD_KEY_SET.has(key)) return false\n }\n return true\n}\n\nfunction isMeshRecordRequest(value: unknown): value is MeshRecordRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'ledgerKind', 'nodeId', 'sessionId', 'taskId', 'payload'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isEvidenceIdentifier(value.meshId)\n && isEvidenceIdentifier(value.ledgerKind)\n && isOptionalId(value.nodeId) && isOptionalId(value.sessionId) && isOptionalId(value.taskId)\n && isMeshRecordPayload(value.payload)\n}\n\nexport function decodeMeshRecordRequest(value: unknown): MeshRecordRequest | null {\n return isMeshRecordRequest(value) ? value : null\n}\n\nfunction isMeshRecordResponse(value: unknown): value is MeshRecordResponse {\n return isRecord(value) && hasOnlyKeys(value, ['eventId', 'seq'])\n && isEvidenceIdentifier(value.eventId) && isNonNegativeInt(value.seq)\n}\n\nexport function decodeMeshRecordResponse(value: unknown): MeshRecordResponse | null {\n return isMeshRecordResponse(value) ? value : null\n}\n\n// ─── turn_cancel ────────────────────────────────────────────────────────────\n\nexport interface TurnCancelRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n /** Exactly one of the two must be present — the decoder rejects both-or-neither. */\n attemptId?: string\n taskId?: string\n reason: TurnReason\n}\n\nexport interface TurnCancelResponse {\n attemptRef: TurnAttemptRef\n verdict: TurnObserveVerdict\n}\n\nfunction isTurnCancelRequest(value: unknown): value is TurnCancelRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'attemptId', 'taskId', 'reason'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n const hasAttempt = value.attemptId !== undefined\n const hasTask = value.taskId !== undefined\n if (hasAttempt === hasTask) return false // exactly one of the two\n if (hasAttempt && !isEvidenceIdentifier(value.attemptId)) return false\n if (hasTask && !isEvidenceIdentifier(value.taskId)) return false\n return isTurnReason(value.reason)\n}\n\nexport function decodeTurnCancelRequest(value: unknown): TurnCancelRequest | null {\n return isTurnCancelRequest(value) ? value : null\n}\n\nfunction isTurnCancelResponse(value: unknown): value is TurnCancelResponse {\n return isRecord(value) && hasOnlyKeys(value, ['attemptRef', 'verdict'])\n && isTurnAttemptRefValue(value.attemptRef) && isTurnObserveVerdict(value.verdict)\n}\n\nexport function decodeTurnCancelResponse(value: unknown): TurnCancelResponse | null {\n return isTurnCancelResponse(value) ? value : null\n}\n\n// ─── operator_status ────────────────────────────────────────────────────────\n\n/**\n * Fire-and-forget operator/tool-call status record — replaces\n * `recordMeshCoordinatorToolCall` (10 sites, `mesh_tool_call_log`) and doubles\n * as the `operator_status` evidence kind's wire shape.\n *\n * NAMING NOTE (flagged for the C-W6 implementer, see report §\"mismatch\"):\n * the C-W6 brief's DELIVERABLES describes this request as\n * `{taskId, status: MeshTaskStatus, reason}`, but C1's `operator_status`\n * evidence kind (`turn-evidence.ts` `OPERATOR_STATUSES`) is the closed\n * 2-value set `'completed' | 'failed'` — a verdict on an operator ACTION, not\n * a `MeshTaskStatus` (5-value queue-row status: pending/assigned/completed/\n * failed/cancelled). This contract follows `turn-evidence.ts` because that is\n * what the C1 reducer actually consumes for this evidence kind; using the\n * 5-value `MeshTaskStatus` here would let this request carry `pending` or\n * `assigned`, which the reducer has no transition for.\n */\nexport const OPERATOR_STATUS_VALUES = ['completed', 'failed'] as const\nexport type OperatorStatusValue = typeof OPERATOR_STATUS_VALUES[number]\nconst isOperatorStatusValue = makeGuard(OPERATOR_STATUS_VALUES)\n\nexport const OPERATOR_STATUS_REASON_VALUES = ['operator_update', 'refine_terminal', 'validation_terminal'] as const\nexport type OperatorStatusReasonValue = typeof OPERATOR_STATUS_REASON_VALUES[number]\nconst isOperatorStatusReasonValue = makeGuard(OPERATOR_STATUS_REASON_VALUES)\n\nexport interface OperatorStatusRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n taskId: string\n status: OperatorStatusValue\n reason: OperatorStatusReasonValue\n}\n\n/** Acknowledgement only — this command is fire-and-forget by design (the daemon owns rate-limiting the underlying log). */\nexport interface OperatorStatusResponse {\n accepted: true\n}\n\nfunction isOperatorStatusRequest(value: unknown): value is OperatorStatusRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'taskId', 'status', 'reason'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isEvidenceIdentifier(value.taskId)\n && isOperatorStatusValue(value.status)\n && isOperatorStatusReasonValue(value.reason)\n}\n\nexport function decodeOperatorStatusRequest(value: unknown): OperatorStatusRequest | null {\n return isOperatorStatusRequest(value) ? value : null\n}\n\nfunction isOperatorStatusResponse(value: unknown): value is OperatorStatusResponse {\n return isRecord(value) && hasOnlyKeys(value, ['accepted']) && value.accepted === true\n}\n\nexport function decodeOperatorStatusResponse(value: unknown): OperatorStatusResponse | null {\n return isOperatorStatusResponse(value) ? value : null\n}\n\n// ─── turn_query ─────────────────────────────────────────────────────────────\n\n/** Row shape returned by `turn_query` — scalar projection of a `turn_attempts` row (C3 schema), never `data_json`/`payload_json` content. */\nexport interface TurnQueryAttemptRow {\n attemptId: string\n generation: number\n meshId?: string\n taskId?: string\n sessionId: string\n nodeId?: string\n providerType?: string\n state: string\n terminalOutcome?: TurnOutcome\n terminalReason?: TurnReason\n acceptedAt: number\n terminalAt?: number\n}\n\n/** Row shape returned by `turn_query` for the event stream — scalar projection of a `turn_events` row, `payload_json` NEVER included. */\nexport interface TurnQueryEventRow {\n eventId: string\n attemptId?: string\n generation?: number\n sessionId: string\n kind: TurnEvidenceKind\n source: string\n verdict: TurnObserveVerdict | 'forwarded'\n atMs: number\n}\n\nexport interface TurnQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n taskId?: string\n attemptId?: string\n sessionId?: string\n state?: string\n since?: number\n tail?: number\n}\n\nexport interface TurnQueryResponse {\n attempts: readonly TurnQueryAttemptRow[]\n events: readonly TurnQueryEventRow[]\n /** C7-5: set while `mesh.<id>.events` replication is behind for this mesh — the caller must not treat a fleet-scope answer as complete. */\n replicationPending?: boolean\n}\n\nfunction isTurnQueryRequest(value: unknown): value is TurnQueryRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'taskId', 'attemptId', 'sessionId', 'state', 'since', 'tail'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isEvidenceIdentifier(value.meshId)\n && isOptionalId(value.taskId) && isOptionalId(value.attemptId) && isOptionalId(value.sessionId)\n && (value.state === undefined || isEvidenceIdentifier(value.state))\n && (value.since === undefined || isFiniteNumber(value.since))\n && (value.tail === undefined || isNonNegativeInt(value.tail))\n}\n\nexport function decodeTurnQueryRequest(value: unknown): TurnQueryRequest | null {\n return isTurnQueryRequest(value) ? value : null\n}\n\nconst TURN_QUERY_ATTEMPT_ROW_KEYS = [\n 'attemptId', 'generation', 'meshId', 'taskId', 'sessionId', 'nodeId', 'providerType',\n 'state', 'terminalOutcome', 'terminalReason', 'acceptedAt', 'terminalAt',\n] as const\n\nfunction isTurnQueryAttemptRow(value: unknown): value is TurnQueryAttemptRow {\n if (!isRecord(value) || !hasOnlyKeys(value, TURN_QUERY_ATTEMPT_ROW_KEYS)) return false\n if (!isEvidenceIdentifier(value.attemptId) || !isNonNegativeInt(value.generation)) return false\n if (!isOptionalId(value.meshId) || !isOptionalId(value.taskId)) return false\n if (!isEvidenceIdentifier(value.sessionId)) return false\n if (!isOptionalId(value.nodeId) || !isOptionalId(value.providerType)) return false\n if (typeof value.state !== 'string') return false\n if (value.terminalOutcome !== undefined && !isTurnOutcomeValue(value.terminalOutcome)) return false\n if (value.terminalReason !== undefined && !isTurnReason(value.terminalReason)) return false\n if (!isFiniteNumber(value.acceptedAt)) return false\n if (value.terminalAt !== undefined && !isFiniteNumber(value.terminalAt)) return false\n return true\n}\n\nconst TURN_QUERY_EVENT_VERDICTS = ['applied', 'recorded', 'rejected', 'forwarded'] as const\nconst TURN_QUERY_EVENT_ROW_KEYS = ['eventId', 'attemptId', 'generation', 'sessionId', 'kind', 'source', 'verdict', 'atMs'] as const\n\nfunction isTurnQueryEventRow(value: unknown): value is TurnQueryEventRow {\n if (!isRecord(value) || !hasOnlyKeys(value, TURN_QUERY_EVENT_ROW_KEYS)) return false\n if (!isEvidenceIdentifier(value.eventId)) return false\n if (!isOptionalId(value.attemptId)) return false\n if (value.generation !== undefined && !isNonNegativeInt(value.generation)) return false\n if (!isEvidenceIdentifier(value.sessionId)) return false\n if (typeof value.kind !== 'string') return false\n if (typeof value.source !== 'string') return false\n if (!(TURN_QUERY_EVENT_VERDICTS as readonly string[]).includes(value.verdict as string)) return false\n if (!isFiniteNumber(value.atMs)) return false\n return true\n}\n\nfunction isTurnQueryResponse(value: unknown): value is TurnQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['attempts', 'events', 'replicationPending'])) return false\n if (!Array.isArray(value.attempts) || !value.attempts.every(isTurnQueryAttemptRow)) return false\n if (!Array.isArray(value.events) || !value.events.every(isTurnQueryEventRow)) return false\n if (value.replicationPending !== undefined && typeof value.replicationPending !== 'boolean') return false\n return true\n}\n\nexport function decodeTurnQueryResponse(value: unknown): TurnQueryResponse | null {\n return isTurnQueryResponse(value) ? value : null\n}\n\n// ─── mesh_index_query ───────────────────────────────────────────────────────\n\nexport const MESH_INDEX_QUERY_WRITER_SCOPES = ['own', 'fleet'] as const\nexport type MeshIndexQueryWriterScope = typeof MESH_INDEX_QUERY_WRITER_SCOPES[number]\nconst isMeshIndexQueryWriterScope = makeGuard(MESH_INDEX_QUERY_WRITER_SCOPES)\n\nexport interface MeshIndexQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n ledgerKind?: string\n sessionId?: string\n taskId?: string\n writer?: MeshIndexQueryWriterScope\n since?: number\n tail?: number\n}\n\n/** Row shape returned by `mesh_index_query` — a `mesh_topic_index` row (C3 schema). */\nexport interface MeshTopicIndexRow {\n writer: string\n seq: number\n meshId: string\n eventId: string\n kind: string\n ledgerKind?: string\n taskId?: string\n sessionId?: string\n nodeId?: string\n atMs: number\n payload: ProjectedScalars\n}\n\nexport interface MeshIndexQueryResponse {\n rows: readonly MeshTopicIndexRow[]\n /** C7-5: true while `mesh.<id>.events` replication is behind for this mesh. */\n replicationPending?: boolean\n}\n\nfunction isMeshIndexQueryRequest(value: unknown): value is MeshIndexQueryRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'ledgerKind', 'sessionId', 'taskId', 'writer', 'since', 'tail'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isEvidenceIdentifier(value.meshId)\n && isOptionalId(value.ledgerKind) && isOptionalId(value.sessionId) && isOptionalId(value.taskId)\n && (value.writer === undefined || isMeshIndexQueryWriterScope(value.writer))\n && (value.since === undefined || isFiniteNumber(value.since))\n && (value.tail === undefined || isNonNegativeInt(value.tail))\n}\n\nexport function decodeMeshIndexQueryRequest(value: unknown): MeshIndexQueryRequest | null {\n return isMeshIndexQueryRequest(value) ? value : null\n}\n\nconst MESH_TOPIC_INDEX_ROW_KEYS = [\n 'writer', 'seq', 'meshId', 'eventId', 'kind', 'ledgerKind', 'taskId', 'sessionId', 'nodeId', 'atMs', 'payload',\n] as const\n\nfunction isMeshTopicIndexRow(value: unknown): value is MeshTopicIndexRow {\n if (!isRecord(value) || !hasOnlyKeys(value, MESH_TOPIC_INDEX_ROW_KEYS)) return false\n if (!isEvidenceIdentifier(value.writer) || !isNonNegativeInt(value.seq)) return false\n if (!isEvidenceIdentifier(value.meshId) || !isEvidenceIdentifier(value.eventId)) return false\n if (typeof value.kind !== 'string') return false\n if (!isOptionalId(value.ledgerKind) || !isOptionalId(value.taskId) || !isOptionalId(value.sessionId) || !isOptionalId(value.nodeId)) return false\n if (!isFiniteNumber(value.atMs)) return false\n // Rows replay mesh.record entries, so the payload is held to the SAME\n // allow-list as a mesh_record request — not just \"any scalar map\" — to\n // stop a fleet-wide read from surfacing a key that was never reviewed.\n if (!isMeshRecordPayload(value.payload)) return false\n return true\n}\n\nexport function isMeshIndexQueryResponse(value: unknown): value is MeshIndexQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['rows', 'replicationPending'])) return false\n if (!Array.isArray(value.rows) || !value.rows.every(isMeshTopicIndexRow)) return false\n if (value.replicationPending !== undefined && typeof value.replicationPending !== 'boolean') return false\n return true\n}\n\nexport function decodeMeshIndexQueryResponse(value: unknown): MeshIndexQueryResponse | null {\n return isMeshIndexQueryResponse(value) ? value : null\n}\n","/**\n * turn-ipc — mission, note, tool-call and ledger commands: mission_upsert,\n * mission_query, mission_list_query, note_upsert, note_forget, tool_call_record,\n * ledger_query. Part of the turn-ipc wire contract (./turn-ipc.ts).\n */\n\nimport {\n makeGuard,\n hasOnlyKeys,\n isStringArray,\n TURN_IPC_PROTOCOL_VERSION,\n isNonNegativeInt,\n isOptionalShortString,\n isOptionalId,\n} from './turn-ipc-guards';\nimport { isRecord } from './protocol/envelope';\nimport { isEvidenceIdentifier } from './turn-evidence';\n\n// ─── mission_upsert / mission_query ────────────────────────────────────────\n//\n// Decision (2026-09-23, design doc §5 C2 update): missions and graph gates\n// have no home in the original six commands — `upsertMeshMission`/\n// `listMeshMissionsForTool` write/read structured state with a free-text\n// `goal`/`title` that cannot fit `mesh_record`'s scalar `ProjectedScalars`\n// allow-list (§ \"MESH_RECORD_PAYLOAD_KEYS\" above has no text field, on\n// purpose). Two more commands, not a widened allow-list:\n//\n// - mission_upsert — create/update a mission (mesh-missions.ts\n// `upsertMeshMission`'s shape).\n// - mission_query — list missions for a mesh, optionally filtered by\n// status (`getMeshMissions`'s shape).\n//\n// WHY FREE TEXT IS FINE HERE, UNLIKE mesh_record's payload: this is LOCAL\n// IPC between mcp-server and the daemon that owns the mission table — both\n// processes run on the operator's own machine. The content boundary this\n// program protects is \"the SERVER never receives chat content\" (CLAUDE.md);\n// IPC between two local processes was never inside that boundary, the same\n// way a direct in-process function call wasn't. Cross-machine mission text\n// (a worker learning about a mission a coordinator defined) travels as a\n// `mesh.<id>.handoff` ref per C10-1's precedent — mission_upsert/query never\n// themselves cross a machine boundary.\n\nexport const MESH_MISSION_STATUSES = ['active', 'paused', 'completed', 'abandoned'] as const\nexport type MeshMissionStatusValue = typeof MESH_MISSION_STATUSES[number]\nexport const isMeshMissionStatusValue = makeGuard(MESH_MISSION_STATUSES)\n\n// H2 (mission brief, wiring-unification Phase H — docs/design/2026-09-23-wiring-\n// unification.md §7c): free text, same \"local IPC is inside the boundary\" rationale\n// as `goal` above (section note). `MissionBriefWire` is a structural mirror of\n// mesh-shared's own `MissionBrief` (mission-brief.ts) rather than importing it —\n// this file's guards are all hand-rolled structural checks, and importing the type\n// only (not the class) would still couple this wire contract to that module's\n// internal shape; a mirror keeps the two independently reviewable, same as every\n// other wire type in this file.\nexport interface MissionBriefWire {\n goal: string\n constraints?: readonly string[]\n doneCriteria?: readonly string[]\n handoffNotes?: readonly string[]\n ownedPaths?: readonly string[]\n}\n\nfunction isMissionBriefWire(value: unknown): value is MissionBriefWire {\n if (!isRecord(value) || !hasOnlyKeys(value, ['goal', 'constraints', 'doneCriteria', 'handoffNotes', 'ownedPaths'])) return false\n if (typeof value.goal !== 'string' || value.goal.trim().length === 0) return false\n for (const k of ['constraints', 'doneCriteria', 'handoffNotes', 'ownedPaths'] as const) {\n if (value[k] !== undefined && !isStringArray(value[k])) return false\n }\n return true\n}\n\nexport interface MissionUpsertRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** Omitted = create a new mission; present = update (must resolve to an existing mission — see mesh-missions.ts MISSION-UPSERT-SILENT-CREATE). */\n id?: string\n title: string\n /** Free text — see file-header note on why this is fine over local IPC. */\n goal?: string\n status?: MeshMissionStatusValue\n /**\n * H2: `undefined` = do not touch the stored brief. `null` = explicitly clear it.\n * A present object with no usable `goal` is treated by the daemon's own\n * `normalizeMissionBrief` as \"no brief\" (see mesh-missions.ts upsertMeshMission) —\n * this wire guard only checks SHAPE, not that decision.\n */\n brief?: MissionBriefWire | null\n}\n\nexport interface MeshMissionRecordWire {\n id: string\n meshId: string\n title: string\n goal: string\n status: MeshMissionStatusValue\n /** H2: absent = no brief attached to this mission. */\n brief?: MissionBriefWire\n}\n\nexport interface MissionUpsertResponse {\n mission: MeshMissionRecordWire\n}\n\nfunction isMeshMissionRecordWire(value: unknown): value is MeshMissionRecordWire {\n if (!isRecord(value) || !hasOnlyKeys(value, ['id', 'meshId', 'title', 'goal', 'status', 'brief'])) return false\n if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false\n if (typeof value.title !== 'string' || typeof value.goal !== 'string') return false\n if (!isMeshMissionStatusValue(value.status)) return false\n if (value.brief !== undefined && !isMissionBriefWire(value.brief)) return false\n return true\n}\n\nfunction isMissionUpsertRequest(value: unknown): value is MissionUpsertRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'id', 'title', 'goal', 'status', 'brief'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n if (value.id !== undefined && !isEvidenceIdentifier(value.id)) return false\n if (typeof value.title !== 'string' || value.title.trim().length === 0) return false\n if (value.goal !== undefined && typeof value.goal !== 'string') return false\n if (value.status !== undefined && !isMeshMissionStatusValue(value.status)) return false\n if (value.brief !== undefined && value.brief !== null && !isMissionBriefWire(value.brief)) return false\n return true\n}\n\nexport function decodeMissionUpsertRequest(value: unknown): MissionUpsertRequest | null {\n return isMissionUpsertRequest(value) ? value : null\n}\n\nexport function isMissionUpsertResponse(value: unknown): value is MissionUpsertResponse {\n return isRecord(value) && hasOnlyKeys(value, ['mission']) && isMeshMissionRecordWire(value.mission)\n}\n\nexport function decodeMissionUpsertResponse(value: unknown): MissionUpsertResponse | null {\n return isMissionUpsertResponse(value) ? value : null\n}\n\nexport interface MissionQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** Omitted = every status. */\n statuses?: readonly MeshMissionStatusValue[]\n /** Single-mission lookup (mesh-missions.ts `getMeshMission`'s shape) — mutually exclusive with `statuses`. */\n id?: string\n}\n\nexport interface MissionQueryResponse {\n missions: readonly MeshMissionRecordWire[]\n}\n\nfunction isMissionQueryRequest(value: unknown): value is MissionQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'statuses', 'id'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n if (value.id !== undefined && !isEvidenceIdentifier(value.id)) return false\n if (value.statuses !== undefined) {\n if (!Array.isArray(value.statuses) || value.statuses.length === 0) return false\n if (!value.statuses.every(isMeshMissionStatusValue)) return false\n }\n return true\n}\n\nexport function decodeMissionQueryRequest(value: unknown): MissionQueryRequest | null {\n return isMissionQueryRequest(value) ? value : null\n}\n\nfunction isMissionQueryResponse(value: unknown): value is MissionQueryResponse {\n return isRecord(value) && hasOnlyKeys(value, ['missions'])\n && Array.isArray(value.missions) && value.missions.every(isMeshMissionRecordWire)\n}\n\nexport function decodeMissionQueryResponse(value: unknown): MissionQueryResponse | null {\n return isMissionQueryResponse(value) ? value : null\n}\n\n// ─── mission_list_query ─────────────────────────────────────────────────────\n//\n// Wiring-unification Phase C, workstream C-W9b.\n//\n// `mesh-tools-mission.ts`'s own file-header note (2026-09-24, C-W6) flagged\n// this exact gap: `mission_query`'s landed response is `{missions:\n// MeshMissionRecordWire[]}` only — no `verbose`/`withStats`/\n// `limit`/`truncated`/`overflowIds`/`historyFold`, all of which\n// `listMeshMissionsForTool` (daemon-core `mesh-missions.ts`) computes for the\n// `mesh_mission_list` tool. Rather than widen `mission_query` itself (an\n// already-landed, already-tested contract other callers rely on for its\n// narrow shape), this is an ADDITIVE sibling command carrying\n// `listMeshMissionsForTool`'s full output shape — request/response fields\n// mirror its options/`MeshMissionListResult` one-for-one (see\n// mesh-missions.ts). `goal`/`goalPreview` are free text, same local-IPC\n// rationale as `mission_upsert`'s `goal` above.\n\nexport interface MissionListQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n statuses?: readonly MeshMissionStatusValue[]\n verbose?: boolean\n withStats?: boolean\n limit?: number\n historyIdLimit?: number\n /**\n * The mesh_status mission projection, computed in the daemon (the MCP no longer\n * opens the daemon's store for it): 'compact' = `getMeshStatusMissionsCompact`\n * (live missions goal-elided + folded history), 'verbose' =\n * `getMeshStatusMissionSummaries({verbose: true})` (live + capped history, full\n * goal, no stats — stats ride one batched `task_stats_query`). Rows then also\n * carry `createdAt`/`updatedAt`/`closeCandidateEmittedAt`. When set, every other\n * option except `historyIdLimit` is ignored. An older daemon rejects the key.\n */\n meshStatusView?: 'compact' | 'verbose'\n}\n\nexport interface MeshMissionTaskAggregateWire {\n total: number\n pending: number\n assigned: number\n completed: number\n failed: number\n cancelled: number\n blocked: number\n lastActivityAt: string | null\n}\n\nexport interface MeshMissionStatsWire {\n missionId: string\n taskCount: number\n completed: number\n failed: number\n totalDurationMs: number\n wallClockMs: number | null\n retries: number\n incompleteTaskIds: readonly string[]\n}\n\n/** Verbose (full-goal) mission row. `goal` present, `goalPreview`/`goalTruncated` absent. */\nexport interface MissionListSummaryVerboseWire {\n id: string\n meshId: string\n title: string\n goal: string\n status: MeshMissionStatusValue\n tasks: MeshMissionTaskAggregateWire\n stats?: MeshMissionStatsWire\n /** H2: absent = no brief attached. */\n brief?: MissionBriefWire\n /** `meshStatusView` rows only. */\n createdAt?: string\n updatedAt?: string\n closeCandidateEmittedAt?: string | null\n}\n\n/** Compact (default) mission row. `goalPreview`/`goalTruncated` present, `goal` absent. */\nexport interface MissionListSummarySlimWire {\n id: string\n meshId: string\n title: string\n goalPreview: string\n goalTruncated: boolean\n status: MeshMissionStatusValue\n tasks: MeshMissionTaskAggregateWire\n stats?: MeshMissionStatsWire\n /** H2: absent = no brief attached. */\n brief?: MissionBriefWire\n /** `meshStatusView` rows only. */\n createdAt?: string\n updatedAt?: string\n closeCandidateEmittedAt?: string | null\n}\n\nexport type MissionListSummaryWire = MissionListSummaryVerboseWire | MissionListSummarySlimWire\n\nexport interface MeshMissionHistoryFoldWire {\n count: number\n byStatus: Record<string, number>\n missionIds: readonly string[]\n note: string\n}\n\nexport interface MissionListQueryResponse {\n missions: readonly MissionListSummaryWire[]\n historyFold: MeshMissionHistoryFoldWire | null\n truncated: boolean\n matched: number\n overflowIds?: readonly string[]\n}\n\nfunction isMissionListQueryRequest(value: unknown): value is MissionListQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'statuses', 'verbose', 'withStats', 'limit', 'historyIdLimit', 'meshStatusView'])) return false\n if (value.meshStatusView !== undefined && value.meshStatusView !== 'compact' && value.meshStatusView !== 'verbose') return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n if (value.statuses !== undefined) {\n if (!Array.isArray(value.statuses) || value.statuses.length === 0) return false\n if (!value.statuses.every(isMeshMissionStatusValue)) return false\n }\n if (value.verbose !== undefined && typeof value.verbose !== 'boolean') return false\n if (value.withStats !== undefined && typeof value.withStats !== 'boolean') return false\n if (value.limit !== undefined && !isNonNegativeInt(value.limit)) return false\n if (value.historyIdLimit !== undefined && !isNonNegativeInt(value.historyIdLimit)) return false\n return true\n}\n\nexport function decodeMissionListQueryRequest(value: unknown): MissionListQueryRequest | null {\n return isMissionListQueryRequest(value) ? value : null\n}\n\nfunction isMeshMissionTaskAggregateWire(value: unknown): value is MeshMissionTaskAggregateWire {\n const keys = ['total', 'pending', 'assigned', 'completed', 'failed', 'cancelled', 'blocked', 'lastActivityAt'] as const\n if (!isRecord(value) || !hasOnlyKeys(value, keys)) return false\n for (const k of ['total', 'pending', 'assigned', 'completed', 'failed', 'cancelled', 'blocked'] as const) {\n if (!isNonNegativeInt(value[k])) return false\n }\n return value.lastActivityAt === null || typeof value.lastActivityAt === 'string'\n}\n\nfunction isMeshMissionStatsWire(value: unknown): value is MeshMissionStatsWire {\n const keys = ['missionId', 'taskCount', 'completed', 'failed', 'totalDurationMs', 'wallClockMs', 'retries', 'incompleteTaskIds'] as const\n if (!isRecord(value) || !hasOnlyKeys(value, keys)) return false\n if (!isEvidenceIdentifier(value.missionId)) return false\n for (const k of ['taskCount', 'completed', 'failed', 'totalDurationMs', 'retries'] as const) {\n if (!isNonNegativeInt(value[k])) return false\n }\n if (value.wallClockMs !== null && !isNonNegativeInt(value.wallClockMs)) return false\n if (!Array.isArray(value.incompleteTaskIds) || !value.incompleteTaskIds.every(isEvidenceIdentifier)) return false\n return true\n}\n\nfunction isMissionListSummaryWire(value: unknown): value is MissionListSummaryWire {\n if (!isRecord(value)) return false\n const hasGoal = 'goal' in value\n const hasPreview = 'goalPreview' in value && 'goalTruncated' in value\n if (hasGoal === hasPreview) return false // exactly one of the two shapes\n const baseKeys = ['id', 'meshId', 'title', 'status', 'tasks', 'stats', 'brief', 'createdAt', 'updatedAt', 'closeCandidateEmittedAt'] as const\n const allowed = hasGoal ? [...baseKeys, 'goal'] : [...baseKeys, 'goalPreview', 'goalTruncated']\n if (!hasOnlyKeys(value, allowed)) return false\n if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false\n if (typeof value.title !== 'string') return false\n if (!isMeshMissionStatusValue(value.status)) return false\n if (!isMeshMissionTaskAggregateWire(value.tasks)) return false\n if (value.stats !== undefined && !isMeshMissionStatsWire(value.stats)) return false\n if (value.brief !== undefined && !isMissionBriefWire(value.brief)) return false\n if (hasGoal && typeof value.goal !== 'string') return false\n if (hasPreview && (typeof value.goalPreview !== 'string' || typeof value.goalTruncated !== 'boolean')) return false\n if (value.createdAt !== undefined && typeof value.createdAt !== 'string') return false\n if (value.updatedAt !== undefined && typeof value.updatedAt !== 'string') return false\n if (value.closeCandidateEmittedAt !== undefined && value.closeCandidateEmittedAt !== null && typeof value.closeCandidateEmittedAt !== 'string') return false\n return true\n}\n\nfunction isMeshMissionHistoryFoldWire(value: unknown): value is MeshMissionHistoryFoldWire {\n if (!isRecord(value) || !hasOnlyKeys(value, ['count', 'byStatus', 'missionIds', 'note'])) return false\n if (!isNonNegativeInt(value.count)) return false\n if (!isRecord(value.byStatus) || !Object.values(value.byStatus).every((n) => isNonNegativeInt(n))) return false\n if (!Array.isArray(value.missionIds) || !value.missionIds.every(isEvidenceIdentifier)) return false\n return typeof value.note === 'string'\n}\n\nfunction isMissionListQueryResponse(value: unknown): value is MissionListQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['missions', 'historyFold', 'truncated', 'matched', 'overflowIds'])) return false\n if (!Array.isArray(value.missions) || !value.missions.every(isMissionListSummaryWire)) return false\n if (value.historyFold !== null && !isMeshMissionHistoryFoldWire(value.historyFold)) return false\n if (typeof value.truncated !== 'boolean') return false\n if (!isNonNegativeInt(value.matched)) return false\n if (value.overflowIds !== undefined && (!Array.isArray(value.overflowIds) || !value.overflowIds.every(isEvidenceIdentifier))) return false\n return true\n}\n\nexport function decodeMissionListQueryResponse(value: unknown): MissionListQueryResponse | null {\n return isMissionListQueryResponse(value) ? value : null\n}\n\n// ─── note_upsert / note_forget ──────────────────────────────────────────────\n//\n// Decision (2026-09-24, C-W6b; implemented C-W8): coordinator operating notes\n// get their own two local-IPC commands. A note's text is coordinator-authored\n// free text, so — exactly like mission_upsert's `goal` — it cannot ride\n// `mesh_record`'s scalar allow-list, and it never needs to: notes live in the\n// owning daemon's `mesh_operating_notes` table (local-only; never on\n// `mesh.<id>.events`). The same \"local IPC is inside the boundary\" rationale as\n// the mission commands above applies.\n\nexport const OPERATING_NOTE_CATEGORIES = ['provider_quirk', 'pattern_to_avoid', 'recovery_lesson'] as const\nexport type OperatingNoteCategory = typeof OPERATING_NOTE_CATEGORIES[number]\nconst isOperatingNoteCategory = makeGuard(OPERATING_NOTE_CATEGORIES)\n\nexport interface NoteUpsertRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** Free text (local IPC — see the section note). */\n text: string\n category?: OperatingNoteCategory\n pinned?: boolean\n /** Explicit expiry, ISO-8601. */\n expiresAt?: string\n /** Note id (or subject key) this note supersedes. */\n supersedes?: string\n subjectKey?: string\n /** Best-effort identity of the recording coordinator (session id / daemon id / host). */\n sourceCoordinator?: string\n}\n\nexport interface NoteUpsertResponse {\n noteId: string\n /** True when the same text was already among the recent live notes (no new note). */\n deduped: boolean\n createdAt: string\n}\n\nfunction isNoteUpsertRequest(value: unknown): value is NoteUpsertRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'text', 'category', 'pinned', 'expiresAt', 'supersedes', 'subjectKey', 'sourceCoordinator'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n if (typeof value.text !== 'string' || value.text.trim().length === 0) return false\n if (value.category !== undefined && !isOperatingNoteCategory(value.category)) return false\n if (value.pinned !== undefined && typeof value.pinned !== 'boolean') return false\n if (value.expiresAt !== undefined && (typeof value.expiresAt !== 'string' || Number.isNaN(Date.parse(value.expiresAt)))) return false\n return isOptionalShortString(value.supersedes) && isOptionalShortString(value.subjectKey) && isOptionalShortString(value.sourceCoordinator)\n}\n\nexport function decodeNoteUpsertRequest(value: unknown): NoteUpsertRequest | null {\n return isNoteUpsertRequest(value) ? value : null\n}\n\nfunction isNoteUpsertResponse(value: unknown): value is NoteUpsertResponse {\n return isRecord(value) && hasOnlyKeys(value, ['noteId', 'deduped', 'createdAt'])\n && isEvidenceIdentifier(value.noteId) && typeof value.deduped === 'boolean' && typeof value.createdAt === 'string'\n}\n\nexport function decodeNoteUpsertResponse(value: unknown): NoteUpsertResponse | null {\n return isNoteUpsertResponse(value) ? value : null\n}\n\nexport interface NoteForgetRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** At least one of `noteId` / `text` (a text forget retracts every note with that exact text, and any recorded later). */\n noteId?: string\n text?: string\n reason?: string\n}\n\nexport interface NoteForgetResponse {\n /** Live notes this forget hid. */\n matched: number\n tombstoneId: string\n}\n\nfunction isNoteForgetRequest(value: unknown): value is NoteForgetRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'noteId', 'text', 'reason'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n if (value.noteId !== undefined && !isEvidenceIdentifier(value.noteId)) return false\n if (value.text !== undefined && (typeof value.text !== 'string' || value.text.trim().length === 0)) return false\n if (value.noteId === undefined && value.text === undefined) return false\n return value.reason === undefined || typeof value.reason === 'string'\n}\n\nexport function decodeNoteForgetRequest(value: unknown): NoteForgetRequest | null {\n return isNoteForgetRequest(value) ? value : null\n}\n\nfunction isNoteForgetResponse(value: unknown): value is NoteForgetResponse {\n return isRecord(value) && hasOnlyKeys(value, ['matched', 'tombstoneId'])\n && typeof value.matched === 'number' && Number.isInteger(value.matched) && value.matched >= 0\n && isEvidenceIdentifier(value.tombstoneId)\n}\n\nexport function decodeNoteForgetResponse(value: unknown): NoteForgetResponse | null {\n return isNoteForgetResponse(value) ? value : null\n}\n\n// ─── tool_call_record ───────────────────────────────────────────────────────\n//\n// Wiring-unification Phase C, workstream C-W9b\n// (docs/design/2026-09-23-wiring-unification.md §5 C2 \"MCP server\" paragraph,\n// 2026-09-24 14:00 stamp \"C-W9\").\n//\n// Replaces `recordMeshToolCall`/`recordMeshCoordinatorToolCall`\n// (`daemon-core/src/mesh/mesh-direct-dispatch.ts`) — an in-process,\n// per-mesh-tool-call rate-limit/advisory bump mcp-server called directly\n// against its own store handle. Every field is an identifier, a closed enum,\n// a boolean or a counter — squarely inside `mesh_record`'s content boundary,\n// but this is its own command (not a `mesh_record` payload) because it is a\n// COUNTER MUTATION with a computed return value (`rateLimitExceeded`,\n// `callsInWindow`, `advisory`), not an append-only scalar record.\n\nexport const TOOL_CALLER_ROLES = ['coordinator', 'unknown'] as const\nexport type ToolCallerRole = typeof TOOL_CALLER_ROLES[number]\nconst isToolCallerRole = makeGuard(TOOL_CALLER_ROLES)\n\nexport interface ToolCallRecordRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** The mesh tool name, e.g. `mesh_status` (identifier, not free text — always a fixed tool-name string). */\n tool: string\n sessionId?: string\n callerRole: ToolCallerRole\n}\n\nexport interface ToolCallRecordResponse {\n rateLimitExceeded: boolean\n callsInWindow: number\n /** Short machine-oriented advisory string, or null. Never free text describing content. */\n advisory: string | null\n}\n\nfunction isToolCallRecordRequest(value: unknown): value is ToolCallRecordRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'tool', 'sessionId', 'callerRole'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isEvidenceIdentifier(value.meshId)\n && isEvidenceIdentifier(value.tool)\n && isOptionalId(value.sessionId)\n && isToolCallerRole(value.callerRole)\n}\n\nexport function decodeToolCallRecordRequest(value: unknown): ToolCallRecordRequest | null {\n return isToolCallRecordRequest(value) ? value : null\n}\n\nfunction isToolCallRecordResponse(value: unknown): value is ToolCallRecordResponse {\n return isRecord(value) && hasOnlyKeys(value, ['rateLimitExceeded', 'callsInWindow', 'advisory'])\n && typeof value.rateLimitExceeded === 'boolean'\n && isNonNegativeInt(value.callsInWindow)\n && (value.advisory === null || typeof value.advisory === 'string')\n}\n\nexport function decodeToolCallRecordResponse(value: unknown): ToolCallRecordResponse | null {\n return isToolCallRecordResponse(value) ? value : null\n}\n\n// ─── ledger_query ───────────────────────────────────────────────────────────\n//\n// Wiring-unification Phase C, workstream C-W9b.\n//\n// Replaces the remaining bare `readLedgerEntries(meshId, opts)` /\n// `getLedgerSummary(meshId)` in-process reads that `turn_query` cannot serve\n// (§5 C2's `mesh-tools-mission.ts` file-header note, 2026-09-24: \"general\n// ledger browsing by arbitrary `kind`/`since`/`node` filters —\n// `turn_query`'s shape... has no free-form kind-list or node filter, so this\n// is a real API mismatch, not a mechanical rename\"). `turn_query` stays\n// scoped to the turn-ledger's own attempt/event rows; `ledger_query` is the\n// general record browse surface (C-W9a: the daemon's `mesh_local_records` plus\n// the turn ledger's task outcomes, `readLocalRecords`) `meshTaskHistory` /\n// `meshLedgerQuery` need.\n//\n// CONTENT BOUNDARY: `MeshLedgerEntry.payload` (daemon-core `mesh-ledger.ts`)\n// is `Record<string, unknown>` — genuinely unbounded JSON (a graph plan, a free-text checkpoint message), NOT constrained to\n// `mesh_record`'s scalar allow-list. This is fine for the SAME reason\n// `mission_upsert`'s `goal` and `note_upsert`'s `text` are fine (see that\n// section's note above): this is local IPC between mcp-server and the\n// daemon that owns the ledger, both on the operator's own machine — never a\n// cross-machine or server hop. `entryPayload` below is therefore an\n// intentionally-unvalidated `Record<string, unknown>` passthrough, exactly\n// like `MissionUpsertRequest.goal` is unvalidated free text.\n\nexport interface LedgerQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** One or more ledger `kind` strings (daemon-core `MeshLedgerKind`; mesh-shared cannot import that union, so these are identifiers here). Omitted = every kind. */\n kind?: readonly string[]\n /** ISO-8601 or epoch-ms-as-string — passed through to `readLedgerEntries`'s `since` (parsed via `new Date()`). */\n since?: string\n /** Filter to entries whose nodeId is equivalent to this daemon id (matched via `daemonIdsEquivalent` daemon-side, not raw `===`). */\n node?: string\n tail?: number\n /** Also return `getLedgerSummary(meshId)` alongside the entries — saves a second round trip for callers that want both (the common case: every existing call site fetches both together). */\n includeSummary?: boolean\n}\n\nexport interface LedgerQueryEntryWire {\n id: string\n meshId: string\n timestamp: string\n kind: string\n nodeId?: string\n sessionId?: string\n providerType?: string\n taskId?: string\n /** Unbounded JSON passthrough — see file section's CONTENT BOUNDARY note. */\n payload: Record<string, unknown>\n}\n\nexport interface LedgerQuerySummaryWire {\n meshId: string\n totalEntries: number\n taskDispatched: number\n taskCompleted: number\n taskFailed: number\n taskStalled: number\n sessionLaunched: number\n checkpointCreated: number\n lastActivityAt: string | null\n recentFailures: number\n}\n\nexport interface LedgerQueryResponse {\n entries: readonly LedgerQueryEntryWire[]\n summary?: LedgerQuerySummaryWire\n}\n\nfunction isLedgerQueryRequest(value: unknown): value is LedgerQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'kind', 'since', 'node', 'tail', 'includeSummary'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n if (value.kind !== undefined && (!Array.isArray(value.kind) || value.kind.length === 0 || !value.kind.every(isEvidenceIdentifier))) return false\n if (value.since !== undefined && typeof value.since !== 'string') return false\n if (!isOptionalId(value.node)) return false\n if (value.tail !== undefined && !isNonNegativeInt(value.tail)) return false\n if (value.includeSummary !== undefined && typeof value.includeSummary !== 'boolean') return false\n return true\n}\n\nexport function decodeLedgerQueryRequest(value: unknown): LedgerQueryRequest | null {\n return isLedgerQueryRequest(value) ? value : null\n}\n\nconst LEDGER_QUERY_ENTRY_KEYS = ['id', 'meshId', 'timestamp', 'kind', 'nodeId', 'sessionId', 'providerType', 'taskId', 'payload'] as const\n\nfunction isLedgerQueryEntryWire(value: unknown): value is LedgerQueryEntryWire {\n if (!isRecord(value) || !hasOnlyKeys(value, LEDGER_QUERY_ENTRY_KEYS)) return false\n if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false\n if (typeof value.timestamp !== 'string' || typeof value.kind !== 'string') return false\n if (!isOptionalId(value.nodeId) || !isOptionalId(value.sessionId) || !isOptionalId(value.providerType) || !isOptionalId(value.taskId)) return false\n if (!isRecord(value.payload)) return false\n return true\n}\n\nfunction isLedgerQuerySummaryWire(value: unknown): value is LedgerQuerySummaryWire {\n const keys = ['meshId', 'totalEntries', 'taskDispatched', 'taskCompleted', 'taskFailed', 'taskStalled', 'sessionLaunched', 'checkpointCreated', 'lastActivityAt', 'recentFailures'] as const\n if (!isRecord(value) || !hasOnlyKeys(value, keys)) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n for (const k of ['totalEntries', 'taskDispatched', 'taskCompleted', 'taskFailed', 'taskStalled', 'sessionLaunched', 'checkpointCreated', 'recentFailures'] as const) {\n if (!isNonNegativeInt(value[k])) return false\n }\n if (value.lastActivityAt !== null && typeof value.lastActivityAt !== 'string') return false\n return true\n}\n\nfunction isLedgerQueryResponse(value: unknown): value is LedgerQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['entries', 'summary'])) return false\n if (!Array.isArray(value.entries) || !value.entries.every(isLedgerQueryEntryWire)) return false\n if (value.summary !== undefined && !isLedgerQuerySummaryWire(value.summary)) return false\n return true\n}\n\nexport function decodeLedgerQueryResponse(value: unknown): LedgerQueryResponse | null {\n return isLedgerQueryResponse(value) ? value : null\n}\n","/**\n * turn-ipc — local records, queue composites and active work (C-W9a):\n * record_local, queue_query, queue_enqueue, queue_enqueue_batch, queue_cancel,\n * queue_requeue, direct_dispatch_record, active_work_query,\n * recovery_context_query. Part of the turn-ipc wire contract (./turn-ipc.ts).\n */\n\n// ─── C-W9a: local records, queue composites, active work ────────────────────\n//\n// Wiring-unification Phase C, workstream C-W9a (the 2026-09-24 14:00 stamp\n// \"Left for C-W9\"): the event ledger and its JSONL mirror are gone, and every\n// mcp-server call that still reached the daemon's `mesh-runtime.db` in-process\n// — record appends, queue mutations, the queue/active-work reads that fed\n// `buildMeshActiveWork`, recovery hints — moves behind the commands below,\n// executed in the daemon that owns the store.\n//\n// CONTENT BOUNDARY: like `mission_upsert`'s `goal`, `note_upsert`'s `text` and\n// `ledger_query`'s entry payloads, several fields here are free text or\n// unbounded JSON (a task message, a queue row with its\n// message, an active-work record with its task summary). This is fine for the\n// same reason: local IPC between the mcp-server and the daemon on the\n// operator's own machine — never a cross-machine or server hop. Those fields\n// are documented as passthroughs and validated only for shape (object/array),\n// exactly like `LedgerQueryEntryWire.payload`. Nothing here is ever published\n// to a topic: `record_local`'s topic leg is the daemon's `mesh.record`\n// allow-list projection, which drops free text by construction.\n\nimport { isRecord } from './protocol/envelope';\nimport { isEvidenceIdentifier } from './turn-evidence';\nimport {\n TURN_IPC_PROTOCOL_VERSION,\n hasOnlyKeys,\n isOptionalId,\n isNonNegativeInt,\n isOptionalBoolean,\n isOptionalRecord,\n isRecordArray,\n isOptionalString,\n} from './turn-ipc-guards';\n\n/** A queue row as the daemon's `getQueue` returns it — a JSON passthrough (see the section note). */\nexport type QueueEntryWire = Record<string, unknown> & { id: string; status: string }\n\nfunction isQueueEntryWire(value: unknown): value is QueueEntryWire {\n return isRecord(value) && isEvidenceIdentifier(value.id) && typeof value.status === 'string'\n}\n\n// ── record_local ──\n//\n// `meshRecord(meshId, kind, scalars, { local: true })` over IPC: the scalar\n// projection goes to `mesh.<id>.events` (content-free), the FULL payload lands\n// in the daemon's `mesh_local_records` (local-only). Replaces every mcp-server\n// `appendLedgerEntry` (dispatch / checkpoint message /\n// reconcile records). `payload` is free-form JSON (see the section note).\n\nexport interface RecordLocalRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** A `MeshLedgerKind` (daemon-core); an identifier here (mesh-shared cannot import that union). */\n kind: string\n nodeId?: string\n sessionId?: string\n providerType?: string\n taskId?: string\n payload: Record<string, unknown>\n}\n\nexport interface RecordLocalResponse {\n eventId: string\n timestamp: string\n storedLocally: boolean\n published: boolean\n}\n\nfunction isRecordLocalRequest(value: unknown): value is RecordLocalRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'kind', 'nodeId', 'sessionId', 'providerType', 'taskId', 'payload'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isEvidenceIdentifier(value.meshId)\n && isEvidenceIdentifier(value.kind)\n && isOptionalId(value.nodeId) && isOptionalId(value.sessionId) && isOptionalId(value.providerType) && isOptionalId(value.taskId)\n && isRecord(value.payload)\n}\n\nexport function decodeRecordLocalRequest(value: unknown): RecordLocalRequest | null {\n return isRecordLocalRequest(value) ? value : null\n}\n\nfunction isRecordLocalResponse(value: unknown): value is RecordLocalResponse {\n return isRecord(value) && hasOnlyKeys(value, ['eventId', 'timestamp', 'storedLocally', 'published'])\n && isEvidenceIdentifier(value.eventId) && typeof value.timestamp === 'string'\n && typeof value.storedLocally === 'boolean' && typeof value.published === 'boolean'\n}\n\nexport function decodeRecordLocalResponse(value: unknown): RecordLocalResponse | null {\n return isRecordLocalResponse(value) ? value : null\n}\n\n// ── queue_query ──\n\nexport interface QueueQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** Status filter (queue statuses); omitted = every row. */\n statuses?: readonly string[]\n /** One row by id (returns 0 or 1 entries). */\n taskId?: string\n /** Project for a VIEW surface: the persisted input envelope → `inputSummary` (summarizeQueueEntryInputForView). */\n view?: boolean\n /**\n * Also return the per-status row counts of the WHOLE mesh queue (columns only,\n * no payload parse) — lets a view read only the rows it shows yet report\n * mesh-wide counts. An older daemon rejects the key.\n */\n withCounts?: boolean\n /** With `withCounts`: also count terminal rows whose `updated_at` is older than this age. */\n historicalOlderThanMs?: number\n /**\n * Also return `dependencyHeads`: id/status/cancelReason of every\n * row the returned entries list in `dependsOn` that is not itself returned —\n * enough to annotate dependency state without reading the whole queue.\n */\n withDependencyHeads?: boolean\n}\n\n/** A dependency row reduced to the fields dependency-state annotation reads. */\nexport interface QueueDependencyHeadWire {\n id: string\n status: string\n cancelReason?: string\n}\n\nexport interface QueueQueryResponse {\n entries: readonly QueueEntryWire[]\n /** `withCounts`: row count per status over the whole mesh queue. */\n counts?: Record<string, number>\n /** `withCounts` + `historicalOlderThanMs`: terminal rows older than that age. */\n oldHistoricalCount?: number\n /** `withDependencyHeads`. */\n dependencyHeads?: readonly QueueDependencyHeadWire[]\n}\n\nfunction isQueueQueryRequest(value: unknown): value is QueueQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'statuses', 'taskId', 'view', 'withCounts', 'historicalOlderThanMs', 'withDependencyHeads'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId)) return false\n if (value.statuses !== undefined && (!Array.isArray(value.statuses) || !value.statuses.every(isEvidenceIdentifier))) return false\n if (value.historicalOlderThanMs !== undefined && !isNonNegativeInt(value.historicalOlderThanMs)) return false\n return isOptionalId(value.taskId) && isOptionalBoolean(value.view)\n && isOptionalBoolean(value.withCounts) && isOptionalBoolean(value.withDependencyHeads)\n}\n\nexport function decodeQueueQueryRequest(value: unknown): QueueQueryRequest | null {\n return isQueueQueryRequest(value) ? value : null\n}\n\nfunction isQueueDependencyHeadWire(value: unknown): value is QueueDependencyHeadWire {\n return isRecord(value) && hasOnlyKeys(value, ['id', 'status', 'cancelReason'])\n && typeof value.id === 'string' && typeof value.status === 'string'\n && (value.cancelReason === undefined || typeof value.cancelReason === 'string')\n}\n\nfunction isQueueQueryResponse(value: unknown): value is QueueQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['entries', 'counts', 'oldHistoricalCount', 'dependencyHeads'])) return false\n if (!Array.isArray(value.entries) || !value.entries.every(isQueueEntryWire)) return false\n if (value.counts !== undefined && (!isRecord(value.counts) || !Object.values(value.counts).every(isNonNegativeInt))) return false\n if (value.oldHistoricalCount !== undefined && !isNonNegativeInt(value.oldHistoricalCount)) return false\n if (value.dependencyHeads !== undefined && (!Array.isArray(value.dependencyHeads) || !value.dependencyHeads.every(isQueueDependencyHeadWire))) return false\n return true\n}\n\nexport function decodeQueueQueryResponse(value: unknown): QueueQueryResponse | null {\n return isQueueQueryResponse(value) ? value : null\n}\n\n// ── queue_enqueue ──\n//\n// `enqueueTask(meshId, message, options)` in the daemon. `options` is\n// `MeshEnqueueTaskOptions` (daemon-core) as a JSON\n// passthrough; the daemon's enqueue guards (message, task-mode, difficulty,\n// dependency cycle) run unchanged and a refusal comes back as the error.\n\nexport interface QueueEnqueueRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** Free text (the task message — see the section note). */\n message: string\n options?: Record<string, unknown>\n}\n\nexport interface QueueEnqueueResponse {\n entry: QueueEntryWire\n}\n\nfunction isQueueEnqueueRequest(value: unknown): value is QueueEnqueueRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'message', 'options'])\n && value.v === TURN_IPC_PROTOCOL_VERSION && isEvidenceIdentifier(value.meshId)\n && typeof value.message === 'string'\n && isOptionalRecord(value.options)\n}\n\nexport function decodeQueueEnqueueRequest(value: unknown): QueueEnqueueRequest | null {\n return isQueueEnqueueRequest(value) ? value : null\n}\n\nfunction isQueueEnqueueResponse(value: unknown): value is QueueEnqueueResponse {\n return isRecord(value) && hasOnlyKeys(value, ['entry']) && isQueueEntryWire(value.entry)\n}\n\nexport function decodeQueueEnqueueResponse(value: unknown): QueueEnqueueResponse | null {\n return isQueueEnqueueResponse(value) ? value : null\n}\n\n// ── queue_enqueue_batch ──\n//\n// The atomic multi-task enqueue in the daemon: `enqueueTaskBatch(meshId, specs)`\n// — every task inserts or none does. A refusal answers\n// `{ ok: false, refusalCode?, message, extra? }` (a domain refusal is a RESULT\n// here, not a transport error, so the caller keeps its code/extra for the tool\n// response). NOT `code`/`error`: those two keys belong to the command envelope\n// (`{ success, error, code }`) the client unwraps, so a result must never\n// reuse them.\n\nexport interface QueueEnqueueBatchRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** `MeshTaskBatchEntrySpec[]` (daemon-core, JSON passthrough). */\n specs: readonly Record<string, unknown>[]\n}\n\nexport type QueueEnqueueBatchResponse =\n | { ok: true; tasks: readonly QueueEntryWire[] }\n | { ok: false; refusalCode?: string; message: string; extra?: Record<string, unknown> }\n\nfunction isQueueEnqueueBatchRequest(value: unknown): value is QueueEnqueueBatchRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'specs'])\n && value.v === TURN_IPC_PROTOCOL_VERSION && isEvidenceIdentifier(value.meshId)\n && isRecordArray(value.specs)\n}\n\nexport function decodeQueueEnqueueBatchRequest(value: unknown): QueueEnqueueBatchRequest | null {\n return isQueueEnqueueBatchRequest(value) ? value : null\n}\n\nfunction isQueueEnqueueBatchResponse(value: unknown): value is QueueEnqueueBatchResponse {\n if (!isRecord(value)) return false\n if (value.ok === true) {\n return hasOnlyKeys(value, ['ok', 'tasks']) && Array.isArray(value.tasks) && value.tasks.every(isQueueEntryWire)\n }\n if (value.ok === false) {\n return hasOnlyKeys(value, ['ok', 'refusalCode', 'message', 'extra']) && typeof value.message === 'string'\n && isOptionalString(value.refusalCode) && isOptionalRecord(value.extra)\n }\n return false\n}\n\nexport function decodeQueueEnqueueBatchResponse(value: unknown): QueueEnqueueBatchResponse | null {\n return isQueueEnqueueBatchResponse(value) ? value : null\n}\n\n// ── queue_cancel ──\n\nexport interface QueueCancelRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n taskId: string\n /** Operator reason (free text, local IPC). */\n reason?: string\n}\n\nexport interface QueueCancelResponse {\n /** The cancelled row, or null when no such task. */\n task: QueueEntryWire | null\n /** The row as it was BEFORE the cancel (its assignment is what a caller stops). */\n before: QueueEntryWire | null\n}\n\nfunction isQueueCancelRequest(value: unknown): value is QueueCancelRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'taskId', 'reason'])\n && value.v === TURN_IPC_PROTOCOL_VERSION && isEvidenceIdentifier(value.meshId) && isEvidenceIdentifier(value.taskId)\n && isOptionalString(value.reason)\n}\n\nexport function decodeQueueCancelRequest(value: unknown): QueueCancelRequest | null {\n return isQueueCancelRequest(value) ? value : null\n}\n\nfunction isQueueCancelResponse(value: unknown): value is QueueCancelResponse {\n return isRecord(value) && hasOnlyKeys(value, ['task', 'before'])\n && (value.task === null || isQueueEntryWire(value.task))\n && (value.before === null || isQueueEntryWire(value.before))\n}\n\nexport function decodeQueueCancelResponse(value: unknown): QueueCancelResponse | null {\n return isQueueCancelResponse(value) ? value : null\n}\n\n// ── queue_requeue ──\n\nexport interface QueueRequeueRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n taskId: string\n /** `requeueTask` options (reason / targetNodeId / targetSessionId / clear* / force / message / maxRetries / notBefore), JSON passthrough. */\n options?: Record<string, unknown>\n}\n\nexport interface QueueRequeueResponse {\n task: QueueEntryWire | null\n}\n\nfunction isQueueRequeueRequest(value: unknown): value is QueueRequeueRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'taskId', 'options'])\n && value.v === TURN_IPC_PROTOCOL_VERSION && isEvidenceIdentifier(value.meshId) && isEvidenceIdentifier(value.taskId)\n && isOptionalRecord(value.options)\n}\n\nexport function decodeQueueRequeueRequest(value: unknown): QueueRequeueRequest | null {\n return isQueueRequeueRequest(value) ? value : null\n}\n\nfunction isQueueRequeueResponse(value: unknown): value is QueueRequeueResponse {\n return isRecord(value) && hasOnlyKeys(value, ['task']) && (value.task === null || isQueueEntryWire(value.task))\n}\n\nexport function decodeQueueRequeueResponse(value: unknown): QueueRequeueResponse | null {\n return isQueueRequeueResponse(value) ? value : null\n}\n\n// ── direct_dispatch_record ──\n//\n// The post-dispatch bookkeeping of `mesh_send_task`'s direct arms, in the\n// daemon: `recordDirectDispatchTask` (materialise the queue row, stamped with\n// the already-open `mesh_direct` attempt). Best-effort and reported — a\n// dispatch that already happened must never fail on its bookkeeping.\n\nexport interface DirectDispatchRecordRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n taskId: string\n /** Free text (the authored task message — the materialised row keeps it). */\n message: string\n /** `recordDirectDispatchTask` options minus `id` (JSON passthrough). */\n task?: Record<string, unknown>\n}\n\nexport interface DirectDispatchRecordResponse {\n taskRecorded: boolean\n}\n\nfunction isDirectDispatchRecordRequest(value: unknown): value is DirectDispatchRecordRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'taskId', 'message', 'task'])\n && value.v === TURN_IPC_PROTOCOL_VERSION && isEvidenceIdentifier(value.meshId) && isEvidenceIdentifier(value.taskId)\n && typeof value.message === 'string' && isOptionalRecord(value.task)\n}\n\nexport function decodeDirectDispatchRecordRequest(value: unknown): DirectDispatchRecordRequest | null {\n return isDirectDispatchRecordRequest(value) ? value : null\n}\n\nfunction isDirectDispatchRecordResponse(value: unknown): value is DirectDispatchRecordResponse {\n return isRecord(value) && hasOnlyKeys(value, ['taskRecorded'])\n && typeof value.taskRecorded === 'boolean'\n}\n\nexport function decodeDirectDispatchRecordResponse(value: unknown): DirectDispatchRecordResponse | null {\n return isDirectDispatchRecordResponse(value) ? value : null\n}\n\n// ── active_work_query ──\n//\n// The active-work view, COMPUTED in the daemon: it reads the queue, the open\n// direct dispatches (`mesh_direct` attempts) and its local records (+ turn\n// outcomes), and runs `buildMeshActiveWork` over them with the caller's live\n// node probe results. `includeInputs` also returns the records + dispatches it\n// used (the transcript-reconcile pass and the stale-direct prune read them);\n// `compute: false` returns only those inputs. `includeSchedulingRuntime` adds\n// `buildMeshSchedulingRuntime(mesh, queue)` for the caller's `mesh` snapshot.\n// `queue` lets a caller substitute its own annotated queue view.\n\nexport interface ActiveWorkQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** Live node probe results (`buildMeshActiveWork`'s `nodes`), JSON passthrough. */\n nodes?: readonly Record<string, unknown>[]\n /** Substitute queue rows (default: the daemon's `getQueue`). */\n queue?: readonly Record<string, unknown>[]\n /** Record tail fed to active work (default 200). */\n recordTail?: number\n includeTerminalDirect?: boolean\n /** Default true. */\n compute?: boolean\n includeInputs?: boolean\n includeSummary?: boolean\n includeSchedulingRuntime?: boolean\n /**\n * The caller's mesh snapshot for the scheduling runtime, JSON passthrough.\n * Optional since the daemon resolves its own mesh record when it is absent;\n * an older daemon rejects `includeSchedulingRuntime` without it (the caller's\n * feature-detect signal to resend with the mesh).\n */\n mesh?: Record<string, unknown>\n}\n\nexport interface ActiveWorkQueryResponse {\n /** `MeshActiveWorkEvidence` (daemon-core), JSON passthrough; absent when `compute: false`. */\n activeWork?: Record<string, unknown>\n records?: readonly Record<string, unknown>[]\n directDispatches?: readonly Record<string, unknown>[]\n /** `MeshLedgerSummary`-shaped record summary. */\n summary?: Record<string, unknown>\n schedulingRuntime?: Record<string, unknown>\n}\n\nfunction isActiveWorkQueryRequest(value: unknown): value is ActiveWorkQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'nodes', 'queue', 'recordTail', 'includeTerminalDirect', 'compute', 'includeInputs', 'includeSummary', 'includeSchedulingRuntime', 'mesh'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId)) return false\n if (value.nodes !== undefined && !isRecordArray(value.nodes)) return false\n if (value.queue !== undefined && !isRecordArray(value.queue)) return false\n if (value.recordTail !== undefined && !isNonNegativeInt(value.recordTail)) return false\n return isOptionalBoolean(value.includeTerminalDirect) && isOptionalBoolean(value.compute) && isOptionalBoolean(value.includeInputs)\n && isOptionalBoolean(value.includeSummary) && isOptionalBoolean(value.includeSchedulingRuntime) && isOptionalRecord(value.mesh)\n}\n\nexport function decodeActiveWorkQueryRequest(value: unknown): ActiveWorkQueryRequest | null {\n return isActiveWorkQueryRequest(value) ? value : null\n}\n\nfunction isActiveWorkQueryResponse(value: unknown): value is ActiveWorkQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['activeWork', 'records', 'directDispatches', 'summary', 'schedulingRuntime'])) return false\n if (value.records !== undefined && !isRecordArray(value.records)) return false\n if (value.directDispatches !== undefined && !isRecordArray(value.directDispatches)) return false\n return isOptionalRecord(value.activeWork) && isOptionalRecord(value.summary) && isOptionalRecord(value.schedulingRuntime)\n}\n\nexport function decodeActiveWorkQueryResponse(value: unknown): ActiveWorkQueryResponse | null {\n return isActiveWorkQueryResponse(value) ? value : null\n}\n\n// ── recovery_context_query ──\n//\n// `getSessionRecoveryContext` (daemon-core `mesh-local-records.ts`) in the\n// daemon. `lastTaskMessage` / `advice` are free text (local IPC).\n\nexport interface RecoveryContextQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n nodeId?: string\n sessionId?: string\n maxRetries?: number\n /**\n * Batch: one context per node id, computed over ONE record read (answers\n * `contexts`). Exclusive with `nodeId`/`sessionId`. An older daemon rejects it.\n */\n nodeIds?: readonly string[]\n}\n\nexport interface RecoveryContextQueryResponse {\n /** Single mode (nodeId/sessionId). */\n context?: Record<string, unknown>\n /** Batch mode (`nodeIds`): context per node id. */\n contexts?: Record<string, Record<string, unknown>>\n}\n\nfunction isRecoveryContextQueryRequest(value: unknown): value is RecoveryContextQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'nodeId', 'sessionId', 'maxRetries', 'nodeIds'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId)) return false\n if (!isOptionalId(value.nodeId) || !isOptionalId(value.sessionId)) return false\n if (value.maxRetries !== undefined && !isNonNegativeInt(value.maxRetries)) return false\n if (value.nodeIds !== undefined) {\n if (!Array.isArray(value.nodeIds) || value.nodeIds.length === 0 || !value.nodeIds.every(isEvidenceIdentifier)) return false\n return value.nodeId === undefined && value.sessionId === undefined\n }\n return value.nodeId !== undefined || value.sessionId !== undefined\n}\n\nexport function decodeRecoveryContextQueryRequest(value: unknown): RecoveryContextQueryRequest | null {\n return isRecoveryContextQueryRequest(value) ? value : null\n}\n\nfunction isRecoveryContextWire(value: unknown): boolean {\n return isRecord(value) && typeof value.consecutiveNodeFailures === 'number'\n}\n\nfunction isRecoveryContextQueryResponse(value: unknown): value is RecoveryContextQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['context', 'contexts'])) return false\n if (value.context === undefined && value.contexts === undefined) return false\n if (value.context !== undefined && !isRecoveryContextWire(value.context)) return false\n if (value.contexts !== undefined && (!isRecord(value.contexts) || !Object.values(value.contexts).every(isRecoveryContextWire))) return false\n return true\n}\n\nexport function decodeRecoveryContextQueryResponse(value: unknown): RecoveryContextQueryResponse | null {\n return isRecoveryContextQueryResponse(value) ? value : null\n}\n","/**\n * turn-ipc — task stats and maintenance commands: task_stats_query,\n * prune_stale_direct, orphaned_pin_notify. Part of the turn-ipc wire contract\n * (./turn-ipc.ts).\n */\n\nimport {\n TURN_IPC_PROTOCOL_VERSION,\n hasOnlyKeys,\n isOptionalBoolean,\n isOptionalRecord,\n isNonNegativeInt,\n isRecordArray,\n} from './turn-ipc-guards';\nimport { isRecord } from './protocol/envelope';\nimport { isEvidenceIdentifier } from './turn-evidence';\n\n// ─── task_stats_query ───────────────────────────────────────────────────────\n//\n// C-W9c: replaces the in-process `computeMeshTaskStats` / `computeMeshMissionStats`\n// (daemon-core `mesh-task-stats.ts`) — both scan the daemon's queue + local\n// records, so both move behind one command. Exactly one of `taskIds` /\n// `missionId` selects the per-task mode; `missionId` alone with `rollup: true`\n// additionally returns the mission-level aggregate.\n\nexport interface TaskStatsQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n taskIds?: readonly string[]\n missionId?: string\n tail?: number\n /** Also compute `computeMeshMissionStats` — requires `missionId`. */\n rollup?: boolean\n /**\n * Batch rollups: `computeMeshMissionStats` for every id, over ONE queue read and\n * ONE record read (answers `missions`, `tasks` empty). Exclusive with\n * `taskIds`/`missionId`. An older daemon rejects the key.\n */\n missionIds?: readonly string[]\n}\n\nexport interface TaskStatsQueryResponse {\n /** `MeshTaskStats[]`, JSON passthrough. */\n tasks: readonly Record<string, unknown>[]\n /** `MeshMissionStats`, JSON passthrough; present only when `rollup: true` was requested and satisfiable. */\n mission?: Record<string, unknown>\n /** Batch mode: `MeshMissionStats` per requested mission id, JSON passthrough. */\n missions?: Record<string, Record<string, unknown>>\n}\n\nfunction isTaskStatsQueryRequest(value: unknown): value is TaskStatsQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'taskIds', 'missionId', 'tail', 'rollup', 'missionIds'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId)) return false\n if (value.taskIds !== undefined) {\n if (!Array.isArray(value.taskIds) || value.taskIds.length === 0 || !value.taskIds.every(isEvidenceIdentifier)) return false\n }\n if (value.missionId !== undefined && !isEvidenceIdentifier(value.missionId)) return false\n if (value.tail !== undefined && !isNonNegativeInt(value.tail)) return false\n if (value.missionIds !== undefined) {\n if (!Array.isArray(value.missionIds) || value.missionIds.length === 0 || !value.missionIds.every(isEvidenceIdentifier)) return false\n if (value.taskIds !== undefined || value.missionId !== undefined) return false\n }\n if (value.rollup === true && value.missionId === undefined) return false\n return isOptionalBoolean(value.rollup)\n}\n\nexport function decodeTaskStatsQueryRequest(value: unknown): TaskStatsQueryRequest | null {\n return isTaskStatsQueryRequest(value) ? value : null\n}\n\nfunction isTaskStatsQueryResponse(value: unknown): value is TaskStatsQueryResponse {\n return isRecord(value) && hasOnlyKeys(value, ['tasks', 'mission', 'missions']) && isRecordArray(value.tasks) && isOptionalRecord(value.mission)\n && (value.missions === undefined || (isRecord(value.missions) && Object.values(value.missions).every(isRecord)))\n}\n\nexport function decodeTaskStatsQueryResponse(value: unknown): TaskStatsQueryResponse | null {\n return isTaskStatsQueryResponse(value) ? value : null\n}\n\n// ─── prune_stale_direct ─────────────────────────────────────────────────────\n//\n// C-W9c: replaces the in-process `pruneStaleDirectDispatches` call\n// (`mesh_cleanup_sessions` mode=prune_stale_direct, `mesh-tools-session.ts`). Unlike the other\n// C-W9 commands this one does NOT take its inputs (queue/records/direct\n// dispatches) on the wire — the daemon already reads them itself\n// (`getQueue`/`readLocalRecords`/`getActiveDirectDispatches`), so the request\n// carries only the decision knobs. `closeDispatches` (the C-W8 `turn_cancel`\n// callback) also runs daemon-side now, since it is the same process.\n\nexport interface PruneStaleDirectRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n execute?: boolean\n includeTerminal?: boolean\n source?: string\n}\n\nexport interface PruneStaleDirectResponse {\n mode: 'execute' | 'dry_run'\n includeTerminal: boolean\n candidateCount: number\n /** `MeshActiveWorkRecord[]`, JSON passthrough. */\n prunable: readonly Record<string, unknown>[]\n prunedCount: number\n preservedUnacknowledged: readonly Record<string, unknown>[]\n preservedLedgerOnly: readonly Record<string, unknown>[]\n preservedNotOrphan: readonly Record<string, unknown>[]\n}\n\nfunction isPruneStaleDirectRequest(value: unknown): value is PruneStaleDirectRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'execute', 'includeTerminal', 'source'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId)) return false\n if (value.source !== undefined && typeof value.source !== 'string') return false\n return isOptionalBoolean(value.execute) && isOptionalBoolean(value.includeTerminal)\n}\n\nexport function decodePruneStaleDirectRequest(value: unknown): PruneStaleDirectRequest | null {\n return isPruneStaleDirectRequest(value) ? value : null\n}\n\nfunction isPruneStaleDirectResponse(value: unknown): value is PruneStaleDirectResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['mode', 'includeTerminal', 'candidateCount', 'prunable', 'prunedCount', 'preservedUnacknowledged', 'preservedLedgerOnly', 'preservedNotOrphan'])) return false\n if (value.mode !== 'execute' && value.mode !== 'dry_run') return false\n if (typeof value.includeTerminal !== 'boolean') return false\n if (!isNonNegativeInt(value.candidateCount) || !isNonNegativeInt(value.prunedCount)) return false\n return isRecordArray(value.prunable) && isRecordArray(value.preservedUnacknowledged)\n && isRecordArray(value.preservedLedgerOnly) && isRecordArray(value.preservedNotOrphan)\n}\n\nexport function decodePruneStaleDirectResponse(value: unknown): PruneStaleDirectResponse | null {\n return isPruneStaleDirectResponse(value) ? value : null\n}\n\n// ─── orphaned_pin_notify ────────────────────────────────────────────────────\n//\n// C-W9c: replaces the in-process `notifyCoordinatorOfOrphanedPins` call\n// (`mesh_queue_cancel` tool, `mesh-tools-queue.ts`, CANCEL-ORPHANS-PINNED-TASK).\n// The core reads the daemon's live queue (`getQueue`) and, when it finds\n// orphans, calls `notifyMeshCoordinator` to page the coordinator — both are\n// daemon-only concerns, so the whole call moves, not just its queue read.\n// `title` is a task-message-derived label (first line, truncated) — free text,\n// hence local IPC only, same rationale as `record_local`'s payload.\n\nexport interface OrphanedPinNotifyRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n stoppedSessionId: string\n excludeTaskId?: string\n cause?: string\n nodeId?: string\n coordinatorSessionId?: string\n}\n\nexport interface OrphanedPinnedTaskWire {\n taskId: string\n title: string\n targetSessionId: string\n targetNodeId?: string\n missionId?: string\n}\n\nexport interface OrphanedPinNotifyResponse {\n orphans: readonly OrphanedPinnedTaskWire[]\n}\n\nfunction isOrphanedPinnedTaskWire(value: unknown): value is OrphanedPinnedTaskWire {\n if (!isRecord(value) || !hasOnlyKeys(value, ['taskId', 'title', 'targetSessionId', 'targetNodeId', 'missionId'])) return false\n if (!isEvidenceIdentifier(value.taskId) || !isEvidenceIdentifier(value.targetSessionId)) return false\n if (typeof value.title !== 'string') return false\n if (value.targetNodeId !== undefined && !isEvidenceIdentifier(value.targetNodeId)) return false\n return value.missionId === undefined || isEvidenceIdentifier(value.missionId)\n}\n\nfunction isOrphanedPinNotifyRequest(value: unknown): value is OrphanedPinNotifyRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'stoppedSessionId', 'excludeTaskId', 'cause', 'nodeId', 'coordinatorSessionId'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId) || !isEvidenceIdentifier(value.stoppedSessionId)) return false\n if (value.excludeTaskId !== undefined && !isEvidenceIdentifier(value.excludeTaskId)) return false\n if (value.cause !== undefined && typeof value.cause !== 'string') return false\n if (value.nodeId !== undefined && !isEvidenceIdentifier(value.nodeId)) return false\n return value.coordinatorSessionId === undefined || isEvidenceIdentifier(value.coordinatorSessionId)\n}\n\nexport function decodeOrphanedPinNotifyRequest(value: unknown): OrphanedPinNotifyRequest | null {\n return isOrphanedPinNotifyRequest(value) ? value : null\n}\n\nfunction isOrphanedPinNotifyResponse(value: unknown): value is OrphanedPinNotifyResponse {\n return isRecord(value) && hasOnlyKeys(value, ['orphans']) && Array.isArray(value.orphans) && value.orphans.every(isOrphanedPinnedTaskWire)\n}\n\nexport function decodeOrphanedPinNotifyResponse(value: unknown): OrphanedPinNotifyResponse | null {\n return isOrphanedPinNotifyResponse(value) ? value : null\n}\n","/**\n * turn-ipc — typed IPC command contracts for the six commands that replace\n * mcp-server's direct `mesh-runtime.db` access (design §5 C2 \"MCP server\").\n *\n * Wiring-unification Phase C, workstream C-W6\n * (docs/design/2026-09-23-wiring-unification.md §5 C2/C3, C9 row C-W6).\n *\n * WHY THIS FILE EXISTS\n * ---------------------\n * mcp-server is a second, in-process writer of `mesh-runtime.db` (~45-69\n * direct-mutation call sites, ~54 reads, per the C-W6 brief). C2 moves every\n * one of those call sites behind IPC, executed in the daemon that owns the\n * turn ledger and the seqscribe node, so mcp-server never opens the SQLite\n * file itself. This file is the WIRE CONTRACT for that IPC surface — request/\n * response shapes, closed enums, runtime decoders — shared by the daemon-core\n * command handlers (added with C-W6 proper; NOT this file) and the mcp-server\n * client (`mcp-server/src/ipc/turn-commands.ts`, this workstream).\n *\n * The six commands (§5 C2):\n * - turn_observe — submit one TurnEvidence; returns the reducer verdict.\n * - mesh_record — append a content-free scalar record (`mesh.record`\n * topic entry), replacing `appendLedgerEntry`.\n * - turn_cancel — cancel an attempt (`cancel` evidence, source `mcp_probe`\n * or `operator`).\n * - operator_status — record a fire-and-forget operator/tool-call status\n * (`operator_status` evidence + the former\n * `recordMeshCoordinatorToolCall` log write).\n * - turn_query — read attempt/event rows (own or fleet scope).\n * - mesh_index_query — read `mesh_topic_index` rows (fleet-wide, replacing\n * the in-memory read model / parity reads).\n *\n * CONTENT BOUNDARY\n * -----------------\n * Every request/response field is an identifier, a closed enum, a boolean, a\n * counter or a timestamp. `turn_observe` carries a `TurnEvidence`, which is\n * content-free by construction (`turn-evidence.ts`). `mesh_record` carries a\n * `ProjectedScalars` payload restricted to the SAME allow-list keys\n * `seqscribe/mesh-event-projection.ts` already reviews and ships\n * (`PROJECTED_PAYLOAD_KEYS`, 35 keys) — this file pins a STRUCTURAL COPY of\n * that key list (`MESH_RECORD_PAYLOAD_KEYS`) so mesh-shared does not import\n * daemon-core (leaf constraint), with a test asserting the two lists agree.\n * Summaries, report bodies, progress notes and modal text never travel in any\n * of these payloads — they go to the content-class `mesh.<id>.handoff` topic\n * and are referenced by `SummaryRef {topic, writer, seq}` (already declared\n * in `./turn-evidence.ts`).\n *\n * VERSIONING\n * -----------\n * Every request carries `v: 1` so a future incompatible change can be\n * detected by the responder before it tries to interpret the args.\n *\n * LAYOUT\n * -------\n * This module holds the error codes and the command registry; the per-command\n * contracts live in ./turn-ipc-{turn,mission,queue,stats}.ts (re-exported here)\n * over the shared guard primitives in ./turn-ipc-guards.ts.\n */\n\nimport { isRecord } from './protocol/envelope'\nimport { hasOnlyKeys, makeGuard } from './turn-ipc-guards';\n\nexport { TURN_IPC_PROTOCOL_VERSION } from './turn-ipc-guards';\nexport * from './turn-ipc-turn';\nexport * from './turn-ipc-mission';\nexport * from './turn-ipc-queue';\nexport * from './turn-ipc-stats';\n\n// ─── error codes ────────────────────────────────────────────────────────────\n\n/**\n * Closed error-code union every command response may carry instead of (or in\n * addition to, for the client-side wrapper) a result.\n *\n * daemon_required — no daemon reachable (no IPC/local transport\n * connection could be established). Distinct from\n * every other failure: it means \"there is nobody to\n * ask\", not \"the ask failed.\"\n * turn_ledger_unavailable — a daemon answered but its turn ledger is not\n * armed yet (mid-boot, mid-migration).\n * ledger_not_owner — the daemon that answered does not own the\n * attempt/mesh addressed by the request (routing\n * mistake, or the owner changed after a reclaim).\n */\nexport const TURN_IPC_ERROR_CODES = ['daemon_required', 'turn_ledger_unavailable', 'ledger_not_owner'] as const\nexport type TurnIpcErrorCode = typeof TURN_IPC_ERROR_CODES[number]\n\nexport const isTurnIpcErrorCode = makeGuard(TURN_IPC_ERROR_CODES)\n\n/** Structured failure shape a responder returns instead of a result. Never thrown across the wire — the client maps it to a typed error (see mcp-server/src/ipc/turn-commands.ts). */\nexport interface TurnIpcError {\n code: TurnIpcErrorCode\n /** Short machine-oriented detail, e.g. which daemon was expected. Never free text describing content. */\n detail?: string\n}\n\nexport function isTurnIpcError(value: unknown): value is TurnIpcError {\n return isRecord(value) && hasOnlyKeys(value, ['code', 'detail']) && isTurnIpcErrorCode(value.code)\n && (value.detail === undefined || typeof value.detail === 'string')\n}\n\n// ─── command registry ───────────────────────────────────────────────────────\n\n/** The complete, closed set of IPC command names this contract defines. */\nexport const TURN_IPC_COMMANDS = [\n 'turn_observe',\n 'mesh_record',\n 'turn_cancel',\n 'operator_status',\n 'turn_query',\n 'mesh_index_query',\n 'mission_upsert',\n 'mission_query',\n 'note_upsert',\n 'note_forget',\n // C-W9b additions (2026-09-24 14:00 stamp \"C-W9\"):\n 'tool_call_record',\n 'ledger_query',\n 'mission_list_query',\n // C-W9a additions (the event ledger retired; the queue behind IPC):\n 'record_local',\n 'queue_query',\n 'queue_enqueue',\n 'queue_enqueue_batch',\n 'queue_cancel',\n 'queue_requeue',\n 'direct_dispatch_record',\n 'active_work_query',\n 'recovery_context_query',\n // C-W9c additions (2026-09-24 19:00 stamp — the last mcp-server in-process\n // daemon-core paths: mission reads, task/mission stats, orphaned-pin\n // helpers, one prune audit):\n 'task_stats_query',\n 'prune_stale_direct',\n 'orphaned_pin_notify',\n] as const\nexport type TurnIpcCommand = typeof TURN_IPC_COMMANDS[number]\nexport const isTurnIpcCommand = makeGuard(TURN_IPC_COMMANDS)\n","/**\n * path-ownership — declared file-ownership sets for `code_change` mesh tasks\n * (wiring-unification Phase H1, `docs/design/2026-09-23-wiring-unification.md`\n * §7c).\n *\n * Today two `code_change` tasks on two different nodes (two worktrees of the\n * same branch, or main + a worktree) can silently touch the same file with\n * zero warning — the only existing isolation is node-level (\"one active write\n * task per node\"), never path-level. This module is the pure, dependency-free\n * core of the fix: normalizing a caller-declared `owned_paths` list, and\n * comparing declared sets for overlap. It has NO opinion on enforcement policy\n * (refuse vs warn, which axis a caller compares against) — that is the mesh\n * runtime's job (`claimNextTask` / `claimNextQueueTask` in daemon-core); this\n * module only answers \"do these two declarations conflict\" and \"did the\n * touched-files report stay inside the declaration\".\n *\n * SCOPE DECISION (glob support): minimal, deliberately. A declaration entry is\n * either an exact repo-relative path (`src/foo.ts`) or a directory prefix\n * spelled with a trailing `/**` (`src/mesh/**`) meaning \"this path and\n * everything under it\". No `*`/`?` mid-segment wildcards, no `!` negation, no\n * brace expansion. Two `code_change` tasks racing on overlapping files is a\n * coordination bug to catch, not a general glob engine to build — a full\n * minimatch-style matcher would need its own test suite and still leave the\n * same ambiguity (does `src/*.ts` \"contain\" `src/foo.ts`?) the design doc's\n * risk list calls out. `src/` (no `**`) is treated as an exact single-path\n * entry, i.e. it owns a literal file/dir node named `src`, NOT everything\n * under it — callers who want subtree ownership must write `src/**`.\n *\n * Rejected inputs (absolute paths, `..` segments, backslash-only entries that\n * still resolve outside the repo after normalization) are dropped rather than\n * silently coerced — `normalizeOwnedPaths` reports what it dropped so the\n * caller (enqueue-time validation) can decide whether to warn or refuse.\n */\n\n/** One normalized ownership entry: a repo-relative path, optionally a `**` subtree prefix. */\nexport interface OwnedPathEntry {\n /** Repo-relative path with forward slashes, no leading `./`, no trailing slash. */\n readonly path: string\n /** True when this entry was declared as `<path>/**` (owns the whole subtree). */\n readonly subtree: boolean\n}\n\n/** A caller's normalized ownership declaration. */\nexport interface OwnedPathsDeclaration {\n readonly paths: readonly OwnedPathEntry[]\n}\n\nexport interface NormalizeOwnedPathsResult {\n readonly declaration: OwnedPathsDeclaration\n /** Raw input entries that were dropped, with why — surfaced to the caller, never silently coerced. */\n readonly rejected: ReadonlyArray<{ input: string; reason: string }>\n}\n\n/** Cap mirrors `depends_on`'s implicit list-size discipline (design doc H1 proposal). */\nexport const MAX_OWNED_PATHS = 64\n\nfunction toPosix(raw: string): string {\n return raw.replace(/\\\\/g, '/')\n}\n\n/**\n * Normalize one raw entry. Returns `null` (with a reason pushed to `rejected`)\n * for anything absolute, escaping the repo via `..`, or empty after trimming.\n */\nfunction normalizeOne(raw: unknown, rejected: Array<{ input: string; reason: string }>): OwnedPathEntry | null {\n if (typeof raw !== 'string') {\n rejected.push({ input: String(raw), reason: 'not_a_string' })\n return null\n }\n const trimmed = raw.trim()\n if (!trimmed) {\n rejected.push({ input: raw, reason: 'empty' })\n return null\n }\n let posix = toPosix(trimmed)\n\n // Absolute paths (POSIX `/…`, Windows drive letter `C:\\…` or `C:/…`, or a\n // stray leading `~`) are refused outright — ownership is repo-relative by\n // construction, and accepting an absolute path would let a declaration\n // silently escape the workspace it is meant to scope.\n if (posix.startsWith('/') || /^[a-zA-Z]:\\//.test(posix) || posix.startsWith('~')) {\n rejected.push({ input: raw, reason: 'absolute_path' })\n return null\n }\n\n // Strip a leading './'.\n posix = posix.replace(/^\\.\\/+/, '')\n\n // Reject any '..' segment anywhere — no escaping the repo root.\n const segments = posix.split('/').filter(Boolean)\n if (segments.some(seg => seg === '..')) {\n rejected.push({ input: raw, reason: 'parent_traversal' })\n return null\n }\n if (segments.length === 0) {\n rejected.push({ input: raw, reason: 'empty' })\n return null\n }\n\n // Minimal glob support: a trailing '**' segment (from '<path>/**') marks a\n // subtree declaration. Any OTHER '*'/'?' anywhere is rejected — this module\n // does not implement general glob matching (see module doc).\n let subtree = false\n if (segments[segments.length - 1] === '**') {\n subtree = true\n segments.pop()\n if (segments.length === 0) {\n // '**' alone (or './**') claims the entire repo — allowed, but the\n // caller (enqueue-time validation) is expected to lint/warn on it\n // per the design doc's deadlock risk; this module only normalizes.\n }\n }\n if (segments.some(seg => seg.includes('*') || seg.includes('?'))) {\n rejected.push({ input: raw, reason: 'unsupported_glob' })\n return null\n }\n\n return { path: segments.join('/'), subtree }\n}\n\n/**\n * Normalize a caller-supplied `owned_paths` array. Never throws — invalid\n * entries are dropped and reported in `rejected`; duplicates (after\n * normalization) collapse to one entry (subtree wins if either declaration\n * form is present for the same path). Entries beyond `MAX_OWNED_PATHS` (after\n * dedup) are dropped with reason `over_cap`, preserving declaration order.\n */\nexport function normalizeOwnedPaths(input: unknown): NormalizeOwnedPathsResult {\n const rejected: Array<{ input: string; reason: string }> = []\n if (input === undefined || input === null) {\n return { declaration: { paths: [] }, rejected }\n }\n if (!Array.isArray(input)) {\n return { declaration: { paths: [] }, rejected: [{ input: String(input), reason: 'not_an_array' }] }\n }\n\n const byPath = new Map<string, OwnedPathEntry>()\n for (const raw of input) {\n const entry = normalizeOne(raw, rejected)\n if (!entry) continue\n const existing = byPath.get(entry.path)\n if (!existing) {\n byPath.set(entry.path, entry)\n } else if (entry.subtree && !existing.subtree) {\n byPath.set(entry.path, entry)\n }\n // else: duplicate, existing entry already at least as broad — keep it.\n }\n\n const all = [...byPath.values()]\n const kept = all.slice(0, MAX_OWNED_PATHS)\n for (const dropped of all.slice(MAX_OWNED_PATHS)) {\n rejected.push({ input: dropped.path, reason: 'over_cap' })\n }\n\n return { declaration: { paths: kept }, rejected }\n}\n\n/** True when `path` is exactly `base`, or (when `base` is a subtree entry) nested under it. */\nfunction entryContains(base: OwnedPathEntry, path: string): boolean {\n if (path === base.path) return true\n if (base.subtree && (path === base.path || path.startsWith(`${base.path}/`))) return true\n return false\n}\n\n/** True when two normalized entries' claimed sets intersect (exact match, or one contains the other's directory). */\nfunction entriesOverlap(a: OwnedPathEntry, b: OwnedPathEntry): boolean {\n if (a.path === b.path) return true\n if (a.subtree && (b.path === a.path || b.path.startsWith(`${a.path}/`))) return true\n if (b.subtree && (a.path === b.path || a.path.startsWith(`${b.path}/`))) return true\n return false\n}\n\n/** True when two declarations claim any overlapping path. Pure set comparison — no policy (refuse vs warn) here. */\nexport function pathsOverlap(a: OwnedPathsDeclaration, b: OwnedPathsDeclaration): boolean {\n if (a.paths.length === 0 || b.paths.length === 0) return false\n for (const pa of a.paths) {\n for (const pb of b.paths) {\n if (entriesOverlap(pa, pb)) return true\n }\n }\n return false\n}\n\nexport interface InFlightOwnership {\n readonly taskId: string\n readonly paths: OwnedPathsDeclaration\n}\n\nexport interface OwnershipConflict {\n readonly taskId: string\n /** The specific overlapping paths, for a readable refusal message. */\n readonly overlappingPaths: readonly string[]\n}\n\n/**\n * Compare a candidate declaration against every other in-flight task's\n * declaration and return every conflict found (not just the first), each\n * naming the owning task id and the specific overlapping path(s) — so a\n * refusal message can say exactly what collided, not just that it did.\n *\n * Backward compatibility (design doc risk #4): an EMPTY candidate declaration\n * never conflicts (opt-in only — absent `owned_paths` performs no overlap\n * check for that task), and an in-flight entry with an empty declaration is\n * never reported as a conflict source either.\n */\nexport function findOwnershipConflicts(\n candidate: OwnedPathsDeclaration,\n inFlight: readonly InFlightOwnership[],\n): OwnershipConflict[] {\n if (candidate.paths.length === 0) return []\n const conflicts: OwnershipConflict[] = []\n for (const other of inFlight) {\n if (other.paths.paths.length === 0) continue\n const overlappingPaths: string[] = []\n for (const pa of candidate.paths) {\n for (const pb of other.paths.paths) {\n if (entriesOverlap(pa, pb)) {\n const narrower = pa.path.length >= pb.path.length ? pa.path : pb.path\n if (!overlappingPaths.includes(narrower)) overlappingPaths.push(narrower)\n }\n }\n }\n if (overlappingPaths.length > 0) {\n conflicts.push({ taskId: other.taskId, overlappingPaths })\n }\n }\n return conflicts\n}\n\nexport interface TouchedFilesOutsideOwnershipResult {\n /** Touched files not covered by any declared owned-path entry. */\n readonly undeclaredTouched: readonly string[]\n /** Declared entries that no touched file matched (informational only — under-reporting is not flagged as a mismatch by policy, just visible here). */\n readonly unusedDeclarations: readonly string[]\n}\n\n/**\n * Compare a worker's `report_completion.touched_files` against its task's\n * declared `owned_paths`. Pure comparison only — per the design doc, a\n * mismatch is \"surfaced as evidence, not silently accepted\"; this function\n * does not decide whether that is an error. Each `touched` entry is\n * normalized with the same rules as a declaration (invalid entries — e.g. an\n * absolute path a worker reported by mistake — are treated as undeclared\n * rather than silently dropped, since they cannot match anything).\n */\nexport function touchedFilesOutsideOwnership(\n touched: readonly string[],\n owned: OwnedPathsDeclaration,\n): TouchedFilesOutsideOwnershipResult {\n const undeclaredTouched: string[] = []\n const usedDeclarations = new Set<string>()\n\n for (const raw of touched ?? []) {\n const rejectedSink: Array<{ input: string; reason: string }> = []\n const entry = normalizeOne(raw, rejectedSink)\n if (!entry) {\n undeclaredTouched.push(raw)\n continue\n }\n const matches = owned.paths.filter(base => entryContains(base, entry.path))\n if (matches.length === 0) {\n undeclaredTouched.push(entry.path)\n } else {\n for (const m of matches) usedDeclarations.add(m.path)\n }\n }\n\n const unusedDeclarations = owned.paths.map(p => p.path).filter(p => !usedDeclarations.has(p))\n return { undeclaredTouched, unusedDeclarations }\n}\n","/**\n * Keyed document delta — THE diff/fold engine behind every keyed dashboard\n * lane: `daemon.metadata` (the daemon's state, sessions keyed by id) and\n * `mesh.status` (the coordinator's mesh view, nodes / queue tasks / missions\n * keyed) — data-path audit 2026-09-29 P1-4 (one engine, one spec per lane).\n *\n * A document is plain top-level fields, optional SPLIT objects (an object whose\n * fields are diffed one by one, e.g. daemon.metadata's `status`), and named\n * keyed COLLECTIONS (arrays of rows identified by an id field, possibly nested\n * one object deep, e.g. `queue.tasks` / `status.sessions`). The daemon digests\n * every body it would have sent, diffs it against the digest of the last body\n * DELIVERED to a subscription, and sends only the difference: changed fields,\n * and per collection the rows whose content changed (changed fields only), the\n * fields a row lost, and the rows that disappeared. An unchanged document\n * diffs to `null` — zero bytes on the wire. The dashboard folds each delta\n * into its held snapshot; the fold of every delta since a snapshot equals the\n * latest snapshot apart from `ignore`d fields (pinned by keyed-doc-delta.test.ts).\n *\n * Volatile fields (a build stamp, live process counters, a row's per-build\n * stamps via `stableRow`) are not a change by themselves; when something else\n * changed they ride along.\n *\n * Pure leaf: plain objects in, plain objects out; no transport, no clock.\n */\n\nexport interface KeyedDocSpec {\n /** Collection path (`nodes`, `queue.tasks`, `status.sessions`) → the id field of its rows. */\n collections: Readonly<Record<string, string>>\n /** Top-level objects whose own fields are diffed one by one (the rest of the object is not re-sent). */\n splitObjects?: readonly string[]\n /** Field paths (`daemonId`, `status.timestamp`) that are never diffed — envelope identity / clock. */\n ignore?: readonly string[]\n /** Field paths (top-level or inside a split object) that change on every build without meaning anything. */\n volatileTopLevel?: readonly string[]\n /**\n * The part of a collection row that decides whether it CHANGED (drop the\n * per-build stamps inside it). A row whose stable view is unchanged sends\n * nothing; a changed row sends every field whose value differs, stamps\n * included. Must not mutate `row`.\n */\n stableRow?: (collection: string, row: Record<string, unknown>) => Record<string, unknown>\n}\n\ntype Row = Record<string, unknown>\n\ninterface RowDigest {\n readonly value: Row\n /** The row as compared (stableRow view). */\n readonly stable: Row\n readonly sig: string\n fieldSigs?: Map<string, string>\n}\n\ninterface CollectionDigest {\n readonly rows: ReadonlyMap<string, RowDigest>\n readonly order: readonly string[]\n}\n\nexport interface KeyedDocDigest {\n /** Field signatures by path (`field`, or `object.field` for a split object). */\n readonly top: ReadonlyMap<string, string>\n readonly topValues: Readonly<Record<string, unknown>>\n readonly collections: ReadonlyMap<string, CollectionDigest>\n readonly volatile: ReadonlySet<string>\n}\n\nexport interface KeyedCollectionDelta {\n /** New rows (whole) and changed rows (id + changed fields). */\n upsert?: Row[]\n /** Fields a row lost, by row id. */\n unsetFields?: Record<string, string[]>\n removed?: string[]\n order?: string[]\n /** The collection is no longer present in the document at all. */\n absent?: true\n}\n\nexport interface KeyedDocDelta {\n set?: Record<string, unknown>\n unset?: string[]\n /** Per split object: its changed / lost fields. */\n objects?: Record<string, { set?: Record<string, unknown>; unset?: string[] }>\n collections?: Record<string, KeyedCollectionDelta>\n}\n\nfunction sig(value: unknown): string | undefined {\n if (value === undefined) return undefined\n try {\n return JSON.stringify(value)\n } catch {\n return undefined\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n}\n\n/** Read the array at `path` (`a` or `a.b`) — undefined when absent. */\nfunction readPath(doc: Record<string, unknown>, path: string): unknown {\n const [head, tail] = splitPath(path)\n if (!tail) return doc[head]\n const parent = doc[head]\n return isRecord(parent) ? parent[tail] : undefined\n}\n\nfunction splitPath(path: string): [string, string | undefined] {\n const dot = path.indexOf('.')\n return dot < 0 ? [path, undefined] : [path.slice(0, dot), path.slice(dot + 1)]\n}\n\n/**\n * The document minus its collections (a nested collection is removed from a\n * shallow copy of its parent, so the parent's other fields stay top-level data).\n */\nfunction stripCollections(doc: Record<string, unknown>, spec: KeyedDocSpec): Record<string, unknown> {\n const out: Record<string, unknown> = { ...doc }\n for (const path of Object.keys(spec.collections)) {\n const [head, tail] = splitPath(path)\n if (!tail) {\n delete out[head]\n continue\n }\n const parent = out[head]\n if (!isRecord(parent) || !(tail in parent)) continue\n const copy = { ...parent }\n delete copy[tail]\n out[head] = copy\n }\n return out\n}\n\nfunction fieldSigsOf(digest: RowDigest): Map<string, string> {\n if (!digest.fieldSigs) {\n const sigs = new Map<string, string>()\n for (const [key, value] of Object.entries(digest.stable)) {\n const s = sig(value)\n if (s !== undefined) sigs.set(key, s)\n }\n digest.fieldSigs = sigs\n }\n return digest.fieldSigs\n}\n\n/** Digest one document. Cheap to hold: values are referenced, not copied. */\nexport function digestKeyedDoc(doc: Record<string, unknown>, spec: KeyedDocSpec): KeyedDocDigest {\n const top = new Map<string, string>()\n const topValues: Record<string, unknown> = {}\n const ignore = new Set(spec.ignore ?? [])\n const split = new Set(spec.splitObjects ?? [])\n const add = (path: string, value: unknown) => {\n if (ignore.has(path)) return\n const s = sig(value)\n if (s === undefined) return\n top.set(path, s)\n topValues[path] = value\n }\n for (const [key, value] of Object.entries(stripCollections(doc, spec))) {\n if (split.has(key) && isRecord(value)) {\n for (const [field, fieldValue] of Object.entries(value)) add(`${key}.${field}`, fieldValue)\n continue\n }\n add(key, value)\n }\n const collections = new Map<string, CollectionDigest>()\n for (const [path, idField] of Object.entries(spec.collections)) {\n const list = readPath(doc, path)\n if (!Array.isArray(list)) continue\n const rows = new Map<string, RowDigest>()\n const order: string[] = []\n for (const row of list) {\n if (!isRecord(row)) continue\n const id = row[idField]\n if (typeof id !== 'string' || !id || rows.has(id)) continue\n const stable = spec.stableRow ? spec.stableRow(path, row) : row\n rows.set(id, { value: row, stable, sig: sig(stable) ?? '' })\n order.push(id)\n }\n collections.set(path, { rows, order })\n }\n return { top, topValues, collections, volatile: new Set(spec.volatileTopLevel ?? []) }\n}\n\nfunction sameOrder(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i += 1) if (a[i] !== b[i]) return false\n return true\n}\n\nfunction diffCollection(prev: CollectionDigest | undefined, next: CollectionDigest | undefined, idField: string): KeyedCollectionDelta | null {\n if (!next) return prev ? { absent: true } : null\n const delta: KeyedCollectionDelta = {}\n const prevRows = prev?.rows ?? new Map<string, RowDigest>()\n const nextRows = next?.rows ?? new Map<string, RowDigest>()\n for (const [id, nextRow] of nextRows) {\n const prevRow = prevRows.get(id)\n if (!prevRow) {\n ;(delta.upsert ??= []).push(nextRow.value)\n continue\n }\n if (prevRow.sig === nextRow.sig) continue\n const prevSigs = fieldSigsOf(prevRow)\n const nextSigs = fieldSigsOf(nextRow)\n const change: Row = { [idField]: id }\n let changed = false\n for (const [key, s] of nextSigs) {\n if (key === idField || prevSigs.get(key) === s) continue\n change[key] = nextRow.value[key]\n changed = true\n }\n // A real change carries the row's volatile fields (dropped by stableRow) along.\n if (changed) {\n for (const [key, value] of Object.entries(nextRow.value)) {\n if (key in nextRow.stable || key in change) continue\n if (sig(prevRow.value[key]) !== sig(value)) change[key] = value\n }\n }\n const gone: string[] = []\n for (const key of prevSigs.keys()) if (!nextSigs.has(key) && !(key in nextRow.value)) gone.push(key)\n if (changed) (delta.upsert ??= []).push(change)\n if (gone.length > 0) (delta.unsetFields ??= {})[id] = gone\n }\n for (const id of prevRows.keys()) {\n if (!nextRows.has(id)) (delta.removed ??= []).push(id)\n }\n if (!sameOrder(prev?.order ?? [], next?.order ?? [])) delta.order = [...(next?.order ?? [])]\n return Object.keys(delta).length > 0 ? delta : null\n}\n\n/**\n * The difference `prev → next`, or `null` when nothing a consumer can observe\n * changed (volatile top-level fields alone are not a change).\n */\nexport function diffKeyedDoc(prev: KeyedDocDigest, next: KeyedDocDigest, spec: KeyedDocSpec): KeyedDocDelta | null {\n const delta: KeyedDocDelta = {}\n let meaningful = false\n let set: Record<string, unknown> | undefined\n let unset: string[] | undefined\n const split = spec.splitObjects ?? []\n const objectOf = (path: string): [string, string] | null => {\n for (const object of split) {\n if (path.startsWith(`${object}.`)) return [object, path.slice(object.length + 1)]\n }\n return null\n }\n const objects: NonNullable<KeyedDocDelta['objects']> = {}\n for (const [path, s] of next.top) {\n if (prev.top.get(path) === s) continue\n const inObject = objectOf(path)\n if (inObject) ((objects[inObject[0]] ??= {}).set ??= {})[inObject[1]] = next.topValues[path]\n else (set ??= {})[path] = next.topValues[path]\n if (!next.volatile.has(path)) meaningful = true\n }\n for (const path of prev.top.keys()) {\n if (next.top.has(path)) continue\n const inObject = objectOf(path)\n if (inObject) ((objects[inObject[0]] ??= {}).unset ??= []).push(inObject[1])\n else (unset ??= []).push(path)\n if (!next.volatile.has(path)) meaningful = true\n }\n for (const [path, idField] of Object.entries(spec.collections)) {\n const change = diffCollection(prev.collections.get(path), next.collections.get(path), idField)\n if (!change) continue\n ;(delta.collections ??= {})[path] = change\n meaningful = true\n }\n if (!meaningful) return null\n if (set) delta.set = set\n if (unset) delta.unset = unset\n if (Object.keys(objects).length > 0) delta.objects = objects\n return delta\n}\n\nfunction foldCollection(held: unknown, change: KeyedCollectionDelta, idField: string): Row[] {\n const byId = new Map<string, Row>()\n const heldOrder: string[] = []\n for (const row of Array.isArray(held) ? held : []) {\n if (!isRecord(row) || typeof row[idField] !== 'string') continue\n byId.set(row[idField] as string, row)\n heldOrder.push(row[idField] as string)\n }\n for (const id of change.removed ?? []) byId.delete(id)\n for (const row of change.upsert ?? []) {\n const id = row[idField]\n if (typeof id !== 'string') continue\n const base = byId.get(id)\n byId.set(id, base ? { ...base, ...row } : { ...row })\n }\n for (const [id, keys] of Object.entries(change.unsetFields ?? {})) {\n const base = byId.get(id)\n if (!base) continue\n const trimmed = { ...base }\n for (const key of keys) delete trimmed[key]\n byId.set(id, trimmed)\n }\n const order = change.order ?? heldOrder\n const out: Row[] = []\n const placed = new Set<string>()\n for (const id of order) {\n const row = byId.get(id)\n if (!row || placed.has(id)) continue\n out.push(row)\n placed.add(id)\n }\n for (const [id, row] of byId) if (!placed.has(id)) out.push(row)\n return out\n}\n\n/** Rebuild the full document from a held one plus a delta. Never mutates `held`. */\nexport function foldKeyedDoc<T extends Record<string, unknown>>(held: T, delta: KeyedDocDelta, spec: KeyedDocSpec): T {\n // Collections are re-inserted below from the held ones, so the plain fields\n // are folded on the stripped view (a nested parent keeps its other fields).\n const heldCollections = new Map<string, unknown>()\n for (const path of Object.keys(spec.collections)) heldCollections.set(path, readPath(held, path))\n const next: Record<string, unknown> = stripCollections(held, spec)\n for (const key of delta.unset ?? []) delete next[key]\n Object.assign(next, delta.set ?? {})\n for (const [object, change] of Object.entries(delta.objects ?? {})) {\n const folded: Record<string, unknown> = isRecord(next[object]) ? { ...(next[object] as Record<string, unknown>) } : {}\n for (const key of change.unset ?? []) delete folded[key]\n Object.assign(folded, change.set ?? {})\n next[object] = folded\n }\n for (const [path, idField] of Object.entries(spec.collections)) {\n const change = delta.collections?.[path]\n const heldList = heldCollections.get(path)\n if (change?.absent) {\n const [head, tail] = splitPath(path)\n if (!tail) delete next[head]\n continue\n }\n if (!change && heldList === undefined) continue\n const list = change ? foldCollection(heldList, change, idField) : heldList\n const [head, tail] = splitPath(path)\n if (!tail) {\n next[head] = list\n continue\n }\n const parent = isRecord(next[head]) ? { ...(next[head] as Record<string, unknown>) } : {}\n parent[tail] = list\n next[head] = parent\n }\n return next as T\n}\n\n/**\n * The `daemon.metadata` document (the snapshot body minus its envelope):\n * `status` is split field by field, its sessions keyed by `id`. `daemonId` is\n * envelope identity and `status.timestamp` the build clock — never diffed (the\n * fold re-stamps them from the frame); a session's `lastUpdated` build stamp is\n * not a change by itself.\n */\nexport const DAEMON_METADATA_DOC_SPEC: KeyedDocSpec = {\n collections: { 'status.sessions': 'id' },\n splitObjects: ['status'],\n ignore: ['daemonId', 'status.timestamp'],\n stableRow: (_collection, row) => {\n if (!('lastUpdated' in row)) return row\n const { lastUpdated: _stamp, ...stable } = row\n return stable\n },\n}\n\n/**\n * The `mesh.status` document: nodes keyed by `nodeId`, queue tasks and missions\n * by `id`. `refreshedAt` and `sourceOfTruth` (its aggregate-cache age /\n * returnedAt) are per-call stamps and the counters are live process tallies —\n * none of them is a change by itself.\n */\nexport const MESH_STATUS_DOC_SPEC: KeyedDocSpec = {\n collections: { nodes: 'nodeId', 'queue.tasks': 'id', missions: 'id' },\n volatileTopLevel: [\n 'refreshedAt', 'sourceOfTruth',\n 'turnPresentationCounters', 'meshProtocolV2Counters', 'pendingRetentionCounters', 'meshProtocolMetrics',\n ],\n stableRow: (collection, row) => (collection === 'nodes' ? stableMeshNodeRow(row) : row),\n}\n\nfunction without(value: unknown, keys: readonly string[]): unknown {\n if (!isRecord(value)) return value\n const out = { ...value }\n for (const key of keys) delete out[key]\n return out\n}\n\n/**\n * A mesh node minus the stamps an aggregate rebuild re-derives from the clock\n * (last-seen / updated / freshness age, the local read's check time, a local\n * facts bundle's reportedAt). A REMOTE node's `gitObservation.observedAt` is\n * real news (the member's own check time — the dashboard's \"aged\" hint) and\n * is compared; the coordinator's own / local checkout's is its read time.\n */\nfunction stableMeshNodeRow(row: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = { ...row }\n delete out.lastSeenAt\n delete out.updatedAt\n delete out.last_seen_at\n delete out.updated_at\n if ('dataFreshness' in out) out.dataFreshness = without(out.dataFreshness, ['ageMs', 'lastProbeAt', 'staleness'])\n if ('connection' in out) out.connection = without(out.connection, ['lastStateChangeAt'])\n if ('git' in out) {\n const git = without(out.git, ['lastCheckedAt'])\n // \"No submodules\" is the same fact whether a read listed none or skipped the scan.\n if (isRecord(git) && Array.isArray(git.submodules) && git.submodules.length === 0) delete git.submodules\n out.git = git\n }\n if ('nodeFacts' in out) out.nodeFacts = without(out.nodeFacts, ['reportedAt'])\n const observation = out.gitObservation\n if (isRecord(observation) && (observation.source === 'self' || observation.source === 'local')) {\n out.gitObservation = without(observation, ['observedAt'])\n }\n return out\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACYO,SAAS,WAAW,OAA4B;AACnD,SAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAAI,QAAsB,CAAC;AAChG;AAGO,SAAS,mBAAmB,OAAwC;AACvE,SAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAAI,QAAsB;AAC/F;AAEO,SAAS,cAAc,QAAuC;AACjE,aAAW,SAAS,QAAQ;AACxB,QAAI,OAAO,UAAU,SAAU;AAC/B,UAAM,UAAU,MAAM,KAAK;AAC3B,QAAI,QAAS,QAAO;AAAA,EACxB;AACA,SAAO;AACX;AAGO,SAAS,YAAY,QAA2B;AACnD,SAAO,WAAW,GAAG,MAAM,KAAK;AACpC;AAEO,SAAS,cAAc,QAAuC;AACjE,aAAW,SAAS,QAAQ;AACxB,QAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAAA,EACpE;AACA,SAAO;AACX;AAEO,SAAS,eAAe,QAAwC;AACnE,aAAW,SAAS,QAAQ;AACxB,QAAI,OAAO,UAAU,UAAW,QAAO;AAAA,EAC3C;AACA,SAAO;AACX;AAEO,SAAS,gBAAgB,OAA0B;AACtD,SAAO,MAAM,QAAQ,KAAK,IACpB,MAAM,OAAO,CAAC,UAA2B,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,CAAC,IAC7F,CAAC;AACX;AAUO,SAAS,gBAAgB,OAA4B;AACxD,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,MAAI,OAAO,UAAU,SAAU,QAAO,WAAW,KAAK;AACtD,MAAI,OAAO,UAAU,SAAU,QAAO,CAAC;AACvC,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,CAAC,QAAS,QAAO,CAAC;AACtB,MAAI;AACA,WAAO,WAAW,KAAK,MAAM,OAAO,CAAC;AAAA,EACzC,QAAQ;AACJ,WAAO,CAAC;AAAA,EACZ;AACJ;AAOO,SAAS,aAAa,MAA0B,cAAsD;AACzG,QAAM,iBAAiB,OAAO,SAAS,WAAW,KAAK,KAAK,EAAE,QAAQ,WAAW,EAAE,IAAI;AACvF,QAAM,iBAAiB,OAAO,iBAAiB,WAAW,aAAa,KAAK,IAAI;AAChF,MAAI,CAAC,eAAgB,QAAO;AAC5B,MAAI,yBAAyB,KAAK,cAAc,EAAG,QAAO;AAC1D,MAAI,CAAC,eAAgB,QAAO;AAC5B,SAAO,GAAG,cAAc,IAAI,eAAe,QAAQ,WAAW,EAAE,CAAC;AACrE;;;AC9EO,SAAS,0BAA0B,QAAkD;AACxF,UAAQ,QAAQ;AAAA,IACZ,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AAAA,IACL,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX;AACI,aAAO;AAAA,EACf;AACJ;AAEO,SAAS,kBAAkB,OAAgB,gBAA2D;AACzG,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO;AAClC,QAAM,aAAa,MACd,IAAI,WAAS;AACV,UAAM,YAAY,WAAW,KAAK;AAClC,UAAM,OAAO,WAAW,UAAU,IAAI;AACtC,UAAM,SAAS,WAAW,UAAU,MAAM;AAC1C,UAAM,WAAW,WAAW,UAAU,UAAU,UAAU,SAAS,KAC5D,aAAa,gBAAgB,IAAI;AAMxC,QAAI,CAAC,QAAQ,CAAC,OAAQ,QAAO;AAC7B,UAAM,SAA6B;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,OAAO,YAAY,UAAU,KAAK,KAAK;AAAA,MACvC,WAAW,YAAY,UAAU,WAAW,UAAU,WAAW,KAAK;AAAA,IAC1E;AACA,UAAM,gBAAgB,WAAW,UAAU,eAAe,UAAU,eAAe;AACnF,QAAI,kBAAkB,OAAW,QAAO,gBAAgB;AACxD,QAAI,SAAU,QAAO,WAAW;AAChC,UAAM,QAAQ,WAAW,UAAU,KAAK;AACxC,QAAI,MAAO,QAAO,QAAQ;AAC1B,WAAO;AAAA,EACX,CAAC,EACA,OAAO,CAAC,UAAuC,UAAU,IAAI;AAClE,SAAO,WAAW,SAAS,IAAI,aAAa;AAChD;AAEO,SAAS,qBAAqB,QAA6B;AAK9D,SAAO,YAAY,OAAO,SAAS,MAAM,UAClC,QAAQ,WAAW,OAAO,QAAQ,OAAO,UAAU,OAAO,gBAAgB,OAAO,iBAAiB,OAAO,UAAU,CAAC,KACpH,QAAQ,WAAW,OAAO,UAAU,OAAO,WAAW,OAAO,SAAS,CAAC,KACvE;AAAA,IACC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,EACX,MAAM,UACF,MAAM,QAAQ,OAAO,UAAU,KAAK,OAAO,WAAW,SAAS;AAC3E;AAEO,SAAS,mBACZ,QACA,MACA,SACyB;AACzB,QAAM,oBAAoB,YAAY,OAAO,SAAS;AACtD,MAAI,CAAC,OAAO,KAAK,MAAM,EAAE,UAAU,CAAC,qBAAqB,MAAM,EAAG,QAAO;AACzE,QAAM,YAAY,qBAAqB;AACvC,QAAM,gBAAgB,MAAM,QAAQ,OAAO,aAAa,IAClD,OAAO,cAAc,OAAO,CAAC,UAA2B,OAAO,UAAU,QAAQ,IACjF,CAAC;AACP,QAAM,gBAAgB,WAAW,OAAO,SAAS,KAAK,cAAc;AACpE,QAAM,eAAe,YAAY,OAAO,YAAY,KAAK,gBAAgB;AAGzE,QAAM,WAAW,WAAW,OAAO,UAAU,OAAO,WAAW,KAAK,UAAU,KAAK,WAAW,OAAO,WAAW,KAAK,SAAS,KAAK;AACnI,QAAM,aAAa,kBAAkB,OAAO,YAAY,QAAQ;AAChE,QAAM,iBAAiB,WAAW,OAAO,gBAAgB,OAAO,eAAe;AAC/E,QAAM,oBAAoB,WAAW,OAAO,mBAAmB,OAAO,mBAAmB;AACzF,QAAM,qBAAqB,WAAW,OAAO,oBAAoB,OAAO,oBAAoB;AAC5F,QAAM,QAAQ,WAAW,OAAO,KAAK;AACrC,QAAM,SAAS,WAAW,OAAO,MAAM,KAAK;AAC5C,QAAM,WAAW,WAAW,OAAO,QAAQ,KAAK;AAChD,QAAM,YAAY,WAAW,OAAO,SAAS,KAAK;AAClD,QAAM,UAAU,WAAW,OAAO,OAAO,KAAK;AAC9C,QAAM,UAAU,WAAW,OAAO,OAAO,KAAK;AAC9C,QAAM,gBAAgB,SAAS,iBAAiB,WAAW,OAAO,eAAe,OAAO,eAAe;AACvG,SAAO;AAAA,IACH,WAAW,WAAW,OAAO,WAAW,KAAK,SAAS,KAAK;AAAA,IAC3D,UAAU,YAAY;AAAA,IACtB;AAAA,IACA,QAAQ,WAAW,OAAO,MAAM,KAAK;AAAA,IACrC,YAAY,WAAW,OAAO,UAAU,KAAK;AAAA,IAC7C,aAAa,WAAW,OAAO,WAAW,KAAK;AAAA,IAC/C,UAAU,WAAW,OAAO,QAAQ,KAAK;AAAA,IACzC,gBAAiB,kBAA2C;AAAA,IAC5D,GAAI,sBAAsB,SAAY,EAAE,kBAAkB,IAAI,CAAC;AAAA,IAC/D,GAAI,qBAAqB,EAAE,mBAAmB,IAAI,CAAC;AAAA,IACnD,OAAO,WAAW,OAAO,KAAK,KAAK;AAAA,IACnC,QAAQ,WAAW,OAAO,MAAM,KAAK;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,YAAY,OAAO,OAAO,OAAO,SAAS,OAAO,QAAQ,MAAM,SAAS,WAAW,YAAY,UAAU,UAAU,KAAK;AAAA,IAC/H;AAAA,IACA;AAAA,IACA,YAAY,WAAW,OAAO,YAAY,OAAO,WAAW,KAAK;AAAA,IACjE,GAAI,kBAAkB,SAAY,EAAE,cAAc,IAAI,CAAC;AAAA,IACvD,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMnC,GAAI,OAAO,qBAAqB,OAAO,OAAO,sBAAsB,WAC9D,EAAE,mBAAmB,OAAO,kBAAkD,IAC9E,CAAC;AAAA,IACP,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,EAC7B;AACJ;AAEO,SAAS,wBAAwB,KAAwC;AAC5E,MAAI,CAAC,IAAK,QAAO,OAAO;AACxB,MAAI,QAAQ;AACZ,MAAI,IAAI,cAAc,KAAM,UAAS;AACrC,MAAI,IAAI,cAAc,MAAO,UAAS;AACtC,MAAI,IAAI,OAAQ,UAAS;AACzB,MAAI,IAAI,WAAY,UAAS;AAC7B,MAAI,IAAI,SAAU,UAAS;AAC3B,WAAS,0BAA0B,IAAI,cAAc;AACrD,MAAI,OAAO,IAAI,UAAU,SAAU,UAAS;AAC5C,MAAI,OAAO,IAAI,WAAW,SAAU,UAAS;AAC7C,MAAI,MAAM,QAAQ,IAAI,UAAU,KAAK,IAAI,WAAW,SAAS,EAAG,UAAS,IAAI,IAAI,WAAW;AAC5F,MAAI,IAAI,MAAO,UAAS;AACxB,SAAO;AACX;AAOO,SAAS,yBAAyB,MAAkB,SAAiE;AACxH,QAAM,SAAS,WAAW,KAAK,WAAW,KAAK,QAAQ;AACvD,QAAM,YAAY,WAAW,OAAO,MAAM;AAC1C,QAAM,eAAe,WAAW,OAAO,MAAM;AAC7C,QAAM,eAAe,WAAW,UAAU,MAAM;AAChD,QAAM,WAAW,WAAW,KAAK,aAAa,KAAK,UAAU;AAC7D,QAAM,WAAW,WAAW,SAAS,GAAG;AACxC,QAAM,iBAAiB,WAAW,SAAS,MAAM;AACjD,QAAM,oBAAoB,WAAW,SAAS,MAAM;AACpD,QAAM,oBAAoB,WAAW,eAAe,MAAM;AAC1D,MAAI,OAAqD;AACzD,aAAW,UAAU,CAAC,cAAc,cAAc,mBAAmB,iBAAiB,GAAG;AACrF,UAAM,aAAa,mBAAmB,QAAQ,MAAM,OAAO;AAC3D,QAAI,CAAC,WAAY;AACjB,UAAM,QAAQ,wBAAwB,UAAU;AAChD,QAAI,CAAC,QAAQ,QAAQ,KAAK,MAAO,QAAO,EAAE,KAAK,YAAY,MAAM;AAAA,EACrE;AACA,SAAO,MAAM;AACjB;;;ACxKA,SAAS,yBAAyB,QAA2D;AACzF,QAAM,QAAQ;AAAA,IACV,WAAW,OAAO,SAAS;AAAA,IAC3B,WAAW,OAAO,cAAc,OAAO,QAAQ;AAAA,IAC/C,WAAW,OAAO,IAAI;AAAA,IACtB,WAAW,OAAO,OAAO,OAAO,MAAM;AAAA,IACtC,WAAW,OAAO,KAAK;AAAA,IACvB,WAAW,OAAO,WAAW,OAAO,UAAU;AAAA,IAC9C,WAAW,OAAO,WAAW,OAAO,UAAU;AAAA,EAClD,EAAE,OAAO,CAAC,SAAyB,QAAQ,IAAI,CAAC;AAChD,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,SAAO,aAAa,MAAM,KAAK,GAAG,CAAC;AACvC;AAYO,SAAS,qBAAqB,GAA8B,GAAuC;AACtG,QAAM,MAAM,WAAW,CAAC;AACxB,QAAM,MAAM,WAAW,CAAC;AACxB,MAAI,CAAC,OAAO,CAAC,IAAK,QAAO;AACzB,SAAO,QAAQ;AACnB;AAEO,SAAS,2BAA2B,OAA8C;AACrF,QAAM,SAAS,WAAW,KAAK;AAM/B,QAAM,YAAY,WAAW,OAAO,WAAW,OAAO,YAAY,OAAO,EAAE,KACpE,yBAAyB,MAAM;AACtC,MAAI,CAAC,UAAW,QAAO;AACvB,SAAO;AAAA,IACH;AAAA,IACA,GAAI,WAAW,OAAO,cAAc,OAAO,QAAQ,IAAI,EAAE,cAAc,WAAW,OAAO,cAAc,OAAO,QAAQ,EAAE,IAAI,CAAC;AAAA,IAC7H,GAAI,WAAW,OAAO,OAAO,OAAO,MAAM,IAAI,EAAE,OAAO,WAAW,OAAO,OAAO,OAAO,MAAM,EAAE,IAAI,CAAC;AAAA,IACpG,GAAI,WAAW,OAAO,YAAY,OAAO,WAAW,IAAI,EAAE,YAAY,WAAW,OAAO,YAAY,OAAO,WAAW,EAAE,IAAI,CAAC;AAAA,IAC7H,GAAI,WAAW,OAAO,SAAS,IAAI,EAAE,WAAW,WAAW,OAAO,SAAS,EAAwC,IAAI,CAAC;AAAA,IACxH,GAAI,WAAW,OAAO,aAAa,OAAO,YAAY,IAAI,EAAE,aAAa,WAAW,OAAO,aAAa,OAAO,YAAY,EAA0C,IAAI,CAAC;AAAA,IAC1K,GAAI,WAAW,OAAO,eAAe,OAAO,cAAc,IAAI,EAAE,eAAe,WAAW,OAAO,eAAe,OAAO,cAAc,EAAE,IAAI,CAAC;AAAA,IAC5I,GAAI,WAAW,OAAO,SAAS,IAAI,EAAE,WAAW,WAAW,OAAO,SAAS,EAAE,IAAI,CAAC;AAAA,IAClF,GAAI,WAAW,OAAO,KAAK,IAAI,EAAE,OAAO,WAAW,OAAO,KAAK,EAAE,IAAI,CAAC;AAAA,IACtE,GAAI,WAAW,OAAO,IAAI,IAAI,EAAE,MAAM,WAAW,OAAO,IAAI,EAAE,IAAI,CAAC;AAAA,IACnE,GAAI,YAAY,OAAO,mBAAmB,OAAO,mBAAmB,MAAM,SAAY,EAAE,mBAAmB,YAAY,OAAO,mBAAmB,OAAO,mBAAmB,EAAE,IAAI,CAAC;AAAA,IAClL,GAAI,WAAW,OAAO,YAAY,OAAO,WAAW,IAAI,EAAE,YAAY,WAAW,OAAO,YAAY,OAAO,WAAW,EAAE,IAAI,CAAC;AAAA,IAC7H,GAAI,WAAW,OAAO,WAAW,OAAO,UAAU,IAAI,EAAE,WAAW,WAAW,OAAO,WAAW,OAAO,UAAU,EAAE,IAAI,CAAC;AAAA,IACxH,GAAI,WAAW,OAAO,WAAW,OAAO,UAAU,IAAI,EAAE,WAAW,WAAW,OAAO,WAAW,OAAO,UAAU,EAAE,IAAI,CAAC;AAAA,IACxH,GAAI,WAAW,OAAO,gBAAgB,OAAO,gBAAgB,IAAI,EAAE,gBAAgB,WAAW,OAAO,gBAAgB,OAAO,gBAAgB,EAAE,IAAI,CAAC;AAAA,IACnJ,GAAI,YAAY,OAAO,UAAU,OAAO,SAAS,MAAM,SAAY,EAAE,UAAU,YAAY,OAAO,UAAU,OAAO,SAAS,EAAE,IAAI,CAAC;AAAA,EACvI;AACJ;;;AC/CO,SAAS,oBAAoB,MAAiE;AACjG,QAAM,SAAU,QAAQ,OAAO,SAAS,WAAW,OAAO,CAAC;AAC3D,SAAO,WAAW,OAAO,IAAI,OAAO,QAAQ,OAAO,OAAO;AAC9D;AAOO,SAAS,kBACZ,MACA,aACO;AACP,MAAI,CAAC,YAAa,QAAO;AACzB,QAAM,UAAU,YAAY,KAAK;AACjC,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,oBAAoB,IAAI,MAAM;AACzC;;;ACoKO,SAAS,uBAAuB,KAAyC;AAC5E,MAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,EAAG,QAAO;AAClE,QAAM,SAAS;AACf,QAAM,gBAAgB,OAAO,OAAO,aAAa;AACjD,QAAM,aAAa,OAAO,OAAO,UAAU;AAC3C,MAAI,CAAC,OAAO,SAAS,aAAa,KAAK,gBAAgB,EAAG,QAAO;AACjE,MAAI,CAAC,OAAO,SAAS,UAAU,KAAK,cAAc,EAAG,QAAO;AAC5D,SAAO,EAAE,GAAG,QAAQ,eAAe,WAAW;AAClD;AA4CO,IAAM,4BAA+C;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAGO,SAAS,cAAc,cAAkD;AAC5E,SAAO,CAAC,CAAC,gBAAgB,0BAA0B,SAAS,YAAY;AAC5E;AAqBO,SAAS,mBAAmB,OAA8D;AAC7F,QAAM,OAAO,OAAO;AACpB,QAAM,QAAQ,OAAO,MAAM,iBAAiB,WAAW,KAAK,aAAa,KAAK,IAAI;AAClF,QAAM,OAAO,OAAO,MAAM,aAAa,WAAW,KAAK,SAAS,KAAK,IAAI;AACzE,QAAM,QAAQ,CAAC,OAAO,IAAI,EAAE,OAAO,OAAO;AAC1C,SAAO,MAAM,SAAS,IAAI,MAAM,KAAK,QAAK,IAAI;AAClD;AAOO,IAAM,8BAAiD,CAAC,cAAc,aAAa,YAAY;AAG/F,SAAS,kCAAkC,OAAqC;AACnF,QAAM,SAAS,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,CAAC,MAAO,OAAO,MAAM,WAAW,EAAE,KAAK,IAAI,EAAG,EAAE,OAAO,OAAO,CAAC,CAAC;AACrG,QAAM,OAAO,CAAC,MAAc;AACxB,UAAM,IAAI,4BAA4B,QAAQ,CAAC;AAC/C,WAAO,IAAI,IAAI,4BAA4B,SAAS;AAAA,EACxD;AACA,SAAO,OAAO,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;AACxE;AAeO,SAAS,qCAAqC,OAA0B;AAC3E,QAAM,IAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAAI,QAAmC;AAC3G,QAAM,aAAa,GAAG;AACtB,MAAI,CAAC,cAAc,OAAO,eAAe,YAAY,MAAM,QAAQ,UAAU,EAAG,QAAO,CAAC;AACxF,QAAM,UAAU,OAAO,QAAQ,UAAqC,EAC/D,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,OAAO,MAAM,YAAa,EAA8B,YAAY,IAAI,EACjG,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AACzB,QAAM,WAAW,GAAG;AACpB,QAAM,WAAW,YAAY,OAAO,aAAa,YAAY,CAAC,MAAM,QAAQ,QAAQ,IAC9E,QAAQ,OAAO,CAAC,SAAS;AACvB,UAAM,IAAK,SAAqC,IAAI;AACpD,WAAO,OAAO,MAAM,YAAY,CAAC,CAAC,EAAE,KAAK;AAAA,EAC7C,CAAC,IACC,CAAC;AACP,SAAO,kCAAkC,SAAS,SAAS,WAAW,OAAO;AACjF;;;ACzUO,SAAS,iCAAiC,KAA6B;AAC1E,MAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,SAAO,IAAI,KAAK,EAAE,QAAQ,WAAW,GAAG,EAAE,QAAQ,QAAQ,EAAE,EAAE,YAAY;AAC9E;AASO,SAAS,yBAAyB,GAAmB,GAA4B;AACpF,QAAM,OAAO,iCAAiC,CAAC;AAC/C,QAAM,QAAQ,iCAAiC,CAAC;AAChD,MAAI,CAAC,QAAQ,CAAC,MAAO,QAAO;AAC5B,SAAO,SAAS;AACpB;;;ACJA,IAAM,qBAAqB,CAAC,WAAW,aAAa;AAQ7C,SAAS,gBAAgBA,KAAwC;AACpE,QAAM,UAAU,WAAWA,GAAE;AAC7B,SAAO,CAAC,CAAC,WAAW,kBAAkB,KAAK,OAAO;AACtD;AAwCO,SAAS,qBACZ,OACO;AACP,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,CAAC,gBAAgB,MAAM,EAAE,EAAG,QAAO;AACvC,QAAM,qBAAqB;AAAA,IACvB,WAAW,MAAM,eAAe,KAC7B,WAAW,MAAM,QAAQ,KACzB,WAAW,MAAM,QAAQ,KACzB,WAAW,MAAM,QAAQ,KACzB,WAAW,MAAM,SAAS,QAAQ,KAClC,WAAW,MAAM,SAAS,QAAQ,KAClC,WAAW,MAAM,SAAS,KACzB,MAAM,QAAQ,MAAM,QAAQ,KAAK,MAAM,SAAS,SAAS;AAAA,EACjE;AACA,SAAO,CAAC;AACZ;AAOO,SAAS,wBAAwBA,KAAmD;AACvF,QAAM,UAAU,WAAWA,GAAE;AAC7B,MAAI,CAAC,QAAS,QAAO;AACrB,aAAW,UAAU,oBAAoB;AACrC,QAAI,QAAQ,WAAW,MAAM,GAAG;AAC5B,YAAM,OAAO,QAAQ,MAAM,OAAO,MAAM,EAAE,KAAK;AAC/C,aAAO,QAAQ;AAAA,IACnB;AAAA,EACJ;AACA,SAAO;AACX;AA0BO,SAAS,kBAAkBA,KAAmD;AACjF,QAAM,OAAO,wBAAwBA,GAAE;AACvC,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,CAAC,KAAK,WAAW,OAAO,EAAG,QAAO;AACtC,SAAO,UAAU,IAAI;AACzB;AAIO,SAAS,oBAAoB,GAA8B,GAAuC;AACrG,QAAM,QAAQ,wBAAwB,CAAC;AACvC,QAAM,QAAQ,wBAAwB,CAAC;AACvC,MAAI,CAAC,SAAS,CAAC,MAAO,QAAO;AAC7B,SAAO,UAAU;AACrB;AAcO,SAAS,oBACZ,KACQ;AACR,QAAM,OAAO,MAAM,QAAQ,GAAG,IAAI,MAAM,OAAO,OAAO,CAAC,GAAG,IAAI,CAAC;AAC/D,QAAM,MAAgB,CAAC;AACvB,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAAM,CAAC,UAAoC;AAC7C,QAAI,CAAC,SAAS,KAAK,IAAI,KAAK,EAAG;AAC/B,SAAK,IAAI,KAAK;AACd,QAAI,KAAK,KAAK;AAAA,EAClB;AAEA,aAAW,OAAO,KAAM,KAAI,WAAW,GAAG,CAAC;AAE3C,aAAW,OAAO,MAAM;AACpB,UAAM,OAAO,wBAAwB,WAAW,GAAG,CAAC;AACpD,QAAI,CAAC,QAAQ,CAAC,KAAK,WAAW,OAAO,EAAG;AACxC,QAAI,IAAI;AACR,eAAW,UAAU,mBAAoB,KAAI,GAAG,MAAM,GAAG,IAAI,EAAE;AAAA,EACnE;AACA,SAAO;AACX;;;ACpLO,SAAS,kBAAkB,QAAiD;AAC/E,QAAM,SAAS,WAAW,MAAM;AAChC,MAAI,CAAC,OAAO,KAAK,MAAM,EAAE,OAAQ,QAAO;AACxC,QAAM,aAAa,MAAM,QAAQ,OAAO,UAAU,IAC5C,OAAO,WAAW,IAAI,CAAC,UAAmB;AACxC,UAAM,MAAM,WAAW,KAAK;AAC5B,WAAO;AAAA,MACH,MAAM,WAAW,IAAI,IAAI,KAAK;AAAA,MAC9B,QAAQ,WAAW,IAAI,MAAM,GAAG,MAAM,GAAG,EAAE,KAAK;AAAA,MAChD,OAAO,YAAY,IAAI,KAAK,KAAK;AAAA,MACjC,WAAW,YAAY,IAAI,WAAW,IAAI,WAAW,KAAK;AAAA,IAC9D;AAAA,EACJ,CAAC,IACC,CAAC;AACP,SAAO;AAAA,IACH,WAAW,YAAY,OAAO,SAAS;AAAA,IACvC,WAAW,WAAW,OAAO,SAAS,KAAK;AAAA,IAC3C,UAAU,WAAW,OAAO,UAAU,OAAO,SAAS,KAAK;AAAA,IAC3D,QAAQ,WAAW,OAAO,MAAM,KAAK;AAAA,IACrC,UAAU,WAAW,OAAO,QAAQ,KAAK;AAAA,IACzC,gBAAgB,WAAW,OAAO,gBAAgB,OAAO,eAAe,KAAK;AAAA,IAC7E,YAAY,WAAW,OAAO,YAAY,OAAO,WAAW,GAAG,MAAM,GAAG,EAAE,KAAK;AAAA,IAC/E,OAAO,WAAW,OAAO,KAAK,KAAK;AAAA,IACnC,QAAQ,WAAW,OAAO,MAAM,KAAK;AAAA,IACrC,aAAa;AAAA,MACT,QAAQ,WAAW,OAAO,MAAM,KAAK;AAAA,MACrC,UAAU,WAAW,OAAO,QAAQ,KAAK;AAAA,MACzC,WAAW,WAAW,OAAO,SAAS,KAAK;AAAA,MAC3C,SAAS,WAAW,OAAO,OAAO,KAAK;AAAA,MACvC,SAAS,WAAW,OAAO,OAAO,KAAK;AAAA,IAC3C;AAAA,IACA,eAAe,WAAW,OAAO,eAAe,OAAO,eAAe,KAAK;AAAA,IAC3E,gBAAgB,WAAW;AAAA,IAC3B;AAAA,EACJ;AACJ;;;AC3BA,SAAS,iBAAiB,MAAc,UAAwD;AAC5F,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,YAAY,MAAM,SAAS;AACjC,SAAO;AAAA,IACH,MAAM,YAAY,MAAM,MAAM,GAAG,QAAQ,EAAE,KAAK,IAAI,IAAI,sBAAsB;AAAA,IAC9E;AAAA,EACJ;AACJ;AAGO,SAAS,mBACZ,MACA,WACA,UACc;AACd,QAAM,MAAM,WAAW,SAAS;AAChC,QAAM,IAAI,WAAW,IAAI,QAAQ,SAAS;AAC1C,QAAM,OAAO,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO;AACnD,QAAM,EAAE,MAAM,UAAU,IAAI,iBAAiB,MAAM,QAAQ;AAC3D,SAAO;AAAA,IACH,MAAM,KAAK;AAAA,IACX,UAAU,KAAK,WAAW;AAAA,IAC1B,QAAQ,KAAK,UAAU;AAAA,IACvB;AAAA,IACA;AAAA,IACA,QAAQ,OAAO,EAAE,WAAW,YAAY,EAAE,SAAS;AAAA,EACvD;AACJ;;;ACjCO,IAAM,yBAA+C,CAAC,QAAQ,UAAU,aAAa,UAAU;AA+B/F,SAAS,qBAAqB,OAA6C;AAC9E,SAAO,OAAO,UAAU,YAAa,uBAAoC,SAAS,KAAK;AAC3F;AAgCO,IAAM,4BAAgD,CAAC;AAGvD,SAAS,uBAAuB,OAAuD;AAC1F,QAAM,IAAI,OAAO,UAAU,WAAW,MAAM,KAAK,EAAE,YAAY,IAAI;AACnE,SAAO,MAAM,SAAS,MAAM,YAAY,MAAM,SAAS,IAAI;AAC/D;AAGO,SAAS,mBAAmB,KAAyB;AACxD,QAAM,IAAK,OAAO,OAAO,QAAQ,WAAY,MAAiC,CAAC;AAC/E,QAAM,WAAW,OAAO,EAAE,aAAa,WAAW,EAAE,SAAS,KAAK,IAAI;AACtE,QAAM,QAAQ,OAAO,EAAE,UAAU,WAAW,EAAE,MAAM,KAAK,IAAI;AAC7D,QAAM,gBAAgB,uBAAuB,EAAE,aAAa;AAC5D,SAAO;AAAA,IACH,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,IAC/B,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IACzB,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;AAAA,EAC7C;AACJ;AAGO,SAAS,4BAA4B,KAAkC;AAC1E,QAAM,MAA0B,CAAC;AACjC,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,aAAW,OAAO,wBAAwB;AACtC,UAAM,OAAO,mBAAoB,IAAgC,GAAG,CAAC;AACrE,QAAI,KAAK,YAAY,KAAK,SAAS,KAAK,cAAe,KAAI,GAAG,IAAI;AAAA,EACtE;AACA,SAAO;AACX;AA4CO,SAAS,4BAA4B,KAAyC;AACjF,QAAM,IAAK,OAAO,OAAO,QAAQ,WAAY,MAAiC,CAAC;AAC/E,QAAM,WAAW,OAAO,EAAE,aAAa,WAAW,EAAE,SAAS,KAAK,IAAI;AACtE,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,QAAQ,OAAO,EAAE,UAAU,WAAW,EAAE,MAAM,KAAK,IAAI;AAG7D,QAAM,gBAAgB,OAAO,EAAE,kBAAkB,WAAW,EAAE,cAAc,KAAK,IAAI;AACrF,QAAM,aAAa,MAAM,QAAQ,EAAE,UAAU,IACtC,EAAE,WAAW,OAAO,oBAAoB,IACzC,CAAC;AACP,QAAM,aAAa,MAAM,QAAQ,EAAE,UAAU,IACvC,EAAE,WAAW,OAAO,CAAC,MAAmB,OAAO,MAAM,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC,IAC9F,CAAC;AACP,QAAM,iBAAiB,OAAO,EAAE,WAAW;AAC3C,QAAM,cAAc,OAAO,SAAS,cAAc,KAAK,iBAAiB,IAAI,KAAK,MAAM,cAAc,IAAI;AACzG,SAAO;AAAA,IACH;AAAA,IACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IACzB,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;AAAA,IACzC,GAAI,WAAW,SAAS,EAAE,WAAW,IAAI,CAAC;AAAA,IAC1C,GAAI,WAAW,SAAS,EAAE,WAAW,IAAI,CAAC;AAAA,IAC1C,GAAI,gBAAgB,SAAY,EAAE,YAAY,IAAI,CAAC;AAAA,EACvD;AACJ;AAGO,SAAS,6BAA6B,KAAoC;AAC7E,MAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO,CAAC;AACjC,QAAM,MAA4B,CAAC;AACnC,aAAW,SAAS,KAAK;AACrB,UAAM,OAAO,4BAA4B,KAAK;AAC9C,QAAI,KAAM,KAAI,KAAK,IAAI;AAAA,EAC3B;AACA,SAAO;AACX;AAgBO,SAAS,sBAAsB,OAGb;AACrB,QAAM,WAAW,MAAM,QAAQ,MAAM,gBAAgB,IAC/C,MAAM,iBAAiB,OAAO,CAAC,MAAmB,OAAO,MAAM,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC,IACxG,CAAC;AACP,MAAI,SAAS,WAAW,EAAG,QAAO,CAAC;AAInC,QAAM,SAAS,MAAM,oBAAoB,CAAC;AAC1C,QAAM,aAAa,oBAAI,IAAkH;AACzI,QAAM,SAA+G,CAAC;AACtH,aAAW,QAAQ,wBAAwB;AACvC,UAAM,IAAI,OAAO,IAAI;AACrB,QAAI,CAAC,EAAG;AACR,UAAM,QAAQ,EAAE,YAAY,MAAM,OAAO,EAAE,OAAO,eAAe,EAAE,cAAc;AACjF,QAAI,EAAE,UAAU;AACZ,YAAM,OAAO,WAAW,IAAI,EAAE,QAAQ,KAAK,CAAC;AAC5C,WAAK,KAAK,KAAK;AACf,iBAAW,IAAI,EAAE,UAAU,IAAI;AAAA,IACnC,OAAO;AACH,aAAO,KAAK,KAAK;AAAA,IACrB;AAAA,EACJ;AAEA,SAAO,SAAS,IAAI,CAAC,aAAiC;AAElD,UAAM,WAAW,WAAW,IAAI,QAAQ,KAAK,CAAC;AAC9C,UAAM,UAAU,SAAS,SAAS,WAAW;AAC7C,UAAM,aAAa,QAAQ,IAAI,OAAK,EAAE,UAAU;AAEhD,UAAM,QAAQ,QAAQ,KAAK,OAAK,EAAE,KAAK,GAAG;AAC1C,UAAM,gBAAgB,QAAQ,KAAK,OAAK,EAAE,aAAa,GAAG;AAC1D,WAAO;AAAA,MACH;AAAA,MACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,MACzB,GAAI,gBAAgB,EAAE,cAAc,IAAI,CAAC;AAAA,MACzC,GAAI,WAAW,SAAS,EAAE,WAAW,IAAI,CAAC;AAAA,IAC9C;AAAA,EACJ,CAAC;AACL;AAcO,SAAS,gCAAgC,OAA0B;AACtE,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAAgB,CAAC;AACvB,aAAW,QAAQ,6BAA6B,KAAK,GAAG;AACpD,QAAI,KAAK,IAAI,KAAK,QAAQ,EAAG;AAC7B,SAAK,IAAI,KAAK,QAAQ;AACtB,QAAI,KAAK,KAAK,QAAQ;AAAA,EAC1B;AACA,SAAO;AACX;;;ACxMO,IAAM,mBAAuE,OAAO,OAAiD;AAAA,EACxI,cAAc;AAAA,IACV;AAAA,MACI,OAAO;AAAA,MACP,eAAe;AAAA,MACf,YAAY,CAAC,UAAU,MAAM;AAAA,MAC7B,aAAa;AAAA,MACb,WAAW;AAAA,IACf;AAAA,IACA;AAAA,MACI,OAAO;AAAA,MACP,eAAe;AAAA,MACf,YAAY,CAAC,WAAW;AAAA,MACxB,aAAa;AAAA,MACb,WAAW;AAAA,IACf;AAAA,EACJ;AAAA,EACA,QAAQ;AAAA,IACJ;AAAA,MACI,OAAO;AAAA,MACP,YAAY,CAAC,UAAU,WAAW;AAAA,MAClC,aAAa;AAAA,MACb,WAAW;AAAA,IACf;AAAA,EACJ;AAAA,EACA,aAAa;AAAA,IACT;AAAA,MACI,YAAY,CAAC,UAAU,aAAa,UAAU;AAAA,MAC9C,aAAa;AAAA,MACb,WAAW;AAAA,IACf;AAAA,EACJ;AAAA,EACA,mBAAmB;AAAA,IACf;AAAA,MACI,OAAO;AAAA,MACP,YAAY,CAAC,MAAM;AAAA,MACnB,aAAa;AAAA,MACb,WAAW;AAAA,IACf;AAAA,EACJ;AAAA,EACA,cAAc;AAAA,IACV;AAAA,MACI,OAAO;AAAA,MACP,YAAY,CAAC,MAAM;AAAA,MACnB,aAAa;AAAA,MACb,WAAW;AAAA,IACf;AAAA,EACJ;AACJ,CAAC;AAOM,IAAM,0BAAmD,OAAO,OAAsB;AAAA,EACzF,YAAY,CAAC,QAAQ;AAAA,EACrB,aAAa;AAAA,EACb,aAAa;AAAA,EACb,WAAW;AACf,CAAC;AA8CD,SAAS,QAAQ,MAAkC;AAC/C,SAAO;AAAA,IACH,KAAK;AAAA,IACL,KAAK,SAAS;AAAA,IACd,KAAK,iBAAiB;AAAA,IACtB,CAAC,GAAI,KAAK,cAAc,CAAC,CAAE,EAAE,KAAK,EAAE,KAAK,GAAG;AAAA,IAC5C,CAAC,GAAI,KAAK,cAAc,CAAC,CAAE,EAAE,KAAK,EAAE,KAAK,GAAG;AAAA,IAC5C,KAAK,eAAe;AAAA,EACxB,EAAE,KAAK,IAAQ;AACnB;AAGA,SAAS,eAAe,UAAiE;AACrF,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAA6B,CAAC;AACpC,aAAW,KAAK,UAAU;AACtB,UAAM,OAAO,OAAO,GAAG,SAAS,WAAW,EAAE,KAAK,KAAK,IAAI;AAC3D,QAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,EAAG;AAC7B,SAAK,IAAI,IAAI;AACb,QAAI,KAAK,EAAE,GAAG,GAAG,KAAK,CAAC;AAAA,EAC3B;AACA,SAAO;AACX;AAYO,SAAS,kBACZ,UACA,eAA8C,CAAC,GACnC;AACZ,QAAM,YAAY,eAAe,YAAY,CAAC,CAAC;AAC/C,QAAM,gBAAsC,CAAC;AAC7C,QAAM,UAA+B,CAAC;AACtC,QAAM,mBAA6B,CAAC;AACpC,QAAM,uBAAiC,CAAC;AAExC,aAAW,YAAY,WAAW;AAC9B,UAAM,QAAQ,iBAAiB,SAAS,IAAI;AAC5C,UAAM,UAAoC,SAAS,CAAC,uBAAuB;AAC3E,UAAM,YAAY,CAAC;AACnB,QAAI,UAAW,kBAAiB,KAAK,SAAS,IAAI;AAElD,QAAI,sBAAsB;AAC1B,eAAW,UAAU,SAAS;AAG1B,YAAM,OAAO,4BAA4B;AAAA,QACrC,UAAU,SAAS;AAAA,QACnB,OAAO,OAAO;AAAA,QACd,eAAe,OAAO;AAAA,QACtB,YAAY,OAAO;AAAA,QACnB,aAAa,OAAO;AAAA,MACxB,CAAC;AACD,UAAI,CAAC,KAAM;AACX,YAAM,cAAc,OAAO,gBAAgB;AAC3C,UAAI,YAAa,uBAAsB;AACvC,oBAAc,KAAK,IAAI;AACvB,cAAQ,KAAK;AAAA,QACT;AAAA,QACA,iBAAiB;AAAA,QACjB;AAAA,QACA,GAAI,OAAO,YAAY,EAAE,WAAW,OAAO,UAAU,IAAI,CAAC;AAAA,MAC9D,CAAC;AAAA,IACL;AACA,QAAI,oBAAqB,sBAAqB,KAAK,SAAS,IAAI;AAAA,EACpE;AAIA,QAAM,eAAe,IAAI,IAAI,cAAc,IAAI,OAAO,CAAC;AACvD,QAAM,eAAe,aAAa,OAAO,UAAQ,CAAC,aAAa,IAAI,QAAQ,IAAI,CAAC,CAAC;AACjF,QAAM,oBAAoB,IAAI,IAAI,cAAc,IAAI,OAAK,EAAE,QAAQ,CAAC;AACpE,QAAM,mBAAmB,CAAC,GAAG,IAAI;AAAA,IAC7B,aAAa,IAAI,OAAK,EAAE,QAAQ,EAAE,OAAO,OAAK,CAAC,kBAAkB,IAAI,CAAC,CAAC;AAAA,EAC3E,CAAC;AAED,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,aAAa,SAAS;AAAA,EACvC;AACJ;;;AC3QO,SAAS,kBAAkB,UAAkB,KAAsC;AACxF,SAAO,SAAS,QAAQ,kBAAkB,CAAC,GAAG,QAAQ;AACpD,UAAM,MAAM,IAAI,GAAG;AACnB,WAAO,QAAQ,SAAY,OAAO,GAAG,IAAI,KAAK,GAAG;AAAA,EACnD,CAAC;AACH;;;ACcO,IAAM,4BAA4B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAKO,IAAM,4BAA4B,0BAA0B;AAe5D,IAAM,qBAIP;AAAA,EACF,qBAAqB,EAAE,MAAM,mBAAmB,MAAM,EAAE,QAAQ,MAAM,EAAE;AAAA,EACxE,sBAAsB,EAAE,MAAM,mBAAmB,MAAM,EAAE,QAAQ,OAAO,EAAE;AAAA,EAC1E,yBAAyB,EAAE,MAAM,mBAAmB,MAAM,EAAE,QAAQ,UAAU,EAAE;AAAA,EAChF,kBAAkB,EAAE,MAAM,aAAa,MAAM,EAAE,QAAQ,SAAS,EAAE;AAAA,EAClE,kBAAkB,EAAE,MAAM,aAAa,MAAM,EAAE,QAAQ,SAAS,EAAE;AAAA,EAClE,aAAa,EAAE,MAAM,aAAa,MAAM,EAAE,MAAM,SAAS,EAAE;AAAA,EAC3D,oBAAoB,EAAE,MAAM,eAAe,MAAM,EAAE,MAAM,SAAS,EAAE;AAAA,EACpE,2BAA2B,EAAE,MAAM,eAAe,MAAM,EAAE,MAAM,gBAAgB,EAAE;AAAA,EAClF,6BAA6B,EAAE,MAAM,eAAe,MAAM,EAAE,MAAM,YAAY,EAAE;AAAA,EAChF,sBAAsB,EAAE,MAAM,eAAe,MAAM,EAAE,MAAM,OAAO,EAAE;AAAA,EACpE,yBAAyB,EAAE,MAAM,yBAAyB,MAAM,EAAE,MAAM,qBAAqB,EAAE;AACnG;AAEA,IAAM,oCAAoC;AAMnC,IAAM,qBAAuD;AAAA,EAChE,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,2BAA2B;AAAA;AAAA,EAE3B,kBAAkB;AAAA;AAAA,EAElB,gCAAgC;AAAA,EAChC,oCAAoC;AAAA,EACpC,oCAAoC;AACxC;AAOO,SAAS,qBAAqB,MAA6B;AAC9D,MAAI,OAAO,UAAU,eAAe,KAAK,oBAAoB,IAAI,GAAG;AAChE,WAAO,SAAS,IAAI,kBAAkB,mBAAmB,IAAI,CAAC;AAAA,EAClE;AACA,QAAM,QAAQ,OAAO,UAAU,eAAe,KAAK,oBAAoB,IAAI,IAAI,mBAAmB,IAAI,IAAI;AAC1G,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,gBAAgB,OAAO,QAAQ,MAAM,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,IAAI;AAC1F,SAAO,SAAS,IAAI,8BAA8B,MAAM,IAAI,WAAW,MAAM,IAAI,SAAS,aAAa,oCAChG,MAAM,OAAO,IAAI,MAAM,IAAI,KAAK;AAC3C;;;ACnHO,IAAM,uBAAuB;AAG7B,SAAS,sBACd,OAAgC,CAAC,GACR;AACzB,SAAO,EAAE,GAAG,MAAM,CAAC,oBAAoB,GAAG,KAAK;AACjD;AAGO,SAAS,2BAA2B,MAAwB;AACjE,SACE,CAAC,CAAC,QACF,OAAO,SAAS,YACf,KAAiC,oBAAoB,MAAM;AAEhE;AAOO,SAAS,uBACd,MACyB;AACzB,MAAI,CAAC,2BAA2B,IAAI,EAAG,QAAO;AAC9C,QAAM,EAAE,CAAC,oBAAoB,GAAG,OAAO,GAAG,KAAK,IAAI;AACnD,SAAO;AACT;;;AClBO,IAAM,8BAA8B;AAkBpC,IAAM,2BAA2B;AAOjC,IAAM,kBAAkB;AAOxB,IAAM,6BAA6B;AAOnC,IAAM,oBAAoB;AAG1B,IAAM,kBAAkB;AAoCxB,SAAS,mBAAmB,OAAuB;AACxD,MAAI,OAAO,gBAAgB,YAAa,QAAO,IAAI,YAAY,EAAE,OAAO,KAAK,EAAE;AAC/E,MAAI,QAAQ;AACZ,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;AACxC,UAAM,OAAO,MAAM,WAAW,CAAC;AAC/B,QAAI,OAAO,IAAM,UAAS;AAAA,aACjB,OAAO,KAAO,UAAS;AAAA,aACvB,QAAQ,SAAU,QAAQ,OAAQ;AAAE,eAAS;AAAG,WAAK;AAAA,IAAE,MAC3D,UAAS;AAAA,EAChB;AACA,SAAO;AACT;AAYO,SAAS,qCAA6C;AAC3D,QAAM,UAAU,SAAI,OAAO,wBAAwB;AACnD,SAAO,mBAAmB,KAAK;AAAA,IAC7B,mBAAmB,OAAO,kBAAkB,IAAI,OAAO,EAAE,GAAG,iBAAiB,iBAAiB,OAAO;AAAA,EACvG,CAAC;AACH;AAGO,SAAS,uBAAuB,MAAuB;AAC5D,SAAO,mBAAmB,IAAI,IAAI;AACpC;AAEA,SAAS,mBACP,SAAiB,SAAiB,OAAe,OAAe,MAC7C;AACnB,SAAO,EAAE,GAAG,SAAS,MAAM,iBAAiB,SAAS,OAAO,OAAO,KAAK;AAC1E;AAUO,SAAS,eAAe,MAAc,SAAiB,SAAuC;AACnG,QAAM,SAAmB,CAAC;AAC1B,MAAI,SAAS;AACb,SAAO,SAAS,KAAK,QAAQ;AAC3B,QAAI,MAAM,KAAK,IAAI,KAAK,QAAQ,SAAS,wBAAwB;AAIjE,WAAO,MAAM,QAAQ;AACnB,YAAM,YAAY,KAAK,MAAM,QAAQ,GAAG;AACxC,YAAM,QAAQ,KAAK,UAAU,mBAAmB,SAAS,SAAS,OAAO,QAAQ,iBAAiB,SAAS,CAAC;AAC5G,UAAI,mBAAmB,KAAK,KAAK,4BAA6B;AAC9D,YAAM,SAAS,KAAK,IAAI,GAAG,KAAK,OAAO,MAAM,UAAU,GAAG,CAAC;AAC3D,UAAI,SAAS,UAAU,KAAK;AAAE,eAAO;AAAG;AAAA,MAAS;AACjD,YAAM,SAAS;AAAA,IACjB;AACA,QAAI,OAAO,QAAQ;AACjB,aAAO,EAAE,IAAI,OAAO,QAAQ,mBAAmB,QAAQ,2DAA2D;AAAA,IACpH;AACA,WAAO,KAAK,KAAK,MAAM,QAAQ,GAAG,CAAC;AACnC,QAAI,OAAO,SAAS,iBAAiB;AACnC,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,QAAQ;AAAA,QACR,QAAQ,yBAAyB,eAAe,YAAY,mBAAmB,IAAI,CAAC;AAAA,MACtF;AAAA,IACF;AACA,aAAS;AAAA,EACX;AACA,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO,EAAE,IAAI,OAAO,QAAQ,mBAAmB,QAAQ,mCAAmC;AAAA,EAC5F;AACA,QAAM,QAAQ,OAAO;AACrB,SAAO,EAAE,IAAI,MAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,UAAU,mBAAmB,SAAS,SAAS,OAAO,OAAO,IAAI,CAAC,EAAE;AACnH;AAgBO,IAAM,qBAAN,MAAyB;AAAA,EAG9B,YAA6B,MAAoB,MAAM,KAAK,IAAI,GAAG;AAAtC;AAAA,EAAuC;AAAA,EAFnD,UAAU,oBAAI,IAA6B;AAAA;AAAA,EAK5D,OAAO,aAAa,OAAyB;AAC3C,WAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAa,MAA6B,SAAS;AAAA,EACxF;AAAA;AAAA,EAGQ,QAAc;AACpB,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,CAAC,KAAK,KAAK,KAAK,MAAM,KAAK,KAAK,QAAQ,QAAQ,CAAC,GAAG;AAC7D,UAAI,MAAM,MAAM,YAAY,kBAAmB,MAAK,QAAQ,OAAO,GAAG;AAAA,IACxE;AAAA,EACF;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,QAAQ,MAAM;AAAA,EACrB;AAAA;AAAA,EAGA,IAAI,eAAuB;AACzB,WAAO,KAAK,QAAQ;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAO,OAAuC;AAC5C,SAAK,MAAM;AACX,UAAM,MAAM;AACZ,UAAM,UAAU,OAAO,KAAK,YAAY,WAAW,IAAI,UAAU;AACjE,UAAM,QAAQ,OAAO,KAAK,KAAK;AAC/B,UAAM,QAAQ,OAAO,KAAK,KAAK;AAC/B,UAAM,OAAO,OAAO,KAAK,SAAS,WAAW,IAAI,OAAO;AAExD,QAAI,CAAC,WAAW,CAAC,OAAO,UAAU,KAAK,KAAK,CAAC,OAAO,UAAU,KAAK,KAC9D,QAAQ,KAAK,SAAS,KAAK,SAAS,SAAS,CAAC,MAAM;AACvD,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,QAAQ,qCAAqC,WAAW,GAAG,UAAU,KAAK,KAAK,UAAU,KAAK,KAAK;AAAA,QACnG;AAAA,MACF;AAAA,IACF;AACA,QAAI,QAAQ,iBAAiB;AAC3B,WAAK,QAAQ,OAAO,OAAO;AAC3B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,QAAQ,eAAe,KAAK,gBAAgB,eAAe;AAAA,QAC3D;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAQ,KAAK,QAAQ,IAAI,OAAO;AACpC,QAAI,CAAC,OAAO;AACV,cAAQ,EAAE,OAAO,QAAQ,IAAI,MAAM,KAAK,EAAE,KAAK,EAAE,GAAG,UAAU,GAAG,eAAe,GAAG,WAAW,KAAK,IAAI,EAAE;AACzG,WAAK,QAAQ,IAAI,SAAS,KAAK;AAAA,IACjC,WAAW,MAAM,UAAU,OAAO;AAGhC,WAAK,QAAQ,OAAO,OAAO;AAC3B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,QAAQ,SAAS,KAAK,mBAAmB,KAAK,kCAAkC,MAAM,KAAK;AAAA,QAC3F;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,OAAO,KAAK;AACnC,QAAI,UAAU;AAGZ,UAAI,aAAa,KAAM,QAAO,EAAE,QAAQ,WAAW,UAAU,MAAM,UAAU,OAAO,MAAM,MAAM;AAChG,WAAK,QAAQ,OAAO,OAAO;AAC3B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,QAAQ,SAAS,KAAK;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,aAAa,mBAAmB,IAAI;AAC1C,QAAI,MAAM,gBAAgB,aAAa,4BAA4B;AACjE,WAAK,QAAQ,OAAO,OAAO;AAC3B,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,QAAQ,kCAAkC,0BAA0B;AAAA,QACpE;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,IAAI;AACtB,UAAM,YAAY;AAClB,UAAM,iBAAiB;AACvB,QAAI,MAAM,WAAW,MAAM,OAAO;AAChC,aAAO,EAAE,QAAQ,WAAW,UAAU,MAAM,UAAU,OAAO,MAAM,MAAM;AAAA,IAC3E;AAEA,SAAK,QAAQ,OAAO,OAAO;AAC3B,QAAI;AACF,aAAO,EAAE,QAAQ,YAAY,OAAO,KAAK,MAAM,MAAM,OAAO,KAAK,EAAE,CAAC,EAAE;AAAA,IACxE,SAAS,OAAO;AAGd,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,QAAQ,wCAAwC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QACtG;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AClSA,IAAM,iBAAiB;AACvB,IAAM,qBAAqB;AAOpB,SAAS,YAAY,SAAuC;AAC/D,MAAI,OAAO,YAAY,SAAU,QAAO;AACxC,QAAM,QAAQ,QAAQ,KAAK,EAAE,QAAQ,MAAM,EAAE,EAAE,MAAM,cAAc;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO;AAAA,IACH,OAAO,OAAO,MAAM,CAAC,CAAC;AAAA,IACtB,OAAO,OAAO,MAAM,CAAC,CAAC;AAAA,IACtB,OAAO,OAAO,MAAM,CAAC,CAAC;AAAA,IACtB,YAAY,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;AAAA,EAClD;AACJ;AAQA,SAAS,kBAAkB,GAAsB,GAA8B;AAC3E,MAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EAAG,QAAO;AAE7C,MAAI,EAAE,WAAW,EAAG,QAAO;AAC3B,MAAI,EAAE,WAAW,EAAG,QAAO;AAC3B,WAAS,IAAI,GAAG,IAAI,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG;AACtD,UAAM,MAAM,EAAE,CAAC;AACf,UAAM,MAAM,EAAE,CAAC;AACf,QAAI,QAAQ,IAAK;AACjB,UAAM,OAAO,mBAAmB,KAAK,GAAG;AACxC,UAAM,OAAO,mBAAmB,KAAK,GAAG;AACxC,QAAI,QAAQ,KAAM,QAAO,OAAO,GAAG,IAAI,OAAO,GAAG,IAAI,KAAK;AAC1D,QAAI,KAAM,QAAO;AACjB,QAAI,KAAM,QAAO;AACjB,WAAO,MAAM,MAAM,KAAK;AAAA,EAC5B;AACA,SAAO,EAAE,WAAW,EAAE,SAAS,IAAK,EAAE,SAAS,EAAE,SAAS,KAAK;AACnE;AAUO,SAAS,cAAc,GAAY,GAA2B;AACjE,QAAM,KAAK,YAAY,CAAC;AACxB,QAAM,KAAK,YAAY,CAAC;AACxB,MAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,MAAI,GAAG,UAAU,GAAG,MAAO,QAAO,GAAG,QAAQ,GAAG,QAAQ,KAAK;AAC7D,MAAI,GAAG,UAAU,GAAG,MAAO,QAAO,GAAG,QAAQ,GAAG,QAAQ,KAAK;AAC7D,MAAI,GAAG,UAAU,GAAG,MAAO,QAAO,GAAG,QAAQ,GAAG,QAAQ,KAAK;AAC7D,SAAO,kBAAkB,GAAG,YAAY,GAAG,UAAU;AACzD;AAWO,SAAS,YAAY,SAAkB,QAA0B;AACpE,QAAM,YAAY,cAAc,QAAQ,OAAO;AAC/C,MAAI,cAAc,KAAM,QAAO;AAC/B,SAAO,YAAY;AACvB;;;ACpFO,SAAS,SAAS,OAAkD;AACvE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC9E;AAEO,SAAS,iBAAiB,OAAiC;AAC9D,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS;AACvD;AAEO,SAAS,eAAe,OAAiC;AAC5D,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAC7D;AAEO,SAAS,cAA2C,OAAkD;AACzG,QAAM,MAA2B,IAAI,IAAI,KAAK;AAC9C,SAAO,CAAC,UAAuC,OAAO,UAAU,YAAY,IAAI,IAAI,KAAK;AAC7F;AAUO,SAAS,gBAAkC,KAAc,QAA4F;AACxJ,MAAI,CAAC,SAAS,GAAG,EAAG,QAAO;AAC3B,MAAI,CAAC,OAAO,IAAI,IAAI,EAAG,QAAO;AAC9B,SAAO,EAAE,MAAM,IAAI,MAAM,OAAO,IAAI;AACxC;AAGO,SAAS,mBAAmB,OAAwE;AACvG,SAAO;AAAA,IACH,GAAI,iBAAiB,MAAM,EAAE,IAAI,EAAE,IAAI,MAAM,GAAG,IAAI,CAAC;AAAA,IACrD,GAAI,eAAe,MAAM,SAAS,IAAI,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,EAC5E;AACJ;;;AC3BO,IAAM,4BAA4B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAEO,IAAM,0BAA0B,cAAc,yBAAyB;AAqFvE,IAAM,mBAAmB,CAAC,UAAU,SAAS;AAE7C,IAAM,kBAAkB,CAAC,UAAU,MAAM;AAEzC,IAAM,yBAAyB,CAAC,sBAAsB,wBAAwB,kBAAkB,cAAc;AA4G9G,IAAM,mBAAmB,CAAC,aAAa,aAAa,cAAc,SAAS;AAE3E,IAAM,kBAAkB,cAAc,gBAAgB;AAGtD,IAAM,0BAA0B,CAAC,aAAa,SAAS;AAEvD,IAAM,wBAAwB,cAAc,uBAAuB;AAyBnE,IAAM,wBAAwB,CAAC,kBAAkB,kBAAkB,mBAAmB,cAAc;AAEpG,IAAM,sBAAsB,cAAc,qBAAqB;AAO/D,IAAM,yBAAyB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAEO,IAAM,uBAAuB,cAAc,sBAAsB;AAkDjE,SAAS,qBAAqB,KAAwC;AACzE,MAAI,CAAC,SAAS,GAAG,KAAK,CAAC,qBAAqB,IAAI,IAAI,EAAG,QAAO;AAC9D,MAAI,IAAI,SAAS,uBAAuB;AAGpC,WAAO;AAAA,MACH,MAAM;AAAA,MACN,WAAW,OAAO,IAAI,cAAc,WAAW,IAAI,YAAY,OAAO,IAAI,aAAa,EAAE;AAAA,MACzF,gBAAgB,OAAO,IAAI,mBAAmB,WAAW,IAAI,iBAAiB;AAAA,MAC9E,SAAS,IAAI;AAAA,MACb,MAAM,SAAS,IAAI,IAAI,IAAI,IAAI,OAAO,CAAC;AAAA,MACvC,WAAW,OAAO,IAAI,cAAc,WAAW,IAAI,YAAY,KAAK,IAAI;AAAA,IAC5E;AAAA,EACJ;AACA,MAAI,CAAC,SAAS,IAAI,OAAO,EAAG,QAAO;AACnC,MAAI,IAAI,SAAS,UAAU,CAAC,iBAAiB,IAAI,QAAQ,KAAK,EAAG,QAAO;AACxE,SAAO,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,SAAS,GAAG,mBAAmB,GAAG,EAAE;AAC9E;AAIO,IAAM,iCAAiC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAEO,IAAM,8BAA8B,cAAc,8BAA8B;AAkEhF,SAAS,yBAAyB,KAAuD;AAC5F,SAAO,CAAC,4BAA4B,IAAI,IAAI;AAChD;AAOA,IAAM,8BAA8B;AAE7B,SAAS,0BAA0B,OAAkD;AACxF,SAAO,OAAO,UAAU,YAAY,4BAA4B,KAAK,KAAK,KAAK,CAAC,4BAA4B,KAAK;AACrH;AAQO,SAAS,qBAAqB,KAAwC;AACzE,MAAI,CAAC,SAAS,GAAG,KAAK,OAAO,IAAI,SAAS,SAAU,QAAO;AAC3D,QAAM,QAAQ;AAAA,IACV,GAAG,mBAAmB,GAAG;AAAA,IACzB,GAAI,iBAAiB,IAAI,MAAM,IAAI,EAAE,QAAQ,IAAI,OAAO,IAAI,CAAC;AAAA,EACjE;AACA,MAAI,IAAI,SAAS,sBAAsB;AACnC,QAAI,CAAC,iBAAiB,IAAI,SAAS,EAAG,QAAO;AAC7C,UAAM,OAAO,EAAE,WAAW,IAAI,WAAW,SAAS,IAAI,YAAY,KAAK;AACvE,WAAO;AAAA,MACH,MAAM;AAAA,MACN,GAAG;AAAA,MACH,GAAI,YAAY,MAAM,EAAE,QAAQ,IAAI,OAAO,IAAI,CAAC;AAAA,MAChD,GAAI,OAAO,IAAI,UAAU,WAAW,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC;AAAA,IAChE;AAAA,EACJ;AACA,MAAI,CAAC,SAAS,IAAI,OAAO,EAAG,QAAO;AACnC,MAAI,4BAA4B,IAAI,IAAI,GAAG;AACvC,WAAO,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,SAAS,GAAG,MAAM;AAAA,EAC5D;AACA,MAAI,CAAC,0BAA0B,IAAI,IAAI,EAAG,QAAO;AACjD,SAAO,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,SAAS,GAAG,MAAM;AAC5D;;;ACpdO,IAAM,4BAA4B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAGO,IAAM,+BAA+B,CAAC,GAAG,2BAA2B,GAAG,yBAAyB;AAEhG,IAAM,6BAA6B,cAAc,4BAA4B;AA8D7E,IAAM,4BAA4B,CAAC,QAAQ,WAAW,UAAU;AAuDhE,IAAM,kCAAkC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAEO,IAAM,+BAA+B,cAAc,+BAA+B;AAmClF,SAAS,6BAA6B,KAAgD;AACzF,MAAI,CAAC,SAAS,GAAG,KAAK,CAAC,6BAA6B,IAAI,IAAI,EAAG,QAAO;AACtE,MAAI,IAAI,SAAS,aAAa;AAC1B,WAAO,EAAE,MAAM,aAAa,SAAS,SAAS,IAAI,OAAO,IAAI,IAAI,UAAU,CAAC,GAAG,GAAG,mBAAmB,GAAG,EAAE;AAAA,EAC9G;AACA,MAAI,CAAC,SAAS,IAAI,OAAO,EAAG,QAAO;AACnC,SAAO,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,SAAS,GAAG,mBAAmB,GAAG,EAAE;AAC9E;AAIO,IAAM,kCAAkC,CAAC,aAAa,WAAW,aAAa,cAAc,SAAS;AAErG,IAAM,+BAA+B,cAAc,+BAA+B;AAGlF,IAAM,6BAA6B,CAAC,aAAa,cAAc,SAAS;AAExE,IAAM,2BAA2B,cAAc,0BAA0B;AA+BzE,SAAS,6BAA6B,KAAgD;AACzF,MAAI,CAAC,SAAS,GAAG,KAAK,CAAC,6BAA6B,IAAI,IAAI,EAAG,QAAO;AACtE,MAAI,IAAI,SAAS,YAAa,QAAO,EAAE,MAAM,aAAa,GAAG,mBAAmB,GAAG,EAAE;AACrF,MAAI,IAAI,SAAS,UAAW,QAAO,EAAE,MAAM,UAAU;AACrD,MAAI,CAAC,SAAS,IAAI,OAAO,KAAK,OAAO,IAAI,QAAQ,aAAa,SAAU,QAAO;AAC/E,SAAO,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,SAAS,GAAG,mBAAmB,GAAG,EAAE;AAC9E;AAIO,IAAM,iCAAiC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAEO,IAAM,8BAA8B,cAAc,8BAA8B;AAuChF,IAAM,iCAAiC,CAAC,aAAa,aAAa,cAAc,SAAS;AAEzF,IAAM,8BAA8B,cAAc,8BAA8B;AAShF,SAAS,4BAA4B,KAA+C;AACvF,MAAI,CAAC,SAAS,GAAG,KAAK,CAAC,4BAA4B,IAAI,IAAI,EAAG,QAAO;AACrE,QAAM,UAAU,SAAS,IAAI,OAAO,IAAI,IAAI,UAAU,CAAC;AACvD,SAAO,EAAE,MAAM,IAAI,MAAM,SAAS,GAAG,mBAAmB,GAAG,EAAE;AACjE;;;ACtSO,SAAS,YAAY,OAA4C;AACpE,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS,QAAQ,KAAK,MAAM,SAAS,SAAS;AAC5F;AAEA,SAAS,gBAAgB,OAAyE;AAC9F,MAAI,CAAC,iBAAiB,MAAM,OAAO,EAAG,QAAO;AAC7C,MAAI,CAAC,OAAO,UAAU,MAAM,KAAK,KAAK,CAAC,OAAO,UAAU,MAAM,KAAK,EAAG,QAAO;AAC7E,MAAI,OAAO,MAAM,SAAS,SAAU,QAAO;AAC3C,SAAO;AAAA,IACH,GAAI,iBAAiB,MAAM,EAAE,IAAI,EAAE,IAAI,MAAM,GAAG,IAAI,CAAC;AAAA,IACrD,SAAS,MAAM;AAAA,IACf,OAAO,MAAM;AAAA,IACb,OAAO,MAAM;AAAA,IACb,MAAM,MAAM;AAAA,EAChB;AACJ;AAIO,IAAM,gCAAgC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAEO,IAAM,6BAA6B,cAAc,6BAA6B;AAG9E,SAAS,6BAA6B,OAAqD;AAC9F,SAAO,YAAY,KAAK,KAAK,2BAA2B,MAAM,MAAM,GAAG,CAAC,SAAS,MAAM,CAAC;AAC5F;AA8CA,IAAM,0BAA0B,oBAAI,IAA8B,CAAC,WAAW,SAAS,QAAQ,SAAS,MAAM,CAAC;AAGxG,SAAS,gCAAgC,KAAgD;AAC5F,MAAI,CAAC,SAAS,GAAG,KAAK,CAAC,6BAA6B,IAAI,IAAI,EAAG,QAAO;AACtE,QAAM,SAAS,gBAAgB,GAAG;AAClC,SAAO,SAAS,EAAE,MAAM,IAAI,MAAM,GAAG,OAAO,IAAI;AACpD;AAOO,SAAS,2BAA2B,KAA8C;AACrF,MAAI,CAAC,SAAS,GAAG,KAAK,CAAC,2BAA2B,IAAI,IAAI,EAAG,QAAO;AACpE,MAAI,wBAAwB,IAAI,IAAI,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,EAAG,QAAO;AAC/E,SAAO;AACX;AAIO,IAAM,gCAAgC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAEO,IAAM,6BAA6B,cAAc,6BAA6B;AA+D9E,SAAS,2BAA2B,KAA8C;AACrF,MAAI,CAAC,SAAS,GAAG,EAAG,QAAO;AAC3B,MAAI,CAAC,2BAA2B,IAAI,IAAI,EAAG,QAAO;AAClD,UAAQ,IAAI,MAAM;AAAA,IACd,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO,SAAS,IAAI,OAAO,IAAK,MAAkC;AAAA,IACtE,KAAK;AACD,aAAO,SAAS,IAAI,MAAM,IAAK,MAA4B;AAAA,IAC/D,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,wBAAwB;AACzB,YAAM,SAAS,gBAAgB,GAAG;AAClC,UAAI,CAAC,OAAQ,QAAO;AACpB,UAAI,IAAI,SAAS,wBAAwB;AACrC,eAAO,iBAAiB,IAAI,SAAS,IAAI,EAAE,MAAM,IAAI,MAAM,WAAW,IAAI,WAAW,GAAG,OAAO,IAAI;AAAA,MACvG;AACA,aAAO,EAAE,MAAM,IAAI,MAAM,GAAG,OAAO;AAAA,IACvC;AAAA,IACA,KAAK;AACD,aAAO,iBAAiB,IAAI,SAAS,KAAK,OAAO,IAAI,SAAS,WAAY,MAA8B;AAAA,IAC5G,KAAK;AACD,aAAO,iBAAiB,IAAI,SAAS,IAAK,MAA+B;AAAA,IAC7E,KAAK;AAAA,IACL,KAAK;AACD,aAAO,iBAAiB,IAAI,EAAE,IAAK,MAAkC;AAAA,IACzE,KAAK;AACD,aAAO,MAAM,QAAQ,IAAI,MAAM,KAAK,IAAI,OAAO,MAAM,CAAC,UAAU,OAAO,UAAU,QAAQ,IACnF,EAAE,MAAM,IAAI,MAAM,QAAQ,IAAI,OAAmB,IACjD;AAAA,EACd;AACJ;AAGO,IAAM,8BAA8B;AAAA,EACvC,GAAG,oBAAI,IAAY,CAAC,GAAG,+BAA+B,GAAG,6BAA6B,CAAC;AAC3F;;;AC/PO,IAAM,yBAAyB;AAK/B,SAAS,4BAA4B,aAAqB,eAA+D;AAC5H,QAAM,SAAS,OAAO,kBAAkB,YAAY,OAAO,SAAS,aAAa,IAAI,gBAAgB;AACrG,MAAI,WAAW,YAAa,QAAO;AACnC,SAAO,SAAS,cAAc,oBAAoB;AACtD;;;ACkBO,IAAM,2BAA2D;AAEjE,IAAM,2BAA2D;AAmDjE,SAAS,sBAAsB,KAAuC;AACzE,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,QAAM,MAAM;AACZ,QAAM,MAAM,CAAC,OAAgB,aACzB,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ;AAClE,SAAO;AAAA,IACH,mBAAmB;AAAA,MACf,IAAI,sBAAsB,SAAY,IAAI,oBAAoB,IAAI;AAAA,MAClE;AAAA,IACJ;AAAA,IACA,2BAA2B,IAAI,IAAI,2BAA2B,CAAC;AAAA,IAC/D,wBAAwB,IAAI,IAAI,wBAAwB,EAAE;AAAA,IAC1D,aAAa,IAAI,IAAI,aAAa,EAAE;AAAA,EACxC;AACJ;;;AC/GO,IAAM,4CAA4C;AAiBlD,IAAM,uCAAuC;;;ACI7C,IAAM,mBAAmB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAIO,IAAM,yBAAyB,CAAC,mBAAmB,WAAW,iBAAiB,MAAM;AAgBrF,IAAM,uBAAsF;AAAA,EAC/F,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN,cAAc;AAAA,EACd,eAAe;AAAA,EACf,OAAO;AAAA,EACP,SAAS;AAAA,EACT,cAAc;AAClB;AAUO,IAAM,yBAAkE;AAAA,EAC3E,SAAS;AAAA,EACT,WAAW;AAAA,EACX,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,mBAAmB;AAAA,EACnB,UAAU;AAAA,EACV,QAAQ;AAAA;AAAA,EAER,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,SAAS;AACb;AAEA,IAAM,qBAA0C,IAAI,IAAI,gBAAgB;AAEjE,SAAS,gBAAgB,OAAwC;AACpE,SAAO,OAAO,UAAU,YAAY,mBAAmB,IAAI,KAAK;AACpE;AAGO,SAAS,uBAAuB,KAAoC;AACvE,MAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,QAAM,QAAQ,IAAI,KAAK,EAAE,YAAY;AACrC,MAAI,mBAAmB,IAAI,KAAK,EAAG,QAAO;AAC1C,SAAO,uBAAuB,KAAK,KAAK;AAC5C;AAEO,SAAS,sBAAsB,KAAkC;AACpE,QAAM,SAAS,uBAAuB,GAAG;AACzC,SAAO,SAAS,qBAAqB,MAAM,IAAI;AACnD;AAEO,SAAS,gBAAgB,KAAuB;AACnD,SAAO,sBAAsB,GAAG,MAAM;AAC1C;AAEO,SAAS,gBAAgB,KAAuB;AACnD,SAAO,sBAAsB,GAAG,MAAM;AAC1C;AAEO,SAAS,cAAc,KAAuB;AACjD,SAAO,sBAAsB,GAAG,MAAM;AAC1C;AAEO,SAAS,aAAa,KAAuB;AAChD,SAAO,sBAAsB,GAAG,MAAM;AAC1C;AAQO,SAAS,aAAa,KAAuB;AAChD,QAAM,MAAM,sBAAsB,GAAG;AACrC,SAAO,QAAQ,aAAa,QAAQ;AACxC;AAEO,SAAS,gBAAgB,KAA8D;AAC1F,SAAO,iBAAiB,OAAO,CAAC,WAAW,qBAAqB,MAAM,MAAM,GAAG;AACnF;AAOO,IAAM,mCAAmC,CAAC,WAAW,UAAU,cAAc,UAAU,QAAQ;AAE/F,SAAS,8BAA8B,KAAuB;AACjE,SAAO,OAAO,QAAQ,YAAa,iCAAuD,SAAS,IAAI,KAAK,EAAE,YAAY,CAAC;AAC/H;AAQO,SAAS,mBAAmB,OAAyB;AACxD,QAAM,SAAS,SAAS,OAAO,UAAU,WAAW,QAAmE,CAAC;AACxH,QAAM,SAAS,OAAO,OAAO,WAAW,WAAW,OAAO,OAAO,KAAK,EAAE,YAAY,IAAI;AACxF,MAAI,8BAA8B,MAAM,KAAK,aAAa,MAAM,EAAG,QAAO;AAC1E,SAAO,cAAc,MAAM,KAAK,OAAO,YAAY,WAAW;AAClE;;;AChJO,IAAM,qBAAqB,CAAC,WAAW,YAAY,aAAa,UAAU,WAAW;AAGrF,IAAM,8BAA8B,CAAC,aAAa,UAAU,WAAW;AAGvE,IAAM,kBAAkB,CAAC,eAAe,cAAc,uBAAuB,cAAc,aAAa;AAGxG,IAAM,uBAAuB,CAAC,OAAO,UAAU,MAAM;AAGrD,IAAM,uBAAuB,CAAC,OAAO,UAAU,MAAM;AAarD,IAAM,sBAAsB,CAAC,aAAa,WAAW;AAOrD,IAAM,6BAA6B,CAAC,YAAY,QAAQ,kBAAkB,iBAAiB;AAI3F,IAAM,yBAAyB,CAAC,aAAa,WAAW,QAAQ;AAIhE,IAAM,uBAAuB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAGA,SAAS,UAAuC,QAAmD;AAC/F,QAAM,MAA2B,IAAI,IAAI,MAAM;AAC/C,SAAO,CAAC,UAAuC,OAAO,UAAU,YAAY,IAAI,IAAI,KAAK;AAC7F;AAEO,IAAM,mBAAmB,UAAU,kBAAkB;AACrD,IAAM,2BAA2B,UAAU,2BAA2B;AACtE,IAAM,iBAAiB,UAAU,eAAe;AAChD,IAAM,qBAAqB,UAAU,oBAAoB;AACzD,IAAM,qBAAqB,UAAU,mBAAmB;AACxD,IAAM,wBAAwB,UAAU,sBAAsB;AAM9D,SAAS,OACZ,QACA,aAC2D;AAC3D,SAAO;AAAA,IACH,MAAM;AAAA,IACN,MAAM,CAAC,GAAG,MAAM;AAAA,IAChB,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,EACzC;AACJ;;;ACoIA,IAAI,2BAA2B;AACxB,SAAS,cAAc,MAAc,KAAK,IAAI,GAAW;AAC5D,MAAI;AAEA,UAAM,YAAa,OAAO,eAAe,cAClC,WAA0D,SAC3D;AACN,QAAI,OAAO,WAAW,eAAe,WAAY,QAAO,OAAO,UAAU,WAAW,CAAC;AAAA,EACzF,QAAQ;AAAA,EAER;AACA,8BAA4B;AAC5B,SAAO,OAAO,GAAG,IAAI,wBAAwB;AACjD;AAGA,IAAM,oBAAoB;AAEnB,SAAS,YAAY,OAAiC;AACzD,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS,kBAAkB,UAAU,MAAM,WAAW,iBAAiB;AACrH;AAIO,IAAM,2BAA2B,CAAC,aAAa,OAAO,QAAQ,OAAO,OAAO,WAAW;AAEvF,SAAS,wBAAwB,OAAgD;AACpF,SAAO,OAAO,UAAU,YAAa,yBAA+C,SAAS,KAAK;AACtG;AAEO,IAAM,oBAAoB,CAAC,SAAS,YAAY,WAAW;AAE3D,SAAS,iBAAiB,OAA6C;AAC1E,SAAO,OAAO,UAAU,YAAa,kBAAwC,SAAS,KAAK;AAC/F;AAEO,SAAS,aAAa,OAAqC;AAC9D,SAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,iBAAkB,MAA6B,IAAI;AACtG;AAEO,IAAM,uBAAuB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAEO,SAAS,cAAc,OAAsC;AAChE,SAAO,OAAO,UAAU,YAAa,qBAA2C,SAAS,KAAK;AAClG;AAEA,IAAM,uBAAuB,CAAC,aAAa,UAAU,aAAa,SAAS;AAEpE,SAAS,gBAAgB,OAAwC;AACpE,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,OAAQ,MAA6B;AAC3C,MAAI,OAAO,SAAS,YAAY,CAAE,qBAA2C,SAAS,IAAI,EAAG,QAAO;AACpG,MAAI,SAAS,SAAU,QAAO,OAAQ,MAAiC,aAAa;AACpF,MAAI,SAAS,YAAa,QAAO,OAAQ,MAA2B,OAAO;AAC3E,MAAI,SAAS,UAAW,QAAO,cAAe,MAA+B,MAAM;AACnF,SAAO;AACX;AAEA,SAAS,gBAAgB,OAAwC;AAC7D,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,OAAQ,MAA6B;AAC3C,SAAO,SAAS,UAAU,SAAS,WAAW,SAAS,WAAW,SAAS,WAAW,SAAS,cAAc,SAAS;AAC1H;AAEO,SAAS,oBAAoB,OAA4C;AAC5E,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,QAAS,MAA8B;AAC7C,QAAM,eAAgB,MAAqC;AAC3D,SAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,eAAe,KAAK,OAAO,iBAAiB;AAC3F;AAGO,SAAS,kBAAkB,OAA0C;AACxE,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,YAAY;AAClB,SAAO,YAAY,UAAU,SAAS,KAC/B,OAAO,UAAU,cAAc,YAAY,UAAU,UAAU,SAAS,KACxE,oBAAoB,UAAU,KAAK,KACnC,wBAAwB,UAAU,MAAM,KACxC,aAAa,UAAU,MAAM,KAC7B,OAAO,UAAU,cAAc;AAC1C;;;ACzSA,IAAM,WAAW;AACjB,IAAM,gBAAgB;AACtB,IAAM,iBAAiB;AAGhB,IAAM,iCAAiC;AAsB9C,SAAS,eAAe,OAAe,KAAqB;AACxD,MAAI,MAAM,UAAU,IAAK,QAAO;AAChC,SAAO,GAAG,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,QAAQ,CAAC;AAC/C;AAEA,SAAS,oBACL,OACA,OACA,WACoB;AACpB,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO;AAClC,QAAM,QAAkB,CAAC;AACzB,MAAI,gBAAgB;AACpB,aAAW,OAAO,OAAO;AACrB,QAAI,OAAO,QAAQ,SAAU;AAC7B,UAAM,UAAU,IAAI,KAAK;AACzB,QAAI,CAAC,QAAS;AACd,QAAI,QAAQ,SAAS,cAAe,iBAAgB;AACpD,UAAM,KAAK,eAAe,SAAS,aAAa,CAAC;AAAA,EACrD;AACA,MAAI,cAAe,WAAU,KAAK,EAAE,OAAO,QAAQ,gBAAgB,CAAC;AACpE,MAAI,MAAM,SAAS,gBAAgB;AAC/B,cAAU,KAAK,EAAE,OAAO,QAAQ,gBAAgB,CAAC;AACjD,WAAO,MAAM,MAAM,GAAG,cAAc;AAAA,EACxC;AACA,SAAO,MAAM,SAAS,IAAI,QAAQ;AACtC;AAQO,SAAS,sBAAsB,OAA6C;AAC/E,QAAM,YAAoG,CAAC;AAC3G,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACrC,WAAO,EAAE,OAAO,MAAM,UAAU;AAAA,EACpC;AACA,QAAM,MAAM;AAEZ,QAAM,UAAU,OAAO,IAAI,SAAS,WAAW,IAAI,KAAK,KAAK,IAAI;AACjE,MAAI,CAAC,SAAS;AACV,WAAO,EAAE,OAAO,MAAM,UAAU;AAAA,EACpC;AACA,MAAI,QAAQ,SAAS,SAAU,WAAU,KAAK,EAAE,OAAO,QAAQ,QAAQ,iBAAiB,CAAC;AACzF,QAAM,OAAO,eAAe,SAAS,QAAQ;AAE7C,QAAM,cAAc,oBAAoB,IAAI,aAAa,eAAe,SAAS;AACjF,QAAM,eAAe,oBAAoB,IAAI,gBAAgB,IAAI,eAAe,gBAAgB,SAAS;AACzG,QAAM,eAAe,oBAAoB,IAAI,gBAAgB,IAAI,eAAe,gBAAgB,SAAS;AACzG,QAAM,aAAa,oBAAoB,IAAI,cAAc,IAAI,aAAa,cAAc,SAAS;AAEjG,QAAM,QAAsB,EAAE,KAAK;AACnC,MAAI,YAAa,OAAM,cAAc;AACrC,MAAI,aAAc,OAAM,eAAe;AACvC,MAAI,aAAc,OAAM,eAAe;AACvC,MAAI,WAAY,OAAM,aAAa;AAEnC,SAAO,EAAE,OAAO,UAAU;AAC9B;AAEA,SAAS,WAAW,SAAiB,OAAgD;AACjF,MAAI,CAAC,SAAS,MAAM,WAAW,EAAG,QAAO,CAAC;AAC1C,SAAO,CAAC,GAAG,OAAO,KAAK,GAAG,MAAM,IAAI,UAAQ,KAAK,IAAI,EAAE,CAAC;AAC5D;AAWO,SAAS,wBAAwB,OAA6B;AACjE,QAAM,WAAqB,CAAC,iBAAiB,MAAM,IAAI,EAAE;AACzD,WAAS,KAAK,GAAG,WAAW,eAAe,MAAM,WAAW,CAAC;AAC7D,WAAS,KAAK,GAAG,WAAW,aAAa,MAAM,YAAY,CAAC;AAC5D,WAAS,KAAK,GAAG,WAAW,eAAe,MAAM,UAAU,CAAC;AAC5D,WAAS,KAAK,GAAG,WAAW,iBAAiB,MAAM,YAAY,CAAC;AAEhE,QAAM,OAAO,SAAS,KAAK,IAAI;AAC/B,MAAI,KAAK,UAAU,+BAAgC,QAAO;AAI1D,QAAM,SAAS;AACf,QAAM,SAAS,iCAAiC,OAAO;AACvD,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,MAAI,MAAM;AACV,aAAW,QAAQ,OAAO;AACtB,UAAM,OAAO,MAAM,GAAG,GAAG;AAAA,EAAK,IAAI,KAAK;AACvC,QAAI,KAAK,SAAS,OAAQ;AAC1B,UAAM;AAAA,EACV;AACA,MAAI,CAAC,IAAK,OAAM,eAAe,MAAM,CAAC,KAAK,IAAI,KAAK,IAAI,QAAQ,CAAC,CAAC;AAClE,SAAO,GAAG,GAAG,GAAG,MAAM;AAC1B;;;ACrHO,IAAM,eAAe;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAIA,IAAM,kBAAuC,IAAI,IAAI,YAAY;AAE1D,SAAS,aAAa,OAAqC;AAC9D,SAAO,OAAO,UAAU,YAAY,gBAAgB,IAAI,KAAK;AACjE;AAGO,IAAM,gCAAgC;AAsBtC,SAAS,wBAAwB,MAAuB;AAC3D,SAAO,OAAO,SAAS,YAAY,KAAK,SAAS,6BAA6B;AAClF;AAOO,SAAS,2BAA2B,QAAmC,CAAC,GAAW;AACtF,QAAM,aAAa,MAAM,eAAe,wBAAwB,MAAM,YAAY,IAAI;AACtF,QAAM,QAAkB,aAAa,CAAC,YAAY,IAAI,6BAA6B,IAAI,CAAC,6BAA6B;AACrH,QAAM,QAAkB,CAAC;AACzB,MAAI,MAAM,OAAQ,OAAM,KAAK,QAAQ,MAAM,MAAM,EAAE;AACnD,MAAI,MAAM,SAAU,OAAM,KAAK,QAAQ,MAAM,QAAQ,EAAE;AAMvD,MAAI,MAAM,YAAY;AAClB,QAAI,qBAAqB,MAAM,UAAU,GAAG;AACxC,YAAM,KAAK,cAAc,MAAM,UAAU,EAAE;AAAA,IAC/C,OAAO;AAGH,cAAQ;AAAA,QACJ,0BAA0B,MAAM,UAAU,WAAW,kCAAkC,MAAM,UAAU;AAAA,MAE3G;AAAA,IACJ;AAAA,EACJ;AACA,MAAI,MAAM,SAAU,OAAM,KAAK,WAAW;AAC1C,MAAI,MAAM,OAAQ,OAAM,KAAK,+BAA+B,MAAM,KAAK,IAAI,CAAC,IAAI;AAAA,MAC3E,OAAM,KAAK,6BAA6B;AAC7C,MAAI,MAAM,cAAc,OAAO;AAC3B,UAAM;AAAA,MACF;AAAA,MAIA;AAAA,IAGJ;AACA,QAAI,MAAM,wBAAwB,MAAM,uBAAuB,GAAG;AAC9D,YAAM;AAAA,QACF,OAAO,MAAM,oBAAoB;AAAA,MAErC;AAAA,IACJ;AACA,WAAO,MAAM,KAAK,IAAI;AAAA,EAC1B;AACA,QAAM;AAAA,IACF;AAAA,IAGA;AAAA,IAEA;AAAA,IAEA;AAAA,IAEA;AAAA,IAGA;AAAA,IAGA;AAAA,EAEJ;AACA,MAAI,MAAM,wBAAwB,MAAM,uBAAuB,GAAG;AAC9D,UAAM;AAAA,MACF,OAAO,MAAM,oBAAoB;AAAA,IAErC;AAAA,EACJ;AACA,SAAO,MAAM,KAAK,IAAI;AAC1B;AAOO,SAAS,0BAA0B,MAAsB;AAC5D,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,QAAM,KAAK,KAAK,QAAQ,6BAA6B;AACrD,MAAI,KAAK,EAAG,QAAO;AACnB,SAAO,KAAK,MAAM,GAAG,EAAE,EAAE,QAAQ,QAAQ,EAAE;AAC/C;AAKO,SAAS,2BAA2B,MAAc,QAAmC,CAAC,GAAW;AACpG,MAAI,wBAAwB,IAAI,EAAG,QAAO;AAC1C,QAAM,UAAU,KAAK,QAAQ,QAAQ,EAAE;AACvC,SAAO,GAAG,OAAO;AAAA;AAAA,EAAO,2BAA2B,KAAK,CAAC;AAC7D;AAMO,SAAS,iCAAyC;AACrD,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA,yGAAyG,aAAa,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,IAC7J;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ,EAAE,KAAK,IAAI;AACf;;;AC9KO,IAAM,kBAAkB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAIA,IAAM,qBAA0C,IAAI,IAAI,eAAe;AAEhE,SAAS,gBAAgB,OAAwC;AACpE,SAAO,OAAO,UAAU,YAAY,mBAAmB,IAAI,KAAK;AACpE;AAGO,IAAM,iBAAiB;AAAA;AAAA,EAE1B,UAAU;AAAA,EACV,eAAe;AAAA,EACf,aAAa;AAAA,EACb,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,aAAa;AAAA,EACb,aAAa;AAAA;AAAA,EAEb,QAAQ;AAAA,EACR,eAAe;AAAA;AAAA,EAEf,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,cAAc;AAClB;AAKO,IAAM,uBAAuE;AAAA,EAChF,UAAU,eAAe;AAAA,EACzB,gBAAgB,eAAe;AAAA,EAC/B,cAAc,eAAe;AAAA,EAC7B,cAAc,eAAe;AAAA,EAC7B,aAAa,eAAe;AAAA,EAC5B,gBAAgB,eAAe;AAAA,EAC/B,QAAQ,eAAe;AAAA,EACvB,YAAY,eAAe;AAAA,EAC3B,cAAc,eAAe;AAAA,EAC7B,cAAc,eAAe;AACjC;AAQO,IAAM,wBAAkD,CAAC,UAAU,gBAAgB,gBAAgB,gBAAgB,aAAa;AAGhI,IAAM,wBAAkD;AAAA,EAC3D,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AACnB;AAGO,IAAM,8BAAwD;AAAA,EACjE,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AACnB;AAOO,IAAM,2BAA2B;AAGjC,IAAM,2BAA2B;;;AC9EjC,IAAM,8BAA8B;AAEpC,IAAM,sBAAsB;AAAA,EAC/B;AAAA,EAAY;AAAA,EAAoB;AAAA,EAA4B;AAAA,EAC5D;AAAA,EAAyB;AAAA,EAA0B;AAAA,EAAoB;AAAA,EACvE;AAAA,EAAuB;AAAA,EAAa;AAAA,EAAiB;AAAA,EACrD;AAAA,EAAuB;AAAA,EAAkB;AAAA,EAAY;AAAA,EACrD;AAAA,EAAqB;AAAA,EAAa;AAAA,EAAe;AAAA,EAAY;AAAA,EAC7D;AAAA,EAAY;AAAA,EAAuB;AAAA,EAAa;AAAA,EAAa;AACjE;AAGO,IAAM,cAAc,CAAC,cAAc,eAAe,OAAO;AAQzD,IAAM,2BAA2B,CAAC,kBAAkB,aAAa,mBAAmB;AAGpF,IAAM,oBAAoB,CAAC,aAAa,QAAQ;AAEhD,IAAM,gBAAgB,CAAC,SAAS,KAAK;AAGrC,IAAM,2BAA2B,CAAC,iBAAiB,mBAAmB,gBAAgB,sBAAsB,SAAS;AAYrH,SAAS,oBAAoB,OAAoC;AACpE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,aAAa,MAAM,KAAK,EAAE,YAAY,EAAE,QAAQ,YAAY,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,YAAY,EAAE;AACjH,MAAI,CAAC,WAAY,QAAO;AACxB,SAAO,WAAW,MAAM,GAAG,EAAE;AACjC;AAEO,IAAM,mBAAmB,CAAC,WAAW,eAAe;AAGpD,IAAM,0BAA0B,CAAC,WAAW,aAAa;AAGzD,IAAM,oBAAoB,CAAC,YAAY,QAAQ;AAE/C,IAAM,yBAAyB,CAAC,YAAY,YAAY,UAAU;AAElE,IAAM,6BAA6B,CAAC,gBAAgB,gBAAgB,eAAe;AAGnF,IAAM,qBAAqB,CAAC,WAAW,MAAM;AAI7C,IAAM,yBAAyB;AAAA,EAClC;AAAA,EAA2B;AAAA,EAAwB;AAAA,EAA2B;AAClF;AAGO,IAAM,uBAAuB,CAAC,aAAa,SAAS;AAGpD,IAAM,mBAAmB,CAAC,SAAS,WAAW,eAAe,MAAM;AAGnE,IAAM,oBAAoB,CAAC,eAAe,gBAAgB;AAY1D,IAAM,wBAAwB,CAAC,kBAAkB,iBAAiB,gBAAgB,eAAe,kBAAkB,WAAW,gBAAgB;AAG9I,IAAM,iBAAiB,CAAC,mBAAmB,uBAAuB,gBAAgB,qBAAqB,YAAY;AAGnH,IAAM,oBAAoB,CAAC,aAAa,QAAQ;AAEhD,IAAM,0BAA0B,CAAC,mBAAmB,mBAAmB,qBAAqB;AAG5F,IAAM,2BAA2B,CAAC,aAAa,UAAU,WAAW;AAIpE,IAAM,gCAAgC,CAAC,GAAG,kBAAkB,SAAS;AAOrE,IAAM,eAAe;AAAA,EACxB;AAAA,EAAkB;AAAA,EAAiB;AAAA,EAAc;AAAA,EAAY;AAAA,EAC7D;AAAA,EAAgB;AAAA,EAAoB;AAAA,EAAkB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA;AACJ;AAGO,IAAM,gBAAgB,CAAC,aAAa,UAAU,WAAW;AAGzD,IAAM,mBAAmB,CAAC,WAAW,QAAQ,eAAe,UAAU;AAItE,IAAM,eAAe;AAAA;AAAA,EAExB;AAAA,EAAY;AAAA,EAAsB;AAAA,EAAoB;AAAA,EACtD;AAAA,EAAoC;AAAA,EAAiB;AAAA,EAAwB;AAAA,EAC7E;AAAA,EAAmB;AAAA,EAAuB;AAAA,EAAgB;AAAA,EAAqB;AAAA,EAC/E;AAAA,EAAmB;AAAA,EAAmB;AAAA,EACtC;AAAA,EAAgB;AAAA,EAA4B;AAAA,EAAsB;AAAA;AAAA,EAElE;AAAA,EAAmC;AAAA,EAA8B;AAAA,EAAsC;AAAA,EACvG;AAAA,EAAgB;AAAA,EAA4B;AAAA,EAAgB;AAAA,EAC5D;AAAA,EAA0C;AAAA,EAAkC;AAChF;AAaO,IAAM,eAAe;AAAA,EACxB;AAAA,EAAa;AAAA,EAAU;AAAA,EAAa;AAAA,EAAW;AAAA,EAAY;AAAA,EAAU;AAAA,EACrE;AAAA,EAAa;AAAA,EAAe;AAAA,EAAY;AAAA,EAAmB;AAC/D;AAoIA,IAAM,KAAK,EAAE,GAAG,KAAK;AACrB,IAAM,QAAQ,EAAE,GAAG,MAAM,UAAU,KAAK;AACxC,IAAM,OAAO,EAAE,GAAG,OAAO;AACzB,IAAM,UAAU,EAAE,GAAG,QAAQ,UAAU,KAAK;AAC5C,IAAM,KAAK,EAAE,GAAG,KAAK;AACrB,IAAM,QAAQ,EAAE,GAAG,MAAM,UAAU,KAAK;AACxC,IAAM,SAAS,EAAE,GAAG,OAAO,UAAU,KAAK;AAC1C,IAAM,KAAK,CAAC,YAA+B,EAAE,GAAG,QAAQ,OAAO;AAC/D,IAAM,QAAQ,CAAC,YAA+B,EAAE,GAAG,QAAQ,QAAQ,UAAU,KAAK;AAE3E,IAAM,gCAAiG;AAAA,EAC1G,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,QAAQ,GAAG,mBAAmB;AAAA,EAC9B,WAAW;AAAA,EACX,YAAY,EAAE,GAAG,eAAe,UAAU,KAAK;AAAA,EAC/C,QAAQ;AAAA,EACR,YAAY;AAChB;AAEO,IAAM,4BAAoD;AAAA,EAC7D,mBAAmB;AAAA,IACf,OAAO,GAAG,WAAW;AAAA,IAAG,WAAW;AAAA,IAAI,QAAQ;AAAA,IAAO,QAAQ;AAAA,IAAO,cAAc;AAAA,IACnF,WAAW;AAAA,IAAQ,eAAe;AAAA,IAAQ,gBAAgB,MAAM,gBAAgB;AAAA,IAAG,gBAAgB;AAAA,IACnG,aAAa,EAAE,GAAG,eAAe,UAAU,KAAK;AAAA,EACpD;AAAA,EACA,WAAW,EAAE,WAAW,IAAI,SAAS,GAAG,iBAAiB,GAAG,KAAK,GAAG,aAAa,EAAE;AAAA,EACnF,kBAAkB,EAAE,WAAW,IAAI,QAAQ,GAAG,oBAAoB,EAAE;AAAA,EACpE,iBAAiB,EAAE,cAAc,MAAM,QAAQ,GAAG,wBAAwB,GAAG,aAAa,MAAM;AAAA,EAChG,4BAA4B,EAAE,iBAAiB,IAAI,iBAAiB,MAAM;AAAA,EAC1E,iBAAiB,EAAE,aAAa,IAAI,QAAQ,GAAG,uBAAuB,EAAE;AAAA,EACxE,cAAc,EAAE,OAAO,KAAK;AAAA,EAC5B,YAAY,EAAE,OAAO,GAAG,iBAAiB,GAAG,UAAU,MAAM;AAAA,EAC5D,qBAAqB,EAAE,YAAY,GAAG,sBAAsB,GAAG,KAAK,GAAG,0BAA0B,EAAE;AAAA,EACnG,UAAU;AAAA,IACN,UAAU,GAAG,kBAAkB;AAAA,IAAG,0BAA0B;AAAA,IAAS,QAAQ;AAAA,IAC7E,SAAS,EAAE,GAAG,eAAe,UAAU,KAAK;AAAA,IAAG,aAAa,MAAM,sBAAsB;AAAA,IACxF,mBAAmB;AAAA,IAAS,eAAe,MAAM,oBAAoB;AAAA,IAAG,MAAM,EAAE,GAAG,QAAQ,UAAU,KAAK;AAAA,IAC1G,gBAAgB;AAAA,IAAS,iBAAiB,MAAM,iBAAiB;AAAA,EACrE;AAAA,EACA,kBAAkB;AAAA,IACd,iBAAiB;AAAA,IAAM,YAAY;AAAA,IAAM,cAAc,EAAE,GAAG,iBAAiB,UAAU,KAAK;AAAA,IAC5F,MAAM,EAAE,GAAG,OAAO;AAAA,IAAG,SAAS,EAAE,GAAG,eAAe,UAAU,KAAK;AAAA,IAAG,WAAW;AAAA,EACnF;AAAA,EACA,qBAAqB,EAAE,kBAAkB,GAAG;AAAA,EAC5C,aAAa,EAAE,WAAW,IAAI,gBAAgB,GAAG,6BAA6B,GAAG,uBAAuB,KAAK;AAAA,EAC7G,UAAU,EAAE,QAAQ,GAAG,gBAAgB,EAAE;AAAA,EACzC,cAAc,EAAE,UAAU,EAAE,GAAG,OAAO,UAAU,KAAK,GAAG,iBAAiB,MAAM,iBAAiB,EAAE;AAAA,EAClG,eAAe,EAAE,QAAQ,GAAG,qBAAqB,EAAE;AAAA,EACnD,eAAe;AAAA,IACX,SAAS,GAAG,sBAAsB;AAAA,IAAG,SAAS,EAAE,GAAG,eAAe,UAAU,KAAK;AAAA,IAAG,iBAAiB;AAAA,IACrG,aAAa,MAAM,oBAAoB;AAAA,IAAG,kBAAkB;AAAA,EAChE;AAAA,EACA,iBAAiB,EAAE,MAAM,EAAE,GAAG,eAAe,UAAU,KAAK,EAAE;AAAA,EAC9D,iBAAiB,EAAE,OAAO,MAAM,sBAAsB,EAAE,GAAG,MAAM,GAAG,cAAc,KAAK;AAAA,EACvF,QAAQ,EAAE,QAAQ,GAAG,cAAc,EAAE;AAAA,EACrC,iBAAiB,EAAE,QAAQ,GAAG,iBAAiB,GAAG,QAAQ,GAAG,uBAAuB,EAAE;AAAA,EACtF,iBAAiB,EAAE,QAAQ,GAAG,YAAY,GAAG,SAAS,GAAG,wBAAwB,EAAE;AAAA,EACnF,cAAc,EAAE,QAAQ,IAAI,QAAQ,GAAG,YAAY,EAAE;AACzD;AAEO,IAAM,sBAAsB,OAAO,KAAK,yBAAyB;AAGjE,IAAM,gCAAgC;AAAA,EACzC;AAAA,EAAY;AAAA,EAAoB;AAAA,EAAe;AAAA,EAAiB;AAAA,EAAiB;AAAA,EAAgB;AAAA,EAAU;AAC/G;AAKA,IAAM,gBAAgB;AAEtB,SAASC,WAAuC,QAAmD;AAC/F,QAAM,MAA2B,IAAI,IAAI,MAAM;AAC/C,SAAO,CAAC,UAAuC,OAAO,UAAU,YAAY,IAAI,IAAI,KAAK;AAC7F;AAEO,IAAM,qBAAqBA,WAAU,mBAAkD;AACvF,IAAM,eAAeA,WAAU,YAAY;AAC3C,IAAM,eAAeA,WAAU,YAAY;AAC3C,IAAM,gBAAgBA,WAAU,aAAa;AAC7C,IAAM,mBAAmBA,WAAU,gBAAgB;AAE1D,SAASC,UAAS,OAAkD;AAChE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC9E;AAEO,SAAS,qBAAqB,OAAiC;AAClE,SAAO,OAAO,UAAU,YAAY,cAAc,KAAK,KAAK;AAChE;AAEA,SAASC,gBAAe,OAAiC;AACrD,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAC7D;AAEO,SAAS,aAAa,OAAqC;AAC9D,SAAOD,UAAS,KAAK,KACd,YAAY,OAAO,CAAC,SAAS,UAAU,KAAK,CAAC,KAC7C,qBAAqB,MAAM,KAAK,KAChC,qBAAqB,MAAM,MAAM,KACjC,OAAO,cAAc,MAAM,GAAG,KAAM,MAAM,OAAkB;AACvE;AAEO,SAAS,iBAAiB,OAAyC;AACtE,SAAOA,UAAS,KAAK,KACd,YAAY,OAAO,CAAC,aAAa,YAAY,CAAC,KAC9C,qBAAqB,MAAM,SAAS,KACpC,OAAO,cAAc,MAAM,UAAU,KAAM,MAAM,cAAyB;AACrF;AAEA,SAAS,kBAAkB,OAA0C;AACjE,SAAOA,UAAS,KAAK,KACd,YAAY,OAAO,CAAC,SAAS,kBAAkB,gBAAgB,kBAAkB,CAAC,KAClF,OAAO,MAAM,UAAU,aACvB,OAAO,MAAM,mBAAmB,aAChC,OAAO,MAAM,iBAAiB,cAC7B,MAAM,qBAAqB,UAAaC,gBAAe,MAAM,gBAAgB;AACzF;AAEA,SAAS,kBAAkB,OAA8C;AACrE,SAAOD,UAAS,KAAK,KACd,YAAY,OAAO,CAAC,WAAW,QAAQ,CAAC,KACvC,qBAA2C,SAAS,MAAM,OAAiB,MAC3E,MAAM,WAAW,UAAa,qBAAqB,MAAM,MAAM;AAC3E;AAEA,SAAS,sBAAsB,OAAsD;AACjF,SAAOA,UAAS,KAAK,KACd,YAAY,OAAO,CAAC,YAAY,oBAAoB,WAAW,CAAC,KAChE,qBAAqB,MAAM,QAAQ,KACnC,qBAAqB,MAAM,gBAAgB,MAC1C,MAAM,cAAc,UAAa,qBAAqB,MAAM,SAAS;AACjF;AAEA,SAAS,YAAY,OAAgC,SAAqC;AACtF,aAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AAClC,QAAI,CAAC,QAAQ,SAAS,GAAG,EAAG,QAAO;AAAA,EACvC;AACA,SAAO;AACX;AAEA,SAAS,aAAa,MAAyB,OAAyB;AACpE,MAAI,UAAU,OAAW,QAAO,KAAK,aAAa;AAClD,UAAQ,KAAK,GAAG;AAAA,IACZ,KAAK;AAAM,aAAO,qBAAqB,KAAK;AAAA,IAC5C,KAAK;AAAQ,aAAO,OAAO,UAAU,YAAY,KAAK,OAAO,SAAS,KAAK;AAAA,IAC3E,KAAK;AAAQ,aAAO,OAAO,UAAU;AAAA,IACrC,KAAK;AAAO,aAAQ,UAAU,QAAQ,KAAK,aAAa,QAAS,OAAO,cAAc,KAAK;AAAA,IAC3F,KAAK;AAAM,aAAOC,gBAAe,KAAK,KAAK,SAAS;AAAA,IACpD,KAAK;AAAe,aAAO,aAAa,KAAK;AAAA,IAC7C,KAAK;AAAe,aAAO,iBAAiB,KAAK;AAAA,IACjD,KAAK;AAAQ,aAAO,kBAAkB,KAAK;AAAA,IAC3C,KAAK;AAAiB,aAAO,kBAAkB,KAAK;AAAA,IACpD,KAAK;AAAe,aAAO,sBAAsB,KAAK;AAAA,EAC1D;AACJ;AAMO,SAAS,eAAe,OAAuC;AAClE,MAAI,CAACD,UAAS,KAAK,KAAK,CAAC,mBAAmB,MAAM,IAAI,EAAG,QAAO;AAChE,QAAM,YAAY,0BAA0B,MAAM,IAAI;AACtD,QAAM,gBAAgB;AACtB,aAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AAClC,QAAI,QAAQ,OAAQ;AACpB,QAAI,EAAE,OAAO,cAAc,EAAE,OAAO,eAAgB,QAAO;AAAA,EAC/D;AACA,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,aAAa,GAAG;AACrD,QAAI,CAAC,aAAa,MAAM,MAAM,GAAG,CAAC,EAAG,QAAO;AAAA,EAChD;AACA,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,SAAS,GAAG;AACjD,QAAI,CAAC,aAAa,MAAM,MAAM,GAAG,CAAC,EAAG,QAAO;AAAA,EAChD;AACA,SAAO;AACX;AAKO,IAAM,sBAAsB,CAAC,UAAU,4BAA4B,gBAAgB,iBAAiB;AAMpG,IAAM,yBAAyB,CAAC,iBAAiB,kBAAkB,eAAe,aAAa;AActG,SAAS,aAAa,OAAyB;AAC3C,SAAO,UAAU,UAAa,qBAAqB,KAAK;AAC5D;AAEA,SAAS,aAAa,OAAyB;AAC3C,SAAO,OAAO,cAAc,KAAK,KAAM,SAAoB;AAC/D;AAEA,SAAS,mBAAmB,OAA2C;AACnE,MAAI,CAACA,UAAS,KAAK,EAAG,QAAO;AAC7B,aAAW,KAAK,OAAO,OAAO,KAAK,GAAG;AAClC,QAAI,EAAE,MAAM,QAAQ,OAAO,MAAM,YAAY,OAAO,MAAM,aAAa,OAAO,MAAM,UAAW,QAAO;AAAA,EAC1G;AACA,SAAO;AACX;AAEO,SAAS,iBAAiB,OAAyC;AACtE,MAAI,CAACA,UAAS,KAAK,EAAG,QAAO;AAC7B,MAAI,MAAM,MAAM,+BAA+B,CAAC,qBAAqB,MAAM,OAAO,KAAK,CAACC,gBAAe,MAAM,EAAE,EAAG,QAAO;AACzH,UAAQ,MAAM,GAAG;AAAA,IACb,KAAK,iBAAiB;AAClB,UAAI,CAAC,qBAAqB,MAAM,SAAS,KAAK,CAAC,aAAa,MAAM,UAAU,EAAG,QAAO;AACtF,UAAI,CAAC,qBAAqB,MAAM,aAAa,KAAK,CAAC,qBAAqB,MAAM,SAAS,KAAK,CAAC,aAAa,MAAM,MAAM,EAAG,QAAO;AAChI,UAAI,CAAC,mBAAmB,MAAM,EAAE,EAAG,QAAO;AAC1C,UAAI,MAAM,aAAa,UAAa,CAAE,mBAAyC,SAAS,MAAM,QAAkB,EAAG,QAAO;AAC1H,UAAI,MAAM,UAAU,QAAW;AAC3B,YAAI,CAACD,UAAS,MAAM,KAAK,EAAG,QAAO;AACnC,mBAAW,CAAC,MAAM,EAAE,KAAK,OAAO,QAAQ,MAAM,KAAK,GAAG;AAClD,cAAI,CAAE,oBAA0C,SAAS,IAAI,KAAK,OAAO,OAAO,UAAW,QAAO;AAAA,QACtG;AAAA,MACJ;AACA,UAAI,MAAM,aAAa,UAAa,EAAE,eAAe,MAAM,QAAQ,KAAK,MAAM,SAAS,SAAS,MAAM,IAAK,QAAO;AAClH,aAAO;AAAA,IACX;AAAA,IACA,KAAK;AACD,aAAO,qBAAqB,MAAM,SAAS,KAAK,aAAa,MAAM,UAAU,KAAK,aAAa,MAAM,MAAM,KACpG,cAAc,MAAM,OAAO,KAAK,iBAAiB,MAAM,QAAQ,KAAK,aAAa,MAAM,MAAM;AAAA,IACxG,KAAK;AACD,aAAO,aAAa,MAAM,SAAS,KAAK,aAAa,MAAM,MAAM,KAAK,qBAAqB,MAAM,cAAc,KACxG,aAAa,MAAM,eAAe,KAAK,aAAa,MAAM,MAAM;AAAA,IAC3E,KAAK;AACD,aAAO,qBAAqB,MAAM,UAAU,KAAK,aAAa,MAAM,MAAM,KAAK,aAAa,MAAM,SAAS,KACpG,aAAa,MAAM,MAAM,KAAK,mBAAmB,MAAM,OAAO;AAAA,IACzE;AACI,aAAO;AAAA,EACf;AACJ;AAMO,SAAS,yBACZ,UACA,SAC+C;AAC/C,QAAM,QAAoD,CAAC;AAC3D,MAAI,SAAS,SAAS,YAAY;AAC9B,QAAI,SAAS,OAAQ,OAAM,SAAS;AACpC,QAAI,SAAS,yBAA0B,OAAM,2BAA2B;AAAA,EAC5E;AACA,MAAI,SAAS,SAAS,oBAAoB;AACtC,QAAI,SAAS,aAAc,OAAM,eAAe;AAChD,QAAI,SAAS,gBAAiB,OAAM,kBAAkB;AAAA,EAC1D;AACA,QAAM,SAAS,SAAS;AACxB,SAAO;AAAA,IACH,GAAG;AAAA,IACH,SAAS,SAAS;AAAA,IAClB,IAAI,SAAS;AAAA,IACb,GAAG;AAAA,IACH,WAAW,QAAQ;AAAA,IACnB,YAAY,QAAQ;AAAA,IACpB,eAAe,QAAQ;AAAA,IACvB,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC3B,WAAW,SAAS;AAAA,IACpB,IAAI,SAAS;AAAA,IACb,GAAI,SAAS,SAAS,aAAa,EAAE,UAAU,SAAS,SAAS,IAAI,CAAC;AAAA,IACtE,GAAI,OAAO,KAAK,KAAK,EAAE,SAAS,IAAI,EAAE,MAAM,IAAI,CAAC;AAAA,IACjD;AAAA,EACJ;AACJ;;;AC7jBO,IAAM,qBAAqB;AAAA;AAAA,EAE9B;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AACJ;AAIO,SAAS,kBAAkB,OAA0C;AACxE,SAAO,OAAO,UAAU,YAAa,mBAAyC,SAAS,KAAK;AAChG;AAQO,IAAM,sBAAsB,CAAC,aAAa,QAAQ,OAAO,OAAO,WAAW,WAAW;AAItF,SAAS,oBAAoB,OAA4C;AAC5E,SAAO,OAAO,UAAU,YAAa,oBAA0C,SAAS,KAAK;AACjG;AA2DO,IAAM,gCAAgC;AAGtC,SAAS,6BAA6B,WAAkE;AAC3G,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,OAAO,MAAM,QAAQ,UAAU,OAAO,IAAI,UAAU,QAAQ,UAAU,QAAQ,SAAS,CAAC,IAAI;AAClG,SAAO,MAAM,SACN,UAAU,WACV,UAAU,YACV,0BAA0B,SAAS;AAC9C;AAGO,SAAS,0BAA0B,WAAkE;AACxG,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,SAAS,MAAM,QAAQ,UAAU,OAAO,IACxC,UAAU,QAAQ,KAAK,CAAC,UAAU,MAAM,QAAQ,QAAQ,IACxD;AACN,SAAO,QAAQ,SAAS,UAAU,eAAe,UAAU,aAAa,UAAU;AACtF;AAWO,SAAS,uBAAuB,WAAiF;AACpH,QAAM,QAAQ,6BAA6B,SAAS;AACpD,MAAI,CAAC,aAAa,CAAC,MAAO,QAAO;AACjC,QAAM,WAAW,0BAA0B,SAAS;AACpD,SAAO;AAAA,IACH;AAAA,IACA,GAAI,YAAY,aAAa,QAAQ,EAAE,aAAa,SAAS,IAAI,CAAC;AAAA,IAClE,QAAQ,kBAAkB,UAAU,MAAM,IAAI,UAAU,SAAS;AAAA,EACrE;AACJ;AAQA,IAAM,2BAA2B;AAE1B,SAAS,wBAAwB,OAAoC;AACxE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,yBAAyB,KAAK,OAAO,IAAI,UAAU;AAC9D;AAEA,SAAS,iBAAiB,OAAoC;AAC1D,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ;AACzE;AAEA,SAAS,oBAAoB,KAA0C;AACnE,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,QAAM,SAAS;AACf,QAAM,UAAwC,CAAC;AAC/C,MAAI,MAAM,QAAQ,OAAO,OAAO,GAAG;AAC/B,eAAW,SAAS,OAAO,SAAS;AAChC,UAAI,CAAC,SAAS,OAAO,UAAU,SAAU;AACzC,YAAM,IAAI;AACV,YAAM,QAAQ,WAAW,EAAE,KAAK;AAChC,YAAM,KAAK,iBAAiB,EAAE,EAAE;AAChC,YAAM,MAAM,EAAE,QAAQ,YAAY,EAAE,QAAQ,kBAAkB,EAAE,QAAQ,aAAa,EAAE,MAAM;AAC7F,UAAI,SAAS,OAAO,UAAa,IAAK,SAAQ,KAAK,EAAE,IAAI,OAAO,IAAI,CAAC;AAAA,IACzE;AAAA,EACJ;AACA,QAAM,YAAY,WAAW,OAAO,SAAS;AAC7C,QAAM,cAAc,WAAW,OAAO,WAAW;AACjD,QAAM,kBAAkB,WAAW,OAAO,eAAe;AACzD,QAAM,UAAU,WAAW,OAAO,OAAO;AACzC,QAAM,WAAW,WAAW,OAAO,QAAQ;AAC3C,QAAM,aAAa,iBAAiB,OAAO,UAAU;AACrD,SAAO;AAAA,IACH,QAAQ,kBAAkB,OAAO,MAAM,IAAI,OAAO,SAAS;AAAA,IAC3D,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjC,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,IACrC,GAAI,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,IAC7C,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC7B,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,IAC/B,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,IACjD,SAAS,QAAQ,MAAM,CAAC,6BAA6B;AAAA,EACzD;AACJ;AAOO,SAAS,yBAAyB,KAA+C;AACpF,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,QAAM,SAAS;AACf,QAAM,YAAY,WAAW,OAAO,SAAS;AAC7C,QAAM,eAAe,WAAW,OAAO,YAAY;AACnD,QAAM,aAAa,iBAAiB,OAAO,UAAU;AACrD,QAAM,QAAQ,oBAAoB,OAAO,KAAK;AAC9C,QAAM,gBAAgB,oBAAoB,OAAO,aAAa;AAC9D,MAAI,CAAC,aAAa,CAAC,gBAAgB,eAAe,UAAa,CAAC,SAAS,CAAC,cAAe,QAAO;AAChG,QAAM,kBAAkB,WAAW,OAAO,eAAe;AACzD,QAAM,YAAY,WAAW,OAAO,SAAS;AAC7C,QAAM,oBAAoB,WAAW,OAAO,iBAAiB;AAC7D,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA,GAAI,kBAAkB,EAAE,gBAAgB,IAAI,CAAC;AAAA,IAC7C,GAAI,OAAO,oBAAoB,YAAY,OAAO,oBAAoB,YAChE,EAAE,iBAAiB,OAAO,gBAAgB,IAC1C,CAAC;AAAA,IACP,YAAY,oBAAoB,OAAO,UAAU,IAAI,OAAO,aAAa;AAAA,IACzE;AAAA,IACA,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjC;AAAA,IACA;AAAA,IACA,GAAI,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;AAAA,EACrD;AACJ;;;AC1OO,IAAM,4BAA4B;AAElC,SAASE,gBAAe,OAAiC;AAC5D,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAC7D;AAEO,SAAS,iBAAiB,OAAiC;AAC9D,SAAO,OAAO,cAAc,KAAK,KAAM,SAAoB;AAC/D;AAEO,SAASC,cAAa,OAAyB;AAClD,SAAO,UAAU,UAAa,qBAAqB,KAAK;AAC5D;AAEO,SAASC,aAAY,OAAgC,SAAqC;AAC7F,aAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AAClC,QAAI,CAAC,QAAQ,SAAS,GAAG,EAAG,QAAO;AAAA,EACvC;AACA,SAAO;AACX;AAEO,SAASC,WAAuC,QAAmD;AACtG,QAAM,MAA2B,IAAI,IAAI,MAAM;AAC/C,SAAO,CAAC,UAAuC,OAAO,UAAU,YAAY,IAAI,IAAI,KAAK;AAC7F;AAEO,SAAS,cAAc,OAA4C;AACtE,SAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,CAAC,MAAM,OAAO,MAAM,QAAQ;AAC3E;AAEO,SAAS,sBAAsB,OAAgB,MAAM,KAAc;AACtE,SAAO,UAAU,UAAc,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,KAAK,MAAM,UAAU;AAC3G;AAEO,SAAS,cAAc,OAA6D;AACvF,SAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,QAAQ;AACvD;AAEO,SAAS,iBAAiB,OAAyB;AACtD,SAAO,UAAU,UAAa,SAAS,KAAK;AAChD;AAEO,SAAS,kBAAkB,OAAyB;AACvD,SAAO,UAAU,UAAa,OAAO,UAAU;AACnD;AAEO,SAAS,iBAAiB,OAAyB;AACtD,SAAO,UAAU,UAAa,OAAO,UAAU;AACnD;;;AC9BO,IAAM,wBAAwB,CAAC,WAAW,YAAY,UAAU;AAEvE,IAAM,uBAAuBC,WAAU,qBAAqB;AAc5D,SAAS,qBAAqB,OAA6C;AACvE,SAAO,SAAS,KAAK,KAAKC,aAAY,OAAO,CAAC,KAAK,UAAU,CAAC,KACvD,MAAM,MAAM,6BACZ,eAAe,MAAM,QAAQ;AACxC;AAEO,SAAS,yBAAyB,OAA2C;AAChF,SAAO,qBAAqB,KAAK,IAAI,QAAQ;AACjD;AAEA,SAAS,sBAAsB,OAAyC;AACpE,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,aAAa,YAAY,CAAC,KACjE,qBAAqB,MAAM,SAAS,KAAK,iBAAiB,MAAM,UAAU;AACrF;AAEA,SAAS,sBAAsB,OAA8C;AACzE,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,WAAW,cAAc,SAAS,CAAC,KAC1E,qBAAqB,MAAM,OAAO,KAClC,sBAAsB,MAAM,UAAU,MACrC,MAAM,YAAY,UAAa,mBAAmB,MAAM,OAAO;AAC3E;AAEA,IAAM,sBAAsB,CAAC,aAAa,UAAU,WAAW;AAC/D,SAAS,mBAAmB,OAAsC;AAC9D,SAAO,OAAO,UAAU,YAAa,oBAA0C,SAAS,KAAK;AACjG;AAEO,SAAS,0BAA0B,OAA4C;AAClF,SAAO,sBAAsB,KAAK,IAAI,QAAQ;AAClD;AAYO,IAAM,2BAA2B;AAAA;AAAA,EAEpC;AAAA,EAAU;AAAA,EAAc;AAAA,EAAa;AAAA,EAAa;AAAA,EAAgB;AAAA,EAAY;AAAA,EAAqB;AAAA;AAAA,EAEnG;AAAA,EAAU;AAAA,EAAa;AAAA,EAAgB;AAAA,EAAa;AAAA,EAAsB;AAAA;AAAA,EAE1E;AAAA,EAAU;AAAA,EAAU;AAAA,EAAW;AAAA,EAAgB;AAAA,EAC/C;AAAA,EAAU;AAAA;AAAA,EAEV;AAAA,EAAa;AAAA,EAAW;AAAA,EAAU;AAAA,EAAY;AAAA,EAAqB;AAAA,EAAkB;AAAA,EACrF;AAAA,EAAqB;AAAA,EAAe;AAAA;AAAA,EAEpC;AAAA,EAAW;AAAA,EAAgB;AAC/B;AAEA,IAAM,8BAAmD,IAAI,IAAI,wBAAwB;AAGlF,IAAM,yBAAyB;AAoBtC,SAAS,wBAAwB,OAA2C;AACxE,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,aAAW,KAAK,OAAO,OAAO,KAAK,GAAG;AAClC,QAAI,MAAM,KAAM;AAChB,QAAI,OAAO,MAAM,aAAa,OAAO,MAAM,SAAU;AACrD,QAAI,OAAO,MAAM,UAAU;AAAE,UAAI,EAAE,SAAS,uBAAwB,QAAO;AAAO;AAAA,IAAS;AAC3F,WAAO;AAAA,EACX;AACA,SAAO;AACX;AAGO,SAAS,oBAAoB,OAA2C;AAC3E,MAAI,CAAC,wBAAwB,KAAK,EAAG,QAAO;AAC5C,aAAW,OAAO,OAAO,KAAK,KAAgC,GAAG;AAC7D,QAAI,CAAC,4BAA4B,IAAI,GAAG,EAAG,QAAO;AAAA,EACtD;AACA,SAAO;AACX;AAEA,SAAS,oBAAoB,OAA4C;AACrE,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,KAAK,UAAU,cAAc,UAAU,aAAa,UAAU,SAAS,CAAC,KAC/G,MAAM,MAAM,6BACZ,qBAAqB,MAAM,MAAM,KACjC,qBAAqB,MAAM,UAAU,KACrCC,cAAa,MAAM,MAAM,KAAKA,cAAa,MAAM,SAAS,KAAKA,cAAa,MAAM,MAAM,KACxF,oBAAoB,MAAM,OAAO;AAC5C;AAEO,SAAS,wBAAwB,OAA0C;AAC9E,SAAO,oBAAoB,KAAK,IAAI,QAAQ;AAChD;AAEA,SAAS,qBAAqB,OAA6C;AACvE,SAAO,SAAS,KAAK,KAAKD,aAAY,OAAO,CAAC,WAAW,KAAK,CAAC,KACxD,qBAAqB,MAAM,OAAO,KAAK,iBAAiB,MAAM,GAAG;AAC5E;AAEO,SAAS,yBAAyB,OAA2C;AAChF,SAAO,qBAAqB,KAAK,IAAI,QAAQ;AACjD;AAiBA,SAAS,oBAAoB,OAA4C;AACrE,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,KAAK,aAAa,UAAU,QAAQ,CAAC,EAAG,QAAO;AAC5F,MAAI,MAAM,MAAM,0BAA2B,QAAO;AAClD,QAAM,aAAa,MAAM,cAAc;AACvC,QAAM,UAAU,MAAM,WAAW;AACjC,MAAI,eAAe,QAAS,QAAO;AACnC,MAAI,cAAc,CAAC,qBAAqB,MAAM,SAAS,EAAG,QAAO;AACjE,MAAI,WAAW,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AAC3D,SAAO,aAAa,MAAM,MAAM;AACpC;AAEO,SAAS,wBAAwB,OAA0C;AAC9E,SAAO,oBAAoB,KAAK,IAAI,QAAQ;AAChD;AAEA,SAAS,qBAAqB,OAA6C;AACvE,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,cAAc,SAAS,CAAC,KAC/D,sBAAsB,MAAM,UAAU,KAAK,qBAAqB,MAAM,OAAO;AACxF;AAEO,SAAS,yBAAyB,OAA2C;AAChF,SAAO,qBAAqB,KAAK,IAAI,QAAQ;AACjD;AAoBO,IAAM,yBAAyB,CAAC,aAAa,QAAQ;AAE5D,IAAM,wBAAwBD,WAAU,sBAAsB;AAEvD,IAAM,gCAAgC,CAAC,mBAAmB,mBAAmB,qBAAqB;AAEzG,IAAM,8BAA8BA,WAAU,6BAA6B;AAc3E,SAAS,wBAAwB,OAAgD;AAC7E,SAAO,SAAS,KAAK,KAAKC,aAAY,OAAO,CAAC,KAAK,UAAU,UAAU,QAAQ,CAAC,KACzE,MAAM,MAAM,6BACZ,qBAAqB,MAAM,MAAM,KACjC,sBAAsB,MAAM,MAAM,KAClC,4BAA4B,MAAM,MAAM;AACnD;AAEO,SAAS,4BAA4B,OAA8C;AACtF,SAAO,wBAAwB,KAAK,IAAI,QAAQ;AACpD;AAEA,SAAS,yBAAyB,OAAiD;AAC/E,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,UAAU,CAAC,KAAK,MAAM,aAAa;AACrF;AAEO,SAAS,6BAA6B,OAA+C;AACxF,SAAO,yBAAyB,KAAK,IAAI,QAAQ;AACrD;AAkDA,SAAS,mBAAmB,OAA2C;AACnE,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,KAAK,UAAU,UAAU,aAAa,aAAa,SAAS,SAAS,MAAM,CAAC,KACnH,MAAM,MAAM,6BACZ,qBAAqB,MAAM,MAAM,KACjCC,cAAa,MAAM,MAAM,KAAKA,cAAa,MAAM,SAAS,KAAKA,cAAa,MAAM,SAAS,MAC1F,MAAM,UAAU,UAAa,qBAAqB,MAAM,KAAK,OAC7D,MAAM,UAAU,UAAaC,gBAAe,MAAM,KAAK,OACvD,MAAM,SAAS,UAAa,iBAAiB,MAAM,IAAI;AACnE;AAEO,SAAS,uBAAuB,OAAyC;AAC5E,SAAO,mBAAmB,KAAK,IAAI,QAAQ;AAC/C;AAEA,IAAM,8BAA8B;AAAA,EAChC;AAAA,EAAa;AAAA,EAAc;AAAA,EAAU;AAAA,EAAU;AAAA,EAAa;AAAA,EAAU;AAAA,EACtE;AAAA,EAAS;AAAA,EAAmB;AAAA,EAAkB;AAAA,EAAc;AAChE;AAEA,SAAS,sBAAsB,OAA8C;AACzE,MAAI,CAAC,SAAS,KAAK,KAAK,CAACF,aAAY,OAAO,2BAA2B,EAAG,QAAO;AACjF,MAAI,CAAC,qBAAqB,MAAM,SAAS,KAAK,CAAC,iBAAiB,MAAM,UAAU,EAAG,QAAO;AAC1F,MAAI,CAACC,cAAa,MAAM,MAAM,KAAK,CAACA,cAAa,MAAM,MAAM,EAAG,QAAO;AACvE,MAAI,CAAC,qBAAqB,MAAM,SAAS,EAAG,QAAO;AACnD,MAAI,CAACA,cAAa,MAAM,MAAM,KAAK,CAACA,cAAa,MAAM,YAAY,EAAG,QAAO;AAC7E,MAAI,OAAO,MAAM,UAAU,SAAU,QAAO;AAC5C,MAAI,MAAM,oBAAoB,UAAa,CAAC,mBAAmB,MAAM,eAAe,EAAG,QAAO;AAC9F,MAAI,MAAM,mBAAmB,UAAa,CAAC,aAAa,MAAM,cAAc,EAAG,QAAO;AACtF,MAAI,CAACC,gBAAe,MAAM,UAAU,EAAG,QAAO;AAC9C,MAAI,MAAM,eAAe,UAAa,CAACA,gBAAe,MAAM,UAAU,EAAG,QAAO;AAChF,SAAO;AACX;AAEA,IAAM,4BAA4B,CAAC,WAAW,YAAY,YAAY,WAAW;AACjF,IAAM,4BAA4B,CAAC,WAAW,aAAa,cAAc,aAAa,QAAQ,UAAU,WAAW,MAAM;AAEzH,SAAS,oBAAoB,OAA4C;AACrE,MAAI,CAAC,SAAS,KAAK,KAAK,CAACF,aAAY,OAAO,yBAAyB,EAAG,QAAO;AAC/E,MAAI,CAAC,qBAAqB,MAAM,OAAO,EAAG,QAAO;AACjD,MAAI,CAACC,cAAa,MAAM,SAAS,EAAG,QAAO;AAC3C,MAAI,MAAM,eAAe,UAAa,CAAC,iBAAiB,MAAM,UAAU,EAAG,QAAO;AAClF,MAAI,CAAC,qBAAqB,MAAM,SAAS,EAAG,QAAO;AACnD,MAAI,OAAO,MAAM,SAAS,SAAU,QAAO;AAC3C,MAAI,OAAO,MAAM,WAAW,SAAU,QAAO;AAC7C,MAAI,CAAE,0BAAgD,SAAS,MAAM,OAAiB,EAAG,QAAO;AAChG,MAAI,CAACC,gBAAe,MAAM,IAAI,EAAG,QAAO;AACxC,SAAO;AACX;AAEA,SAAS,oBAAoB,OAA4C;AACrE,MAAI,CAAC,SAAS,KAAK,KAAK,CAACF,aAAY,OAAO,CAAC,YAAY,UAAU,oBAAoB,CAAC,EAAG,QAAO;AAClG,MAAI,CAAC,MAAM,QAAQ,MAAM,QAAQ,KAAK,CAAC,MAAM,SAAS,MAAM,qBAAqB,EAAG,QAAO;AAC3F,MAAI,CAAC,MAAM,QAAQ,MAAM,MAAM,KAAK,CAAC,MAAM,OAAO,MAAM,mBAAmB,EAAG,QAAO;AACrF,MAAI,MAAM,uBAAuB,UAAa,OAAO,MAAM,uBAAuB,UAAW,QAAO;AACpG,SAAO;AACX;AAEO,SAAS,wBAAwB,OAA0C;AAC9E,SAAO,oBAAoB,KAAK,IAAI,QAAQ;AAChD;AAIO,IAAM,iCAAiC,CAAC,OAAO,OAAO;AAE7D,IAAM,8BAA8BD,WAAU,8BAA8B;AAkC5E,SAAS,wBAAwB,OAAgD;AAC7E,SAAO,SAAS,KAAK,KAAKC,aAAY,OAAO,CAAC,KAAK,UAAU,cAAc,aAAa,UAAU,UAAU,SAAS,MAAM,CAAC,KACrH,MAAM,MAAM,6BACZ,qBAAqB,MAAM,MAAM,KACjCC,cAAa,MAAM,UAAU,KAAKA,cAAa,MAAM,SAAS,KAAKA,cAAa,MAAM,MAAM,MAC3F,MAAM,WAAW,UAAa,4BAA4B,MAAM,MAAM,OACtE,MAAM,UAAU,UAAaC,gBAAe,MAAM,KAAK,OACvD,MAAM,SAAS,UAAa,iBAAiB,MAAM,IAAI;AACnE;AAEO,SAAS,4BAA4B,OAA8C;AACtF,SAAO,wBAAwB,KAAK,IAAI,QAAQ;AACpD;AAEA,IAAM,4BAA4B;AAAA,EAC9B;AAAA,EAAU;AAAA,EAAO;AAAA,EAAU;AAAA,EAAW;AAAA,EAAQ;AAAA,EAAc;AAAA,EAAU;AAAA,EAAa;AAAA,EAAU;AAAA,EAAQ;AACzG;AAEA,SAAS,oBAAoB,OAA4C;AACrE,MAAI,CAAC,SAAS,KAAK,KAAK,CAACF,aAAY,OAAO,yBAAyB,EAAG,QAAO;AAC/E,MAAI,CAAC,qBAAqB,MAAM,MAAM,KAAK,CAAC,iBAAiB,MAAM,GAAG,EAAG,QAAO;AAChF,MAAI,CAAC,qBAAqB,MAAM,MAAM,KAAK,CAAC,qBAAqB,MAAM,OAAO,EAAG,QAAO;AACxF,MAAI,OAAO,MAAM,SAAS,SAAU,QAAO;AAC3C,MAAI,CAACC,cAAa,MAAM,UAAU,KAAK,CAACA,cAAa,MAAM,MAAM,KAAK,CAACA,cAAa,MAAM,SAAS,KAAK,CAACA,cAAa,MAAM,MAAM,EAAG,QAAO;AAC5I,MAAI,CAACC,gBAAe,MAAM,IAAI,EAAG,QAAO;AAIxC,MAAI,CAAC,oBAAoB,MAAM,OAAO,EAAG,QAAO;AAChD,SAAO;AACX;AAEO,SAAS,yBAAyB,OAAiD;AACtF,MAAI,CAAC,SAAS,KAAK,KAAK,CAACF,aAAY,OAAO,CAAC,QAAQ,oBAAoB,CAAC,EAAG,QAAO;AACpF,MAAI,CAAC,MAAM,QAAQ,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,mBAAmB,EAAG,QAAO;AACjF,MAAI,MAAM,uBAAuB,UAAa,OAAO,MAAM,uBAAuB,UAAW,QAAO;AACpG,SAAO;AACX;AAEO,SAAS,6BAA6B,OAA+C;AACxF,SAAO,yBAAyB,KAAK,IAAI,QAAQ;AACrD;;;AC1ZO,IAAM,wBAAwB,CAAC,UAAU,UAAU,aAAa,WAAW;AAE3E,IAAM,2BAA2BG,WAAU,qBAAqB;AAkBvE,SAAS,mBAAmB,OAA2C;AACnE,MAAI,CAAC,SAAS,KAAK,KAAK,CAACC,aAAY,OAAO,CAAC,QAAQ,eAAe,gBAAgB,gBAAgB,YAAY,CAAC,EAAG,QAAO;AAC3H,MAAI,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,KAAK,EAAE,WAAW,EAAG,QAAO;AAC7E,aAAW,KAAK,CAAC,eAAe,gBAAgB,gBAAgB,YAAY,GAAY;AACpF,QAAI,MAAM,CAAC,MAAM,UAAa,CAAC,cAAc,MAAM,CAAC,CAAC,EAAG,QAAO;AAAA,EACnE;AACA,SAAO;AACX;AAkCA,SAAS,wBAAwB,OAAgD;AAC7E,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,MAAM,UAAU,SAAS,QAAQ,UAAU,OAAO,CAAC,EAAG,QAAO;AAC1G,MAAI,CAAC,qBAAqB,MAAM,EAAE,KAAK,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AACnF,MAAI,OAAO,MAAM,UAAU,YAAY,OAAO,MAAM,SAAS,SAAU,QAAO;AAC9E,MAAI,CAAC,yBAAyB,MAAM,MAAM,EAAG,QAAO;AACpD,MAAI,MAAM,UAAU,UAAa,CAAC,mBAAmB,MAAM,KAAK,EAAG,QAAO;AAC1E,SAAO;AACX;AAEA,SAAS,uBAAuB,OAA+C;AAC3E,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,KAAK,UAAU,MAAM,SAAS,QAAQ,UAAU,OAAO,CAAC,EAAG,QAAO;AAC/G,MAAI,MAAM,MAAM,0BAA2B,QAAO;AAClD,MAAI,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AAChD,MAAI,MAAM,OAAO,UAAa,CAAC,qBAAqB,MAAM,EAAE,EAAG,QAAO;AACtE,MAAI,OAAO,MAAM,UAAU,YAAY,MAAM,MAAM,KAAK,EAAE,WAAW,EAAG,QAAO;AAC/E,MAAI,MAAM,SAAS,UAAa,OAAO,MAAM,SAAS,SAAU,QAAO;AACvE,MAAI,MAAM,WAAW,UAAa,CAAC,yBAAyB,MAAM,MAAM,EAAG,QAAO;AAClF,MAAI,MAAM,UAAU,UAAa,MAAM,UAAU,QAAQ,CAAC,mBAAmB,MAAM,KAAK,EAAG,QAAO;AAClG,SAAO;AACX;AAEO,SAAS,2BAA2B,OAA6C;AACpF,SAAO,uBAAuB,KAAK,IAAI,QAAQ;AACnD;AAEO,SAAS,wBAAwB,OAAgD;AACpF,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,SAAS,CAAC,KAAK,wBAAwB,MAAM,OAAO;AACtG;AAEO,SAAS,4BAA4B,OAA8C;AACtF,SAAO,wBAAwB,KAAK,IAAI,QAAQ;AACpD;AAeA,SAAS,sBAAsB,OAA8C;AACzE,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,KAAK,UAAU,YAAY,IAAI,CAAC,EAAG,QAAO;AACvF,MAAI,MAAM,MAAM,0BAA2B,QAAO;AAClD,MAAI,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AAChD,MAAI,MAAM,OAAO,UAAa,CAAC,qBAAqB,MAAM,EAAE,EAAG,QAAO;AACtE,MAAI,MAAM,aAAa,QAAW;AAC9B,QAAI,CAAC,MAAM,QAAQ,MAAM,QAAQ,KAAK,MAAM,SAAS,WAAW,EAAG,QAAO;AAC1E,QAAI,CAAC,MAAM,SAAS,MAAM,wBAAwB,EAAG,QAAO;AAAA,EAChE;AACA,SAAO;AACX;AAEO,SAAS,0BAA0B,OAA4C;AAClF,SAAO,sBAAsB,KAAK,IAAI,QAAQ;AAClD;AAEA,SAAS,uBAAuB,OAA+C;AAC3E,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,UAAU,CAAC,KAClD,MAAM,QAAQ,MAAM,QAAQ,KAAK,MAAM,SAAS,MAAM,uBAAuB;AACxF;AAEO,SAAS,2BAA2B,OAA6C;AACpF,SAAO,uBAAuB,KAAK,IAAI,QAAQ;AACnD;AAiHA,SAAS,0BAA0B,OAAkD;AACjF,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,KAAK,UAAU,YAAY,WAAW,aAAa,SAAS,kBAAkB,gBAAgB,CAAC,EAAG,QAAO;AACtJ,MAAI,MAAM,mBAAmB,UAAa,MAAM,mBAAmB,aAAa,MAAM,mBAAmB,UAAW,QAAO;AAC3H,MAAI,MAAM,MAAM,0BAA2B,QAAO;AAClD,MAAI,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AAChD,MAAI,MAAM,aAAa,QAAW;AAC9B,QAAI,CAAC,MAAM,QAAQ,MAAM,QAAQ,KAAK,MAAM,SAAS,WAAW,EAAG,QAAO;AAC1E,QAAI,CAAC,MAAM,SAAS,MAAM,wBAAwB,EAAG,QAAO;AAAA,EAChE;AACA,MAAI,MAAM,YAAY,UAAa,OAAO,MAAM,YAAY,UAAW,QAAO;AAC9E,MAAI,MAAM,cAAc,UAAa,OAAO,MAAM,cAAc,UAAW,QAAO;AAClF,MAAI,MAAM,UAAU,UAAa,CAAC,iBAAiB,MAAM,KAAK,EAAG,QAAO;AACxE,MAAI,MAAM,mBAAmB,UAAa,CAAC,iBAAiB,MAAM,cAAc,EAAG,QAAO;AAC1F,SAAO;AACX;AAEO,SAAS,8BAA8B,OAAgD;AAC1F,SAAO,0BAA0B,KAAK,IAAI,QAAQ;AACtD;AAEA,SAAS,+BAA+B,OAAuD;AAC3F,QAAM,OAAO,CAAC,SAAS,WAAW,YAAY,aAAa,UAAU,aAAa,WAAW,gBAAgB;AAC7G,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,IAAI,EAAG,QAAO;AAC1D,aAAW,KAAK,CAAC,SAAS,WAAW,YAAY,aAAa,UAAU,aAAa,SAAS,GAAY;AACtG,QAAI,CAAC,iBAAiB,MAAM,CAAC,CAAC,EAAG,QAAO;AAAA,EAC5C;AACA,SAAO,MAAM,mBAAmB,QAAQ,OAAO,MAAM,mBAAmB;AAC5E;AAEA,SAAS,uBAAuB,OAA+C;AAC3E,QAAM,OAAO,CAAC,aAAa,aAAa,aAAa,UAAU,mBAAmB,eAAe,WAAW,mBAAmB;AAC/H,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,IAAI,EAAG,QAAO;AAC1D,MAAI,CAAC,qBAAqB,MAAM,SAAS,EAAG,QAAO;AACnD,aAAW,KAAK,CAAC,aAAa,aAAa,UAAU,mBAAmB,SAAS,GAAY;AACzF,QAAI,CAAC,iBAAiB,MAAM,CAAC,CAAC,EAAG,QAAO;AAAA,EAC5C;AACA,MAAI,MAAM,gBAAgB,QAAQ,CAAC,iBAAiB,MAAM,WAAW,EAAG,QAAO;AAC/E,MAAI,CAAC,MAAM,QAAQ,MAAM,iBAAiB,KAAK,CAAC,MAAM,kBAAkB,MAAM,oBAAoB,EAAG,QAAO;AAC5G,SAAO;AACX;AAEA,SAAS,yBAAyB,OAAiD;AAC/E,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,UAAU,UAAU;AAC1B,QAAM,aAAa,iBAAiB,SAAS,mBAAmB;AAChE,MAAI,YAAY,WAAY,QAAO;AACnC,QAAM,WAAW,CAAC,MAAM,UAAU,SAAS,UAAU,SAAS,SAAS,SAAS,aAAa,aAAa,yBAAyB;AACnI,QAAM,UAAU,UAAU,CAAC,GAAG,UAAU,MAAM,IAAI,CAAC,GAAG,UAAU,eAAe,eAAe;AAC9F,MAAI,CAACA,aAAY,OAAO,OAAO,EAAG,QAAO;AACzC,MAAI,CAAC,qBAAqB,MAAM,EAAE,KAAK,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AACnF,MAAI,OAAO,MAAM,UAAU,SAAU,QAAO;AAC5C,MAAI,CAAC,yBAAyB,MAAM,MAAM,EAAG,QAAO;AACpD,MAAI,CAAC,+BAA+B,MAAM,KAAK,EAAG,QAAO;AACzD,MAAI,MAAM,UAAU,UAAa,CAAC,uBAAuB,MAAM,KAAK,EAAG,QAAO;AAC9E,MAAI,MAAM,UAAU,UAAa,CAAC,mBAAmB,MAAM,KAAK,EAAG,QAAO;AAC1E,MAAI,WAAW,OAAO,MAAM,SAAS,SAAU,QAAO;AACtD,MAAI,eAAe,OAAO,MAAM,gBAAgB,YAAY,OAAO,MAAM,kBAAkB,WAAY,QAAO;AAC9G,MAAI,MAAM,cAAc,UAAa,OAAO,MAAM,cAAc,SAAU,QAAO;AACjF,MAAI,MAAM,cAAc,UAAa,OAAO,MAAM,cAAc,SAAU,QAAO;AACjF,MAAI,MAAM,4BAA4B,UAAa,MAAM,4BAA4B,QAAQ,OAAO,MAAM,4BAA4B,SAAU,QAAO;AACvJ,SAAO;AACX;AAEA,SAAS,6BAA6B,OAAqD;AACvF,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,SAAS,YAAY,cAAc,MAAM,CAAC,EAAG,QAAO;AACjG,MAAI,CAAC,iBAAiB,MAAM,KAAK,EAAG,QAAO;AAC3C,MAAI,CAAC,SAAS,MAAM,QAAQ,KAAK,CAAC,OAAO,OAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,iBAAiB,CAAC,CAAC,EAAG,QAAO;AAC1G,MAAI,CAAC,MAAM,QAAQ,MAAM,UAAU,KAAK,CAAC,MAAM,WAAW,MAAM,oBAAoB,EAAG,QAAO;AAC9F,SAAO,OAAO,MAAM,SAAS;AACjC;AAEA,SAAS,2BAA2B,OAAmD;AACnF,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,YAAY,eAAe,aAAa,WAAW,aAAa,CAAC,EAAG,QAAO;AACxH,MAAI,CAAC,MAAM,QAAQ,MAAM,QAAQ,KAAK,CAAC,MAAM,SAAS,MAAM,wBAAwB,EAAG,QAAO;AAC9F,MAAI,MAAM,gBAAgB,QAAQ,CAAC,6BAA6B,MAAM,WAAW,EAAG,QAAO;AAC3F,MAAI,OAAO,MAAM,cAAc,UAAW,QAAO;AACjD,MAAI,CAAC,iBAAiB,MAAM,OAAO,EAAG,QAAO;AAC7C,MAAI,MAAM,gBAAgB,WAAc,CAAC,MAAM,QAAQ,MAAM,WAAW,KAAK,CAAC,MAAM,YAAY,MAAM,oBAAoB,GAAI,QAAO;AACrI,SAAO;AACX;AAEO,SAAS,+BAA+B,OAAiD;AAC5F,SAAO,2BAA2B,KAAK,IAAI,QAAQ;AACvD;AAYO,IAAM,4BAA4B,CAAC,kBAAkB,oBAAoB,iBAAiB;AAEjG,IAAM,0BAA0BD,WAAU,yBAAyB;AAyBnE,SAAS,oBAAoB,OAA4C;AACrE,MAAI,CAAC,SAAS,KAAK,KAAK,CAACC,aAAY,OAAO,CAAC,KAAK,UAAU,QAAQ,YAAY,UAAU,aAAa,cAAc,cAAc,mBAAmB,CAAC,EAAG,QAAO;AACjK,MAAI,MAAM,MAAM,0BAA2B,QAAO;AAClD,MAAI,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AAChD,MAAI,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,KAAK,EAAE,WAAW,EAAG,QAAO;AAC7E,MAAI,MAAM,aAAa,UAAa,CAAC,wBAAwB,MAAM,QAAQ,EAAG,QAAO;AACrF,MAAI,MAAM,WAAW,UAAa,OAAO,MAAM,WAAW,UAAW,QAAO;AAC5E,MAAI,MAAM,cAAc,WAAc,OAAO,MAAM,cAAc,YAAY,OAAO,MAAM,KAAK,MAAM,MAAM,SAAS,CAAC,GAAI,QAAO;AAChI,SAAO,sBAAsB,MAAM,UAAU,KAAK,sBAAsB,MAAM,UAAU,KAAK,sBAAsB,MAAM,iBAAiB;AAC9I;AAEO,SAAS,wBAAwB,OAA0C;AAC9E,SAAO,oBAAoB,KAAK,IAAI,QAAQ;AAChD;AAEA,SAAS,qBAAqB,OAA6C;AACvE,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,UAAU,WAAW,WAAW,CAAC,KACxE,qBAAqB,MAAM,MAAM,KAAK,OAAO,MAAM,YAAY,aAAa,OAAO,MAAM,cAAc;AAClH;AAEO,SAAS,yBAAyB,OAA2C;AAChF,SAAO,qBAAqB,KAAK,IAAI,QAAQ;AACjD;AAiBA,SAAS,oBAAoB,OAA4C;AACrE,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,KAAK,UAAU,UAAU,QAAQ,QAAQ,CAAC,EAAG,QAAO;AACjG,MAAI,MAAM,MAAM,0BAA2B,QAAO;AAClD,MAAI,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AAChD,MAAI,MAAM,WAAW,UAAa,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AAC9E,MAAI,MAAM,SAAS,WAAc,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,KAAK,EAAE,WAAW,GAAI,QAAO;AAC3G,MAAI,MAAM,WAAW,UAAa,MAAM,SAAS,OAAW,QAAO;AACnE,SAAO,MAAM,WAAW,UAAa,OAAO,MAAM,WAAW;AACjE;AAEO,SAAS,wBAAwB,OAA0C;AAC9E,SAAO,oBAAoB,KAAK,IAAI,QAAQ;AAChD;AAEA,SAAS,qBAAqB,OAA6C;AACvE,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,WAAW,aAAa,CAAC,KAChE,OAAO,MAAM,YAAY,YAAY,OAAO,UAAU,MAAM,OAAO,KAAK,MAAM,WAAW,KACzF,qBAAqB,MAAM,WAAW;AACjD;AAEO,SAAS,yBAAyB,OAA2C;AAChF,SAAO,qBAAqB,KAAK,IAAI,QAAQ;AACjD;AAiBO,IAAM,oBAAoB,CAAC,eAAe,SAAS;AAE1D,IAAM,mBAAmBD,WAAU,iBAAiB;AAkBpD,SAAS,wBAAwB,OAAgD;AAC7E,SAAO,SAAS,KAAK,KAAKC,aAAY,OAAO,CAAC,KAAK,UAAU,QAAQ,aAAa,YAAY,CAAC,KACxF,MAAM,MAAM,6BACZ,qBAAqB,MAAM,MAAM,KACjC,qBAAqB,MAAM,IAAI,KAC/BC,cAAa,MAAM,SAAS,KAC5B,iBAAiB,MAAM,UAAU;AAC5C;AAEO,SAAS,4BAA4B,OAA8C;AACtF,SAAO,wBAAwB,KAAK,IAAI,QAAQ;AACpD;AAEA,SAAS,yBAAyB,OAAiD;AAC/E,SAAO,SAAS,KAAK,KAAKD,aAAY,OAAO,CAAC,qBAAqB,iBAAiB,UAAU,CAAC,KACxF,OAAO,MAAM,sBAAsB,aACnC,iBAAiB,MAAM,aAAa,MACnC,MAAM,aAAa,QAAQ,OAAO,MAAM,aAAa;AACjE;AAEO,SAAS,6BAA6B,OAA+C;AACxF,SAAO,yBAAyB,KAAK,IAAI,QAAQ;AACrD;AAwEA,SAAS,qBAAqB,OAA6C;AACvE,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,KAAK,UAAU,QAAQ,SAAS,QAAQ,QAAQ,gBAAgB,CAAC,EAAG,QAAO;AACxH,MAAI,MAAM,MAAM,0BAA2B,QAAO;AAClD,MAAI,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AAChD,MAAI,MAAM,SAAS,WAAc,CAAC,MAAM,QAAQ,MAAM,IAAI,KAAK,MAAM,KAAK,WAAW,KAAK,CAAC,MAAM,KAAK,MAAM,oBAAoB,GAAI,QAAO;AAC3I,MAAI,MAAM,UAAU,UAAa,OAAO,MAAM,UAAU,SAAU,QAAO;AACzE,MAAI,CAACC,cAAa,MAAM,IAAI,EAAG,QAAO;AACtC,MAAI,MAAM,SAAS,UAAa,CAAC,iBAAiB,MAAM,IAAI,EAAG,QAAO;AACtE,MAAI,MAAM,mBAAmB,UAAa,OAAO,MAAM,mBAAmB,UAAW,QAAO;AAC5F,SAAO;AACX;AAEO,SAAS,yBAAyB,OAA2C;AAChF,SAAO,qBAAqB,KAAK,IAAI,QAAQ;AACjD;AAEA,IAAM,0BAA0B,CAAC,MAAM,UAAU,aAAa,QAAQ,UAAU,aAAa,gBAAgB,UAAU,SAAS;AAEhI,SAAS,uBAAuB,OAA+C;AAC3E,MAAI,CAAC,SAAS,KAAK,KAAK,CAACD,aAAY,OAAO,uBAAuB,EAAG,QAAO;AAC7E,MAAI,CAAC,qBAAqB,MAAM,EAAE,KAAK,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AACnF,MAAI,OAAO,MAAM,cAAc,YAAY,OAAO,MAAM,SAAS,SAAU,QAAO;AAClF,MAAI,CAACC,cAAa,MAAM,MAAM,KAAK,CAACA,cAAa,MAAM,SAAS,KAAK,CAACA,cAAa,MAAM,YAAY,KAAK,CAACA,cAAa,MAAM,MAAM,EAAG,QAAO;AAC9I,MAAI,CAAC,SAAS,MAAM,OAAO,EAAG,QAAO;AACrC,SAAO;AACX;AAEA,SAAS,yBAAyB,OAAiD;AAC/E,QAAM,OAAO,CAAC,UAAU,gBAAgB,kBAAkB,iBAAiB,cAAc,eAAe,mBAAmB,qBAAqB,kBAAkB,gBAAgB;AAClL,MAAI,CAAC,SAAS,KAAK,KAAK,CAACD,aAAY,OAAO,IAAI,EAAG,QAAO;AAC1D,MAAI,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AAChD,aAAW,KAAK,CAAC,gBAAgB,kBAAkB,iBAAiB,cAAc,eAAe,mBAAmB,qBAAqB,gBAAgB,GAAY;AACjK,QAAI,CAAC,iBAAiB,MAAM,CAAC,CAAC,EAAG,QAAO;AAAA,EAC5C;AACA,MAAI,MAAM,mBAAmB,QAAQ,OAAO,MAAM,mBAAmB,SAAU,QAAO;AACtF,SAAO;AACX;AAEA,SAAS,sBAAsB,OAA8C;AACzE,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,WAAW,SAAS,CAAC,EAAG,QAAO;AAC5E,MAAI,CAAC,MAAM,QAAQ,MAAM,OAAO,KAAK,CAAC,MAAM,QAAQ,MAAM,sBAAsB,EAAG,QAAO;AAC1F,MAAI,MAAM,YAAY,UAAa,CAAC,yBAAyB,MAAM,OAAO,EAAG,QAAO;AACpF,SAAO;AACX;AAEO,SAAS,0BAA0B,OAA4C;AAClF,SAAO,sBAAsB,KAAK,IAAI,QAAQ;AAClD;;;AC3lBA,SAAS,iBAAiB,OAAyC;AAC/D,SAAO,SAAS,KAAK,KAAK,qBAAqB,MAAM,EAAE,KAAK,OAAO,MAAM,WAAW;AACxF;AA6BA,SAAS,qBAAqB,OAA6C;AACvE,SAAO,SAAS,KAAK,KAAKE,aAAY,OAAO,CAAC,KAAK,UAAU,QAAQ,UAAU,aAAa,gBAAgB,UAAU,SAAS,CAAC,KACzH,MAAM,MAAM,6BACZ,qBAAqB,MAAM,MAAM,KACjC,qBAAqB,MAAM,IAAI,KAC/BC,cAAa,MAAM,MAAM,KAAKA,cAAa,MAAM,SAAS,KAAKA,cAAa,MAAM,YAAY,KAAKA,cAAa,MAAM,MAAM,KAC5H,SAAS,MAAM,OAAO;AACjC;AAEO,SAAS,yBAAyB,OAA2C;AAChF,SAAO,qBAAqB,KAAK,IAAI,QAAQ;AACjD;AAEA,SAAS,sBAAsB,OAA8C;AACzE,SAAO,SAAS,KAAK,KAAKD,aAAY,OAAO,CAAC,WAAW,aAAa,iBAAiB,WAAW,CAAC,KAC5F,qBAAqB,MAAM,OAAO,KAAK,OAAO,MAAM,cAAc,YAClE,OAAO,MAAM,kBAAkB,aAAa,OAAO,MAAM,cAAc;AAClF;AAEO,SAAS,0BAA0B,OAA4C;AAClF,SAAO,sBAAsB,KAAK,IAAI,QAAQ;AAClD;AA8CA,SAAS,oBAAoB,OAA4C;AACrE,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,KAAK,UAAU,YAAY,UAAU,QAAQ,cAAc,yBAAyB,qBAAqB,CAAC,EAAG,QAAO;AACjK,MAAI,MAAM,MAAM,6BAA6B,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AACzF,MAAI,MAAM,aAAa,WAAc,CAAC,MAAM,QAAQ,MAAM,QAAQ,KAAK,CAAC,MAAM,SAAS,MAAM,oBAAoB,GAAI,QAAO;AAC5H,MAAI,MAAM,0BAA0B,UAAa,CAAC,iBAAiB,MAAM,qBAAqB,EAAG,QAAO;AACxG,SAAOC,cAAa,MAAM,MAAM,KAAK,kBAAkB,MAAM,IAAI,KAC1D,kBAAkB,MAAM,UAAU,KAAK,kBAAkB,MAAM,mBAAmB;AAC7F;AAEO,SAAS,wBAAwB,OAA0C;AAC9E,SAAO,oBAAoB,KAAK,IAAI,QAAQ;AAChD;AAEA,SAAS,0BAA0B,OAAkD;AACjF,SAAO,SAAS,KAAK,KAAKD,aAAY,OAAO,CAAC,MAAM,UAAU,cAAc,CAAC,KACtE,OAAO,MAAM,OAAO,YAAY,OAAO,MAAM,WAAW,aACvD,MAAM,iBAAiB,UAAa,OAAO,MAAM,iBAAiB;AAC9E;AAEA,SAAS,qBAAqB,OAA6C;AACvE,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,WAAW,UAAU,sBAAsB,iBAAiB,CAAC,EAAG,QAAO;AACpH,MAAI,CAAC,MAAM,QAAQ,MAAM,OAAO,KAAK,CAAC,MAAM,QAAQ,MAAM,gBAAgB,EAAG,QAAO;AACpF,MAAI,MAAM,WAAW,WAAc,CAAC,SAAS,MAAM,MAAM,KAAK,CAAC,OAAO,OAAO,MAAM,MAAM,EAAE,MAAM,gBAAgB,GAAI,QAAO;AAC5H,MAAI,MAAM,uBAAuB,UAAa,CAAC,iBAAiB,MAAM,kBAAkB,EAAG,QAAO;AAClG,MAAI,MAAM,oBAAoB,WAAc,CAAC,MAAM,QAAQ,MAAM,eAAe,KAAK,CAAC,MAAM,gBAAgB,MAAM,yBAAyB,GAAI,QAAO;AACtJ,SAAO;AACX;AAEO,SAAS,yBAAyB,OAA2C;AAChF,SAAO,qBAAqB,KAAK,IAAI,QAAQ;AACjD;AAqBA,SAAS,sBAAsB,OAA8C;AACzE,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,KAAK,UAAU,WAAW,SAAS,CAAC,KAC3E,MAAM,MAAM,6BAA6B,qBAAqB,MAAM,MAAM,KAC1E,OAAO,MAAM,YAAY,YACzB,iBAAiB,MAAM,OAAO;AACzC;AAEO,SAAS,0BAA0B,OAA4C;AAClF,SAAO,sBAAsB,KAAK,IAAI,QAAQ;AAClD;AAEA,SAAS,uBAAuB,OAA+C;AAC3E,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,OAAO,CAAC,KAAK,iBAAiB,MAAM,KAAK;AAC3F;AAEO,SAAS,2BAA2B,OAA6C;AACpF,SAAO,uBAAuB,KAAK,IAAI,QAAQ;AACnD;AAuBA,SAAS,2BAA2B,OAAmD;AACnF,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,KAAK,UAAU,OAAO,CAAC,KAC9D,MAAM,MAAM,6BAA6B,qBAAqB,MAAM,MAAM,KAC1E,cAAc,MAAM,KAAK;AACpC;AAEO,SAAS,+BAA+B,OAAiD;AAC5F,SAAO,2BAA2B,KAAK,IAAI,QAAQ;AACvD;AAEA,SAAS,4BAA4B,OAAoD;AACrF,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,MAAI,MAAM,OAAO,MAAM;AACnB,WAAOA,aAAY,OAAO,CAAC,MAAM,OAAO,CAAC,KAAK,MAAM,QAAQ,MAAM,KAAK,KAAK,MAAM,MAAM,MAAM,gBAAgB;AAAA,EAClH;AACA,MAAI,MAAM,OAAO,OAAO;AACpB,WAAOA,aAAY,OAAO,CAAC,MAAM,eAAe,WAAW,OAAO,CAAC,KAAK,OAAO,MAAM,YAAY,YAC1F,iBAAiB,MAAM,WAAW,KAAK,iBAAiB,MAAM,KAAK;AAAA,EAC9E;AACA,SAAO;AACX;AAEO,SAAS,gCAAgC,OAAkD;AAC9F,SAAO,4BAA4B,KAAK,IAAI,QAAQ;AACxD;AAmBA,SAAS,qBAAqB,OAA6C;AACvE,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,KAAK,UAAU,UAAU,QAAQ,CAAC,KACzE,MAAM,MAAM,6BAA6B,qBAAqB,MAAM,MAAM,KAAK,qBAAqB,MAAM,MAAM,KAChH,iBAAiB,MAAM,MAAM;AACxC;AAEO,SAAS,yBAAyB,OAA2C;AAChF,SAAO,qBAAqB,KAAK,IAAI,QAAQ;AACjD;AAEA,SAAS,sBAAsB,OAA8C;AACzE,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,QAAQ,QAAQ,CAAC,MACvD,MAAM,SAAS,QAAQ,iBAAiB,MAAM,IAAI,OAClD,MAAM,WAAW,QAAQ,iBAAiB,MAAM,MAAM;AAClE;AAEO,SAAS,0BAA0B,OAA4C;AAClF,SAAO,sBAAsB,KAAK,IAAI,QAAQ;AAClD;AAgBA,SAAS,sBAAsB,OAA8C;AACzE,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,KAAK,UAAU,UAAU,SAAS,CAAC,KAC1E,MAAM,MAAM,6BAA6B,qBAAqB,MAAM,MAAM,KAAK,qBAAqB,MAAM,MAAM,KAChH,iBAAiB,MAAM,OAAO;AACzC;AAEO,SAAS,0BAA0B,OAA4C;AAClF,SAAO,sBAAsB,KAAK,IAAI,QAAQ;AAClD;AAEA,SAAS,uBAAuB,OAA+C;AAC3E,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,MAAM,CAAC,MAAM,MAAM,SAAS,QAAQ,iBAAiB,MAAM,IAAI;AACjH;AAEO,SAAS,2BAA2B,OAA6C;AACpF,SAAO,uBAAuB,KAAK,IAAI,QAAQ;AACnD;AAuBA,SAAS,8BAA8B,OAAsD;AACzF,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,KAAK,UAAU,UAAU,WAAW,MAAM,CAAC,KAClF,MAAM,MAAM,6BAA6B,qBAAqB,MAAM,MAAM,KAAK,qBAAqB,MAAM,MAAM,KAChH,OAAO,MAAM,YAAY,YAAY,iBAAiB,MAAM,IAAI;AAC3E;AAEO,SAAS,kCAAkC,OAAoD;AAClG,SAAO,8BAA8B,KAAK,IAAI,QAAQ;AAC1D;AAEA,SAAS,+BAA+B,OAAuD;AAC3F,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,cAAc,CAAC,KACtD,OAAO,MAAM,iBAAiB;AACzC;AAEO,SAAS,mCAAmC,OAAqD;AACpG,SAAO,+BAA+B,KAAK,IAAI,QAAQ;AAC3D;AA+CA,SAAS,yBAAyB,OAAiD;AAC/E,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,KAAK,UAAU,SAAS,SAAS,cAAc,yBAAyB,WAAW,iBAAiB,kBAAkB,4BAA4B,MAAM,CAAC,EAAG,QAAO;AAChN,MAAI,MAAM,MAAM,6BAA6B,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AACzF,MAAI,MAAM,UAAU,UAAa,CAAC,cAAc,MAAM,KAAK,EAAG,QAAO;AACrE,MAAI,MAAM,UAAU,UAAa,CAAC,cAAc,MAAM,KAAK,EAAG,QAAO;AACrE,MAAI,MAAM,eAAe,UAAa,CAAC,iBAAiB,MAAM,UAAU,EAAG,QAAO;AAClF,SAAO,kBAAkB,MAAM,qBAAqB,KAAK,kBAAkB,MAAM,OAAO,KAAK,kBAAkB,MAAM,aAAa,KAC3H,kBAAkB,MAAM,cAAc,KAAK,kBAAkB,MAAM,wBAAwB,KAAK,iBAAiB,MAAM,IAAI;AACtI;AAEO,SAAS,6BAA6B,OAA+C;AACxF,SAAO,yBAAyB,KAAK,IAAI,QAAQ;AACrD;AAEA,SAAS,0BAA0B,OAAkD;AACjF,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,cAAc,WAAW,oBAAoB,WAAW,mBAAmB,CAAC,EAAG,QAAO;AACnI,MAAI,MAAM,YAAY,UAAa,CAAC,cAAc,MAAM,OAAO,EAAG,QAAO;AACzE,MAAI,MAAM,qBAAqB,UAAa,CAAC,cAAc,MAAM,gBAAgB,EAAG,QAAO;AAC3F,SAAO,iBAAiB,MAAM,UAAU,KAAK,iBAAiB,MAAM,OAAO,KAAK,iBAAiB,MAAM,iBAAiB;AAC5H;AAEO,SAAS,8BAA8B,OAAgD;AAC1F,SAAO,0BAA0B,KAAK,IAAI,QAAQ;AACtD;AA2BA,SAAS,8BAA8B,OAAsD;AACzF,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,KAAK,UAAU,UAAU,aAAa,cAAc,SAAS,CAAC,EAAG,QAAO;AACrH,MAAI,MAAM,MAAM,6BAA6B,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AACzF,MAAI,CAACC,cAAa,MAAM,MAAM,KAAK,CAACA,cAAa,MAAM,SAAS,EAAG,QAAO;AAC1E,MAAI,MAAM,eAAe,UAAa,CAAC,iBAAiB,MAAM,UAAU,EAAG,QAAO;AAClF,MAAI,MAAM,YAAY,QAAW;AAC7B,QAAI,CAAC,MAAM,QAAQ,MAAM,OAAO,KAAK,MAAM,QAAQ,WAAW,KAAK,CAAC,MAAM,QAAQ,MAAM,oBAAoB,EAAG,QAAO;AACtH,WAAO,MAAM,WAAW,UAAa,MAAM,cAAc;AAAA,EAC7D;AACA,SAAO,MAAM,WAAW,UAAa,MAAM,cAAc;AAC7D;AAEO,SAAS,kCAAkC,OAAoD;AAClG,SAAO,8BAA8B,KAAK,IAAI,QAAQ;AAC1D;AAEA,SAAS,sBAAsB,OAAyB;AACpD,SAAO,SAAS,KAAK,KAAK,OAAO,MAAM,4BAA4B;AACvE;AAEA,SAAS,+BAA+B,OAAuD;AAC3F,MAAI,CAAC,SAAS,KAAK,KAAK,CAACD,aAAY,OAAO,CAAC,WAAW,UAAU,CAAC,EAAG,QAAO;AAC7E,MAAI,MAAM,YAAY,UAAa,MAAM,aAAa,OAAW,QAAO;AACxE,MAAI,MAAM,YAAY,UAAa,CAAC,sBAAsB,MAAM,OAAO,EAAG,QAAO;AACjF,MAAI,MAAM,aAAa,WAAc,CAAC,SAAS,MAAM,QAAQ,KAAK,CAAC,OAAO,OAAO,MAAM,QAAQ,EAAE,MAAM,qBAAqB,GAAI,QAAO;AACvI,SAAO;AACX;AAEO,SAAS,mCAAmC,OAAqD;AACpG,SAAO,+BAA+B,KAAK,IAAI,QAAQ;AAC3D;;;AC1bA,SAAS,wBAAwB,OAAgD;AAC7E,MAAI,CAAC,SAAS,KAAK,KAAK,CAACE,aAAY,OAAO,CAAC,KAAK,UAAU,WAAW,aAAa,QAAQ,UAAU,YAAY,CAAC,EAAG,QAAO;AAC7H,MAAI,MAAM,MAAM,6BAA6B,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AACzF,MAAI,MAAM,YAAY,QAAW;AAC7B,QAAI,CAAC,MAAM,QAAQ,MAAM,OAAO,KAAK,MAAM,QAAQ,WAAW,KAAK,CAAC,MAAM,QAAQ,MAAM,oBAAoB,EAAG,QAAO;AAAA,EAC1H;AACA,MAAI,MAAM,cAAc,UAAa,CAAC,qBAAqB,MAAM,SAAS,EAAG,QAAO;AACpF,MAAI,MAAM,SAAS,UAAa,CAAC,iBAAiB,MAAM,IAAI,EAAG,QAAO;AACtE,MAAI,MAAM,eAAe,QAAW;AAChC,QAAI,CAAC,MAAM,QAAQ,MAAM,UAAU,KAAK,MAAM,WAAW,WAAW,KAAK,CAAC,MAAM,WAAW,MAAM,oBAAoB,EAAG,QAAO;AAC/H,QAAI,MAAM,YAAY,UAAa,MAAM,cAAc,OAAW,QAAO;AAAA,EAC7E;AACA,MAAI,MAAM,WAAW,QAAQ,MAAM,cAAc,OAAW,QAAO;AACnE,SAAO,kBAAkB,MAAM,MAAM;AACzC;AAEO,SAAS,4BAA4B,OAA8C;AACtF,SAAO,wBAAwB,KAAK,IAAI,QAAQ;AACpD;AAEA,SAAS,yBAAyB,OAAiD;AAC/E,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,SAAS,WAAW,UAAU,CAAC,KAAK,cAAc,MAAM,KAAK,KAAK,iBAAiB,MAAM,OAAO,MACtI,MAAM,aAAa,UAAc,SAAS,MAAM,QAAQ,KAAK,OAAO,OAAO,MAAM,QAAQ,EAAE,MAAM,QAAQ;AACrH;AAEO,SAAS,6BAA6B,OAA+C;AACxF,SAAO,yBAAyB,KAAK,IAAI,QAAQ;AACrD;AAgCA,SAAS,0BAA0B,OAAkD;AACjF,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,KAAK,UAAU,WAAW,mBAAmB,QAAQ,CAAC,EAAG,QAAO;AAC7G,MAAI,MAAM,MAAM,6BAA6B,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AACzF,MAAI,MAAM,WAAW,UAAa,OAAO,MAAM,WAAW,SAAU,QAAO;AAC3E,SAAO,kBAAkB,MAAM,OAAO,KAAK,kBAAkB,MAAM,eAAe;AACtF;AAEO,SAAS,8BAA8B,OAAgD;AAC1F,SAAO,0BAA0B,KAAK,IAAI,QAAQ;AACtD;AAEA,SAAS,2BAA2B,OAAmD;AACnF,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,QAAQ,mBAAmB,kBAAkB,YAAY,eAAe,2BAA2B,uBAAuB,oBAAoB,CAAC,EAAG,QAAO;AACtM,MAAI,MAAM,SAAS,aAAa,MAAM,SAAS,UAAW,QAAO;AACjE,MAAI,OAAO,MAAM,oBAAoB,UAAW,QAAO;AACvD,MAAI,CAAC,iBAAiB,MAAM,cAAc,KAAK,CAAC,iBAAiB,MAAM,WAAW,EAAG,QAAO;AAC5F,SAAO,cAAc,MAAM,QAAQ,KAAK,cAAc,MAAM,uBAAuB,KAC5E,cAAc,MAAM,mBAAmB,KAAK,cAAc,MAAM,kBAAkB;AAC7F;AAEO,SAAS,+BAA+B,OAAiD;AAC5F,SAAO,2BAA2B,KAAK,IAAI,QAAQ;AACvD;AAkCA,SAAS,yBAAyB,OAAiD;AAC/E,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,UAAU,SAAS,mBAAmB,gBAAgB,WAAW,CAAC,EAAG,QAAO;AACzH,MAAI,CAAC,qBAAqB,MAAM,MAAM,KAAK,CAAC,qBAAqB,MAAM,eAAe,EAAG,QAAO;AAChG,MAAI,OAAO,MAAM,UAAU,SAAU,QAAO;AAC5C,MAAI,MAAM,iBAAiB,UAAa,CAAC,qBAAqB,MAAM,YAAY,EAAG,QAAO;AAC1F,SAAO,MAAM,cAAc,UAAa,qBAAqB,MAAM,SAAS;AAChF;AAEA,SAAS,2BAA2B,OAAmD;AACnF,MAAI,CAAC,SAAS,KAAK,KAAK,CAACA,aAAY,OAAO,CAAC,KAAK,UAAU,oBAAoB,iBAAiB,SAAS,UAAU,sBAAsB,CAAC,EAAG,QAAO;AACrJ,MAAI,MAAM,MAAM,6BAA6B,CAAC,qBAAqB,MAAM,MAAM,KAAK,CAAC,qBAAqB,MAAM,gBAAgB,EAAG,QAAO;AAC1I,MAAI,MAAM,kBAAkB,UAAa,CAAC,qBAAqB,MAAM,aAAa,EAAG,QAAO;AAC5F,MAAI,MAAM,UAAU,UAAa,OAAO,MAAM,UAAU,SAAU,QAAO;AACzE,MAAI,MAAM,WAAW,UAAa,CAAC,qBAAqB,MAAM,MAAM,EAAG,QAAO;AAC9E,SAAO,MAAM,yBAAyB,UAAa,qBAAqB,MAAM,oBAAoB;AACtG;AAEO,SAAS,+BAA+B,OAAiD;AAC5F,SAAO,2BAA2B,KAAK,IAAI,QAAQ;AACvD;AAEA,SAAS,4BAA4B,OAAoD;AACrF,SAAO,SAAS,KAAK,KAAKA,aAAY,OAAO,CAAC,SAAS,CAAC,KAAK,MAAM,QAAQ,MAAM,OAAO,KAAK,MAAM,QAAQ,MAAM,wBAAwB;AAC7I;AAEO,SAAS,gCAAgC,OAAkD;AAC9F,SAAO,4BAA4B,KAAK,IAAI,QAAQ;AACxD;;;AC7GO,IAAM,uBAAuB,CAAC,mBAAmB,2BAA2B,kBAAkB;AAG9F,IAAM,qBAAqBC,WAAU,oBAAoB;AASzD,SAAS,eAAe,OAAuC;AAClE,SAAO,SAAS,KAAK,KAAKC,aAAY,OAAO,CAAC,QAAQ,QAAQ,CAAC,KAAK,mBAAmB,MAAM,IAAI,MACzF,MAAM,WAAW,UAAa,OAAO,MAAM,WAAW;AAClE;AAKO,IAAM,oBAAoB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AACJ;AAEO,IAAM,mBAAmBD,WAAU,iBAAiB;;;AClFpD,IAAM,kBAAkB;AAE/B,SAAS,QAAQ,KAAqB;AAClC,SAAO,IAAI,QAAQ,OAAO,GAAG;AACjC;AAMA,SAAS,aAAa,KAAc,UAA2E;AAC3G,MAAI,OAAO,QAAQ,UAAU;AACzB,aAAS,KAAK,EAAE,OAAO,OAAO,GAAG,GAAG,QAAQ,eAAe,CAAC;AAC5D,WAAO;AAAA,EACX;AACA,QAAM,UAAU,IAAI,KAAK;AACzB,MAAI,CAAC,SAAS;AACV,aAAS,KAAK,EAAE,OAAO,KAAK,QAAQ,QAAQ,CAAC;AAC7C,WAAO;AAAA,EACX;AACA,MAAI,QAAQ,QAAQ,OAAO;AAM3B,MAAI,MAAM,WAAW,GAAG,KAAK,eAAe,KAAK,KAAK,KAAK,MAAM,WAAW,GAAG,GAAG;AAC9E,aAAS,KAAK,EAAE,OAAO,KAAK,QAAQ,gBAAgB,CAAC;AACrD,WAAO;AAAA,EACX;AAGA,UAAQ,MAAM,QAAQ,UAAU,EAAE;AAGlC,QAAM,WAAW,MAAM,MAAM,GAAG,EAAE,OAAO,OAAO;AAChD,MAAI,SAAS,KAAK,SAAO,QAAQ,IAAI,GAAG;AACpC,aAAS,KAAK,EAAE,OAAO,KAAK,QAAQ,mBAAmB,CAAC;AACxD,WAAO;AAAA,EACX;AACA,MAAI,SAAS,WAAW,GAAG;AACvB,aAAS,KAAK,EAAE,OAAO,KAAK,QAAQ,QAAQ,CAAC;AAC7C,WAAO;AAAA,EACX;AAKA,MAAI,UAAU;AACd,MAAI,SAAS,SAAS,SAAS,CAAC,MAAM,MAAM;AACxC,cAAU;AACV,aAAS,IAAI;AACb,QAAI,SAAS,WAAW,GAAG;AAAA,IAI3B;AAAA,EACJ;AACA,MAAI,SAAS,KAAK,SAAO,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,CAAC,GAAG;AAC9D,aAAS,KAAK,EAAE,OAAO,KAAK,QAAQ,mBAAmB,CAAC;AACxD,WAAO;AAAA,EACX;AAEA,SAAO,EAAE,MAAM,SAAS,KAAK,GAAG,GAAG,QAAQ;AAC/C;AASO,SAAS,oBAAoB,OAA2C;AAC3E,QAAM,WAAqD,CAAC;AAC5D,MAAI,UAAU,UAAa,UAAU,MAAM;AACvC,WAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,GAAG,SAAS;AAAA,EAClD;AACA,MAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACvB,WAAO,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,GAAG,UAAU,CAAC,EAAE,OAAO,OAAO,KAAK,GAAG,QAAQ,eAAe,CAAC,EAAE;AAAA,EACtG;AAEA,QAAM,SAAS,oBAAI,IAA4B;AAC/C,aAAW,OAAO,OAAO;AACrB,UAAM,QAAQ,aAAa,KAAK,QAAQ;AACxC,QAAI,CAAC,MAAO;AACZ,UAAM,WAAW,OAAO,IAAI,MAAM,IAAI;AACtC,QAAI,CAAC,UAAU;AACX,aAAO,IAAI,MAAM,MAAM,KAAK;AAAA,IAChC,WAAW,MAAM,WAAW,CAAC,SAAS,SAAS;AAC3C,aAAO,IAAI,MAAM,MAAM,KAAK;AAAA,IAChC;AAAA,EAEJ;AAEA,QAAM,MAAM,CAAC,GAAG,OAAO,OAAO,CAAC;AAC/B,QAAM,OAAO,IAAI,MAAM,GAAG,eAAe;AACzC,aAAW,WAAW,IAAI,MAAM,eAAe,GAAG;AAC9C,aAAS,KAAK,EAAE,OAAO,QAAQ,MAAM,QAAQ,WAAW,CAAC;AAAA,EAC7D;AAEA,SAAO,EAAE,aAAa,EAAE,OAAO,KAAK,GAAG,SAAS;AACpD;AAGA,SAAS,cAAc,MAAsB,MAAuB;AAChE,MAAI,SAAS,KAAK,KAAM,QAAO;AAC/B,MAAI,KAAK,YAAY,SAAS,KAAK,QAAQ,KAAK,WAAW,GAAG,KAAK,IAAI,GAAG,GAAI,QAAO;AACrF,SAAO;AACX;AAGA,SAAS,eAAe,GAAmB,GAA4B;AACnE,MAAI,EAAE,SAAS,EAAE,KAAM,QAAO;AAC9B,MAAI,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,WAAW,GAAG,EAAE,IAAI,GAAG,GAAI,QAAO;AAChF,MAAI,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,WAAW,GAAG,EAAE,IAAI,GAAG,GAAI,QAAO;AAChF,SAAO;AACX;AAGO,SAAS,aAAa,GAA0B,GAAmC;AACtF,MAAI,EAAE,MAAM,WAAW,KAAK,EAAE,MAAM,WAAW,EAAG,QAAO;AACzD,aAAW,MAAM,EAAE,OAAO;AACtB,eAAW,MAAM,EAAE,OAAO;AACtB,UAAI,eAAe,IAAI,EAAE,EAAG,QAAO;AAAA,IACvC;AAAA,EACJ;AACA,SAAO;AACX;AAwBO,SAAS,uBACZ,WACA,UACmB;AACnB,MAAI,UAAU,MAAM,WAAW,EAAG,QAAO,CAAC;AAC1C,QAAM,YAAiC,CAAC;AACxC,aAAW,SAAS,UAAU;AAC1B,QAAI,MAAM,MAAM,MAAM,WAAW,EAAG;AACpC,UAAM,mBAA6B,CAAC;AACpC,eAAW,MAAM,UAAU,OAAO;AAC9B,iBAAW,MAAM,MAAM,MAAM,OAAO;AAChC,YAAI,eAAe,IAAI,EAAE,GAAG;AACxB,gBAAM,WAAW,GAAG,KAAK,UAAU,GAAG,KAAK,SAAS,GAAG,OAAO,GAAG;AACjE,cAAI,CAAC,iBAAiB,SAAS,QAAQ,EAAG,kBAAiB,KAAK,QAAQ;AAAA,QAC5E;AAAA,MACJ;AAAA,IACJ;AACA,QAAI,iBAAiB,SAAS,GAAG;AAC7B,gBAAU,KAAK,EAAE,QAAQ,MAAM,QAAQ,iBAAiB,CAAC;AAAA,IAC7D;AAAA,EACJ;AACA,SAAO;AACX;AAkBO,SAAS,6BACZ,SACA,OACkC;AAClC,QAAM,oBAA8B,CAAC;AACrC,QAAM,mBAAmB,oBAAI,IAAY;AAEzC,aAAW,OAAO,WAAW,CAAC,GAAG;AAC7B,UAAM,eAAyD,CAAC;AAChE,UAAM,QAAQ,aAAa,KAAK,YAAY;AAC5C,QAAI,CAAC,OAAO;AACR,wBAAkB,KAAK,GAAG;AAC1B;AAAA,IACJ;AACA,UAAM,UAAU,MAAM,MAAM,OAAO,UAAQ,cAAc,MAAM,MAAM,IAAI,CAAC;AAC1E,QAAI,QAAQ,WAAW,GAAG;AACtB,wBAAkB,KAAK,MAAM,IAAI;AAAA,IACrC,OAAO;AACH,iBAAW,KAAK,QAAS,kBAAiB,IAAI,EAAE,IAAI;AAAA,IACxD;AAAA,EACJ;AAEA,QAAM,qBAAqB,MAAM,MAAM,IAAI,OAAK,EAAE,IAAI,EAAE,OAAO,OAAK,CAAC,iBAAiB,IAAI,CAAC,CAAC;AAC5F,SAAO,EAAE,mBAAmB,mBAAmB;AACnD;;;ACzLA,SAAS,IAAI,OAAoC;AAC7C,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI;AACA,WAAO,KAAK,UAAU,KAAK;AAAA,EAC/B,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AAEA,SAASE,UAAS,OAAkD;AAChE,SAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AACvE;AAGA,SAAS,SAAS,KAA8B,MAAuB;AACnE,QAAM,CAAC,MAAM,IAAI,IAAI,UAAU,IAAI;AACnC,MAAI,CAAC,KAAM,QAAO,IAAI,IAAI;AAC1B,QAAM,SAAS,IAAI,IAAI;AACvB,SAAOA,UAAS,MAAM,IAAI,OAAO,IAAI,IAAI;AAC7C;AAEA,SAAS,UAAU,MAA4C;AAC3D,QAAM,MAAM,KAAK,QAAQ,GAAG;AAC5B,SAAO,MAAM,IAAI,CAAC,MAAM,MAAS,IAAI,CAAC,KAAK,MAAM,GAAG,GAAG,GAAG,KAAK,MAAM,MAAM,CAAC,CAAC;AACjF;AAMA,SAAS,iBAAiB,KAA8B,MAA6C;AACjG,QAAM,MAA+B,EAAE,GAAG,IAAI;AAC9C,aAAW,QAAQ,OAAO,KAAK,KAAK,WAAW,GAAG;AAC9C,UAAM,CAAC,MAAM,IAAI,IAAI,UAAU,IAAI;AACnC,QAAI,CAAC,MAAM;AACP,aAAO,IAAI,IAAI;AACf;AAAA,IACJ;AACA,UAAM,SAAS,IAAI,IAAI;AACvB,QAAI,CAACA,UAAS,MAAM,KAAK,EAAE,QAAQ,QAAS;AAC5C,UAAM,OAAO,EAAE,GAAG,OAAO;AACzB,WAAO,KAAK,IAAI;AAChB,QAAI,IAAI,IAAI;AAAA,EAChB;AACA,SAAO;AACX;AAEA,SAAS,YAAY,QAAwC;AACzD,MAAI,CAAC,OAAO,WAAW;AACnB,UAAM,OAAO,oBAAI,IAAoB;AACrC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,MAAM,GAAG;AACtD,YAAM,IAAI,IAAI,KAAK;AACnB,UAAI,MAAM,OAAW,MAAK,IAAI,KAAK,CAAC;AAAA,IACxC;AACA,WAAO,YAAY;AAAA,EACvB;AACA,SAAO,OAAO;AAClB;AAGO,SAAS,eAAe,KAA8B,MAAoC;AAC7F,QAAM,MAAM,oBAAI,IAAoB;AACpC,QAAM,YAAqC,CAAC;AAC5C,QAAM,SAAS,IAAI,IAAI,KAAK,UAAU,CAAC,CAAC;AACxC,QAAM,QAAQ,IAAI,IAAI,KAAK,gBAAgB,CAAC,CAAC;AAC7C,QAAM,MAAM,CAAC,MAAc,UAAmB;AAC1C,QAAI,OAAO,IAAI,IAAI,EAAG;AACtB,UAAM,IAAI,IAAI,KAAK;AACnB,QAAI,MAAM,OAAW;AACrB,QAAI,IAAI,MAAM,CAAC;AACf,cAAU,IAAI,IAAI;AAAA,EACtB;AACA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,iBAAiB,KAAK,IAAI,CAAC,GAAG;AACpE,QAAI,MAAM,IAAI,GAAG,KAAKA,UAAS,KAAK,GAAG;AACnC,iBAAW,CAAC,OAAO,UAAU,KAAK,OAAO,QAAQ,KAAK,EAAG,KAAI,GAAG,GAAG,IAAI,KAAK,IAAI,UAAU;AAC1F;AAAA,IACJ;AACA,QAAI,KAAK,KAAK;AAAA,EAClB;AACA,QAAM,cAAc,oBAAI,IAA8B;AACtD,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,WAAW,GAAG;AAC5D,UAAM,OAAO,SAAS,KAAK,IAAI;AAC/B,QAAI,CAAC,MAAM,QAAQ,IAAI,EAAG;AAC1B,UAAM,OAAO,oBAAI,IAAuB;AACxC,UAAM,QAAkB,CAAC;AACzB,eAAW,OAAO,MAAM;AACpB,UAAI,CAACA,UAAS,GAAG,EAAG;AACpB,YAAMC,MAAK,IAAI,OAAO;AACtB,UAAI,OAAOA,QAAO,YAAY,CAACA,OAAM,KAAK,IAAIA,GAAE,EAAG;AACnD,YAAM,SAAS,KAAK,YAAY,KAAK,UAAU,MAAM,GAAG,IAAI;AAC5D,WAAK,IAAIA,KAAI,EAAE,OAAO,KAAK,QAAQ,KAAK,IAAI,MAAM,KAAK,GAAG,CAAC;AAC3D,YAAM,KAAKA,GAAE;AAAA,IACjB;AACA,gBAAY,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAAA,EACzC;AACA,SAAO,EAAE,KAAK,WAAW,aAAa,UAAU,IAAI,IAAI,KAAK,oBAAoB,CAAC,CAAC,EAAE;AACzF;AAEA,SAAS,UAAU,GAAsB,GAA+B;AACpE,MAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK,EAAG,KAAI,EAAE,CAAC,MAAM,EAAE,CAAC,EAAG,QAAO;AAChE,SAAO;AACX;AAEA,SAAS,eAAe,MAAoC,MAAoC,SAA8C;AAC1I,MAAI,CAAC,KAAM,QAAO,OAAO,EAAE,QAAQ,KAAK,IAAI;AAC5C,QAAM,QAA8B,CAAC;AACrC,QAAM,WAAW,MAAM,QAAQ,oBAAI,IAAuB;AAC1D,QAAM,WAAW,MAAM,QAAQ,oBAAI,IAAuB;AAC1D,aAAW,CAACA,KAAI,OAAO,KAAK,UAAU;AAClC,UAAM,UAAU,SAAS,IAAIA,GAAE;AAC/B,QAAI,CAAC,SAAS;AACV;AAAC,OAAC,MAAM,WAAW,CAAC,GAAG,KAAK,QAAQ,KAAK;AACzC;AAAA,IACJ;AACA,QAAI,QAAQ,QAAQ,QAAQ,IAAK;AACjC,UAAM,WAAW,YAAY,OAAO;AACpC,UAAM,WAAW,YAAY,OAAO;AACpC,UAAM,SAAc,EAAE,CAAC,OAAO,GAAGA,IAAG;AACpC,QAAI,UAAU;AACd,eAAW,CAAC,KAAK,CAAC,KAAK,UAAU;AAC7B,UAAI,QAAQ,WAAW,SAAS,IAAI,GAAG,MAAM,EAAG;AAChD,aAAO,GAAG,IAAI,QAAQ,MAAM,GAAG;AAC/B,gBAAU;AAAA,IACd;AAEA,QAAI,SAAS;AACT,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,KAAK,GAAG;AACtD,YAAI,OAAO,QAAQ,UAAU,OAAO,OAAQ;AAC5C,YAAI,IAAI,QAAQ,MAAM,GAAG,CAAC,MAAM,IAAI,KAAK,EAAG,QAAO,GAAG,IAAI;AAAA,MAC9D;AAAA,IACJ;AACA,UAAM,OAAiB,CAAC;AACxB,eAAW,OAAO,SAAS,KAAK,EAAG,KAAI,CAAC,SAAS,IAAI,GAAG,KAAK,EAAE,OAAO,QAAQ,OAAQ,MAAK,KAAK,GAAG;AACnG,QAAI,QAAS,EAAC,MAAM,WAAW,CAAC,GAAG,KAAK,MAAM;AAC9C,QAAI,KAAK,SAAS,EAAG,EAAC,MAAM,gBAAgB,CAAC,GAAGA,GAAE,IAAI;AAAA,EAC1D;AACA,aAAWA,OAAM,SAAS,KAAK,GAAG;AAC9B,QAAI,CAAC,SAAS,IAAIA,GAAE,EAAG,EAAC,MAAM,YAAY,CAAC,GAAG,KAAKA,GAAE;AAAA,EACzD;AACA,MAAI,CAAC,UAAU,MAAM,SAAS,CAAC,GAAG,MAAM,SAAS,CAAC,CAAC,EAAG,OAAM,QAAQ,CAAC,GAAI,MAAM,SAAS,CAAC,CAAE;AAC3F,SAAO,OAAO,KAAK,KAAK,EAAE,SAAS,IAAI,QAAQ;AACnD;AAMO,SAAS,aAAa,MAAsB,MAAsB,MAA0C;AAC/G,QAAM,QAAuB,CAAC;AAC9B,MAAI,aAAa;AACjB,MAAI;AACJ,MAAI;AACJ,QAAM,QAAQ,KAAK,gBAAgB,CAAC;AACpC,QAAM,WAAW,CAAC,SAA0C;AACxD,eAAW,UAAU,OAAO;AACxB,UAAI,KAAK,WAAW,GAAG,MAAM,GAAG,EAAG,QAAO,CAAC,QAAQ,KAAK,MAAM,OAAO,SAAS,CAAC,CAAC;AAAA,IACpF;AACA,WAAO;AAAA,EACX;AACA,QAAM,UAAiD,CAAC;AACxD,aAAW,CAAC,MAAM,CAAC,KAAK,KAAK,KAAK;AAC9B,QAAI,KAAK,IAAI,IAAI,IAAI,MAAM,EAAG;AAC9B,UAAM,WAAW,SAAS,IAAI;AAC9B,QAAI,SAAU,GAAE,QAAQ,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI;AAAA,QACtF,EAAC,QAAQ,CAAC,GAAG,IAAI,IAAI,KAAK,UAAU,IAAI;AAC7C,QAAI,CAAC,KAAK,SAAS,IAAI,IAAI,EAAG,cAAa;AAAA,EAC/C;AACA,aAAW,QAAQ,KAAK,IAAI,KAAK,GAAG;AAChC,QAAI,KAAK,IAAI,IAAI,IAAI,EAAG;AACxB,UAAM,WAAW,SAAS,IAAI;AAC9B,QAAI,SAAU,GAAE,QAAQ,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,UAAU,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC;AAAA,QACtE,EAAC,UAAU,CAAC,GAAG,KAAK,IAAI;AAC7B,QAAI,CAAC,KAAK,SAAS,IAAI,IAAI,EAAG,cAAa;AAAA,EAC/C;AACA,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,WAAW,GAAG;AAC5D,UAAM,SAAS,eAAe,KAAK,YAAY,IAAI,IAAI,GAAG,KAAK,YAAY,IAAI,IAAI,GAAG,OAAO;AAC7F,QAAI,CAAC,OAAQ;AACZ,KAAC,MAAM,gBAAgB,CAAC,GAAG,IAAI,IAAI;AACpC,iBAAa;AAAA,EACjB;AACA,MAAI,CAAC,WAAY,QAAO;AACxB,MAAI,IAAK,OAAM,MAAM;AACrB,MAAI,MAAO,OAAM,QAAQ;AACzB,MAAI,OAAO,KAAK,OAAO,EAAE,SAAS,EAAG,OAAM,UAAU;AACrD,SAAO;AACX;AAEA,SAAS,eAAe,MAAe,QAA8B,SAAwB;AACzF,QAAM,OAAO,oBAAI,IAAiB;AAClC,QAAM,YAAsB,CAAC;AAC7B,aAAW,OAAO,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,GAAG;AAC/C,QAAI,CAACD,UAAS,GAAG,KAAK,OAAO,IAAI,OAAO,MAAM,SAAU;AACxD,SAAK,IAAI,IAAI,OAAO,GAAa,GAAG;AACpC,cAAU,KAAK,IAAI,OAAO,CAAW;AAAA,EACzC;AACA,aAAWC,OAAM,OAAO,WAAW,CAAC,EAAG,MAAK,OAAOA,GAAE;AACrD,aAAW,OAAO,OAAO,UAAU,CAAC,GAAG;AACnC,UAAMA,MAAK,IAAI,OAAO;AACtB,QAAI,OAAOA,QAAO,SAAU;AAC5B,UAAM,OAAO,KAAK,IAAIA,GAAE;AACxB,SAAK,IAAIA,KAAI,OAAO,EAAE,GAAG,MAAM,GAAG,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC;AAAA,EACxD;AACA,aAAW,CAACA,KAAI,IAAI,KAAK,OAAO,QAAQ,OAAO,eAAe,CAAC,CAAC,GAAG;AAC/D,UAAM,OAAO,KAAK,IAAIA,GAAE;AACxB,QAAI,CAAC,KAAM;AACX,UAAM,UAAU,EAAE,GAAG,KAAK;AAC1B,eAAW,OAAO,KAAM,QAAO,QAAQ,GAAG;AAC1C,SAAK,IAAIA,KAAI,OAAO;AAAA,EACxB;AACA,QAAM,QAAQ,OAAO,SAAS;AAC9B,QAAM,MAAa,CAAC;AACpB,QAAM,SAAS,oBAAI,IAAY;AAC/B,aAAWA,OAAM,OAAO;AACpB,UAAM,MAAM,KAAK,IAAIA,GAAE;AACvB,QAAI,CAAC,OAAO,OAAO,IAAIA,GAAE,EAAG;AAC5B,QAAI,KAAK,GAAG;AACZ,WAAO,IAAIA,GAAE;AAAA,EACjB;AACA,aAAW,CAACA,KAAI,GAAG,KAAK,KAAM,KAAI,CAAC,OAAO,IAAIA,GAAE,EAAG,KAAI,KAAK,GAAG;AAC/D,SAAO;AACX;AAGO,SAAS,aAAgD,MAAS,OAAsB,MAAuB;AAGlH,QAAM,kBAAkB,oBAAI,IAAqB;AACjD,aAAW,QAAQ,OAAO,KAAK,KAAK,WAAW,EAAG,iBAAgB,IAAI,MAAM,SAAS,MAAM,IAAI,CAAC;AAChG,QAAM,OAAgC,iBAAiB,MAAM,IAAI;AACjE,aAAW,OAAO,MAAM,SAAS,CAAC,EAAG,QAAO,KAAK,GAAG;AACpD,SAAO,OAAO,MAAM,MAAM,OAAO,CAAC,CAAC;AACnC,aAAW,CAAC,QAAQ,MAAM,KAAK,OAAO,QAAQ,MAAM,WAAW,CAAC,CAAC,GAAG;AAChE,UAAM,SAAkCD,UAAS,KAAK,MAAM,CAAC,IAAI,EAAE,GAAI,KAAK,MAAM,EAA8B,IAAI,CAAC;AACrH,eAAW,OAAO,OAAO,SAAS,CAAC,EAAG,QAAO,OAAO,GAAG;AACvD,WAAO,OAAO,QAAQ,OAAO,OAAO,CAAC,CAAC;AACtC,SAAK,MAAM,IAAI;AAAA,EACnB;AACA,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,QAAQ,KAAK,WAAW,GAAG;AAC5D,UAAM,SAAS,MAAM,cAAc,IAAI;AACvC,UAAM,WAAW,gBAAgB,IAAI,IAAI;AACzC,QAAI,QAAQ,QAAQ;AAChB,YAAM,CAACE,OAAMC,KAAI,IAAI,UAAU,IAAI;AACnC,UAAI,CAACA,MAAM,QAAO,KAAKD,KAAI;AAC3B;AAAA,IACJ;AACA,QAAI,CAAC,UAAU,aAAa,OAAW;AACvC,UAAM,OAAO,SAAS,eAAe,UAAU,QAAQ,OAAO,IAAI;AAClE,UAAM,CAAC,MAAM,IAAI,IAAI,UAAU,IAAI;AACnC,QAAI,CAAC,MAAM;AACP,WAAK,IAAI,IAAI;AACb;AAAA,IACJ;AACA,UAAM,SAASF,UAAS,KAAK,IAAI,CAAC,IAAI,EAAE,GAAI,KAAK,IAAI,EAA8B,IAAI,CAAC;AACxF,WAAO,IAAI,IAAI;AACf,SAAK,IAAI,IAAI;AAAA,EACjB;AACA,SAAO;AACX;AASO,IAAM,2BAAyC;AAAA,EAClD,aAAa,EAAE,mBAAmB,KAAK;AAAA,EACvC,cAAc,CAAC,QAAQ;AAAA,EACvB,QAAQ,CAAC,YAAY,kBAAkB;AAAA,EACvC,WAAW,CAAC,aAAa,QAAQ;AAC7B,QAAI,EAAE,iBAAiB,KAAM,QAAO;AACpC,UAAM,EAAE,aAAa,QAAQ,GAAG,OAAO,IAAI;AAC3C,WAAO;AAAA,EACX;AACJ;AAQO,IAAM,uBAAqC;AAAA,EAC9C,aAAa,EAAE,OAAO,UAAU,eAAe,MAAM,UAAU,KAAK;AAAA,EACpE,kBAAkB;AAAA,IACd;AAAA,IAAe;AAAA,IACf;AAAA,IAA4B;AAAA,IAA0B;AAAA,IAA4B;AAAA,EACtF;AAAA,EACA,WAAW,CAAC,YAAY,QAAS,eAAe,UAAU,kBAAkB,GAAG,IAAI;AACvF;AAEA,SAAS,QAAQ,OAAgB,MAAkC;AAC/D,MAAI,CAACA,UAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,MAAM,EAAE,GAAG,MAAM;AACvB,aAAW,OAAO,KAAM,QAAO,IAAI,GAAG;AACtC,SAAO;AACX;AASA,SAAS,kBAAkB,KAAuD;AAC9E,QAAM,MAA+B,EAAE,GAAG,IAAI;AAC9C,SAAO,IAAI;AACX,SAAO,IAAI;AACX,SAAO,IAAI;AACX,SAAO,IAAI;AACX,MAAI,mBAAmB,IAAK,KAAI,gBAAgB,QAAQ,IAAI,eAAe,CAAC,SAAS,eAAe,WAAW,CAAC;AAChH,MAAI,gBAAgB,IAAK,KAAI,aAAa,QAAQ,IAAI,YAAY,CAAC,mBAAmB,CAAC;AACvF,MAAI,SAAS,KAAK;AACd,UAAM,MAAM,QAAQ,IAAI,KAAK,CAAC,eAAe,CAAC;AAE9C,QAAIA,UAAS,GAAG,KAAK,MAAM,QAAQ,IAAI,UAAU,KAAK,IAAI,WAAW,WAAW,EAAG,QAAO,IAAI;AAC9F,QAAI,MAAM;AAAA,EACd;AACA,MAAI,eAAe,IAAK,KAAI,YAAY,QAAQ,IAAI,WAAW,CAAC,YAAY,CAAC;AAC7E,QAAM,cAAc,IAAI;AACxB,MAAIA,UAAS,WAAW,MAAM,YAAY,WAAW,UAAU,YAAY,WAAW,UAAU;AAC5F,QAAI,iBAAiB,QAAQ,aAAa,CAAC,YAAY,CAAC;AAAA,EAC5D;AACA,SAAO;AACX;","names":["id","makeGuard","isRecord","isFiniteNumber","isFiniteNumber","isOptionalId","hasOnlyKeys","makeGuard","makeGuard","hasOnlyKeys","isOptionalId","isFiniteNumber","makeGuard","hasOnlyKeys","isOptionalId","hasOnlyKeys","isOptionalId","hasOnlyKeys","makeGuard","hasOnlyKeys","isRecord","id","head","tail"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/json.ts","../src/git-normalize.ts","../src/session-normalize.ts","../src/node-normalize.ts","../src/node-facts.ts","../src/workspace-normalize.ts","../src/daemon-normalize.ts","../src/git-summarize.ts","../src/git-diff.ts","../src/brain-routing.ts","../src/slot-proposal.ts","../src/interpolation.ts","../src/mesh-tool-names.ts","../src/mesh-status-probe.ts","../src/rpc-chunking.ts","../src/semver-compare.ts","../src/protocol/envelope.ts","../src/protocol/daemon-server.ts","../src/protocol/dashboard-server.ts","../src/protocol/dashboard-daemon-p2p.ts","../src/protocol/dashboard-wire-version.ts","../src/ws-protocol.ts","../src/interactive-prompt-constants.ts","../src/session-status.ts","../src/mesh-vocabulary.ts","../src/outbound-message.ts","../src/mission-brief.ts","../src/worker-protocol.ts","../src/assistant-protocol.ts","../src/turn-evidence.ts","../src/session-launch.ts","../src/turn-ipc-guards.ts","../src/turn-ipc-turn.ts","../src/turn-ipc-mission.ts","../src/turn-ipc-queue.ts","../src/turn-ipc-stats.ts","../src/turn-ipc.ts","../src/path-ownership.ts","../src/keyed-doc-delta.ts"],"sourcesContent":["/**\n * @adhdev/mesh-shared — pure, dependency-free mesh/git status normalizers shared\n * by daemon-core (standalone / local IPC) and web-core (cloud / P2P transit).\n *\n * This package exists to kill a recurring bug class: the cloud and standalone\n * transports each used to carry their own hand-synced copy of these normalizers,\n * and they drifted (cloud would strip/reshape fields, the web filter would drop\n * entries the standalone path kept). Both cores now import this single source of\n * truth. It MUST stay a pure leaf — types + pure functions on plain JS objects,\n * no Node/DOM APIs, no git exec, no transport, and an empty dependency set.\n */\n\nexport * from './json'\nexport * from './types'\nexport * from './git-normalize'\nexport * from './session-normalize'\nexport * from './node-normalize'\nexport * from './node-facts'\nexport * from './workspace-normalize'\nexport * from './daemon-normalize'\nexport * from './git-summarize'\nexport * from './git-diff'\nexport * from './brain-routing'\nexport * from './slot-proposal'\nexport * from './interpolation'\nexport * from './mesh-tool-names'\nexport * from './mesh-status-probe'\nexport * from './rpc-chunking'\nexport * from './semver-compare'\nexport * from './ws-protocol'\nexport * from './interactive-prompt-constants'\nexport * from './session-status'\nexport * from './mesh-vocabulary'\nexport * from './outbound-message'\nexport * from './worker-protocol'\nexport * from './assistant-protocol'\nexport * from './protocol'\nexport * from './turn-evidence'\nexport * from './session-launch'\nexport * from './turn-ipc'\nexport * from './path-ownership'\nexport * from './mission-brief'\nexport * from './keyed-doc-delta'\n","/**\n * Pure JSON-record reading primitives shared by the cloud (web-core / P2P transit)\n * and standalone (daemon-core / local IPC) mesh normalizers.\n *\n * These operate only on plain JS values — no Node/DOM APIs, no transport, no git\n * exec — so both cores can import them without violating the core↔core dependency\n * ban. They are the single source of truth for the field-coercion rules that the\n * two transports previously hand-synced (and drifted on).\n */\n\nexport type JsonRecord = Record<string, unknown>\n\nexport function readRecord(value: unknown): JsonRecord {\n return value && typeof value === 'object' && !Array.isArray(value) ? value as JsonRecord : {}\n}\n\n/** A plain-object record, or undefined — for callers that must tell \"absent\" from \"empty\". */\nexport function readOptionalRecord(value: unknown): JsonRecord | undefined {\n return value && typeof value === 'object' && !Array.isArray(value) ? value as JsonRecord : undefined\n}\n\nexport function readString(...values: unknown[]): string | undefined {\n for (const value of values) {\n if (typeof value !== 'string') continue\n const trimmed = value.trim()\n if (trimmed) return trimmed\n }\n return undefined\n}\n\n/** The first non-blank trimmed string, or '' — readString for callers that want a plain string. */\nexport function readText(...values: unknown[]): string {\n return readString(...values) ?? ''\n}\n\nexport function readNumber(...values: unknown[]): number | undefined {\n for (const value of values) {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n }\n return undefined\n}\n\nexport function readBoolean(...values: unknown[]): boolean | undefined {\n for (const value of values) {\n if (typeof value === 'boolean') return value\n }\n return undefined\n}\n\nexport function readStringArray(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((entry): entry is string => typeof entry === 'string' && entry.trim().length > 0)\n : []\n}\n\n/**\n * Coerce a value that is either an already-parsed plain object or a JSON string\n * into a plain object record. Arrays, primitives, parse failures and empty\n * strings all collapse to {} — callers treat the result as a best-effort record.\n *\n * This is the single source of truth for the `parseJsonRecord`/`parseJsonObject`\n * coercion that cloud mesh normalizers previously hand-redefined per file.\n */\nexport function parseJsonRecord(value: unknown): JsonRecord {\n if (!value) return {}\n if (typeof value === 'object') return readRecord(value)\n if (typeof value !== 'string') return {}\n const trimmed = value.trim()\n if (!trimmed) return {}\n try {\n return readRecord(JSON.parse(trimmed))\n } catch {\n return {}\n }\n}\n\n/**\n * Join a (possibly absent) repo root with a relative submodule path. Returns the\n * path unchanged when it is already absolute, and undefined when nothing usable\n * can be derived — callers must treat the result as optional.\n */\nexport function joinRepoPath(root: string | undefined, relativePath: string | undefined): string | undefined {\n const normalizedRoot = typeof root === 'string' ? root.trim().replace(/[\\\\/]+$/, '') : ''\n const normalizedPath = typeof relativePath === 'string' ? relativePath.trim() : ''\n if (!normalizedPath) return undefined\n if (/^(?:[A-Za-z]:[\\\\/]|\\/)/.test(normalizedPath)) return normalizedPath\n if (!normalizedRoot) return undefined\n return `${normalizedRoot}/${normalizedPath.replace(/^[\\\\/]+/, '')}`\n}\n","/**\n * Canonical git-status normalizers shared by the cloud (web-core) and standalone\n * (daemon-core router) mesh paths. Previously each transport hand-maintained its\n * own copy and they drifted (e.g. submodule drop rules, evidence checks); this is\n * the one implementation both import.\n */\n\nimport { joinRepoPath, readBoolean, readNumber, readRecord, readString, type JsonRecord } from './json'\nimport type { DaemonBuildBehind, GitRepoStatus, GitSubmoduleStatus, GitUpstreamFreshness } from './types'\n\nexport function scoreGitUpstreamFreshness(status: GitUpstreamFreshness | undefined): number {\n switch (status) {\n case 'fresh':\n return 30\n case 'no_upstream':\n return 4\n case 'unchecked':\n case undefined:\n return 0\n case 'stale':\n return -10\n case 'unavailable':\n return -15\n default:\n return 0\n }\n}\n\nexport function readGitSubmodules(value: unknown, parentRepoRoot?: string): GitSubmoduleStatus[] | undefined {\n if (!Array.isArray(value)) return undefined\n const submodules = value\n .map(entry => {\n const submodule = readRecord(entry)\n const path = readString(submodule.path)\n const commit = readString(submodule.commit)\n const repoPath = readString(submodule.repoPath, submodule.repo_root)\n ?? joinRepoPath(parentRepoRoot, path)\n // repoPath is only used for the submodule node's display workspace, which is\n // allowed to be empty. The cloud P2P transit path can deliver submodule entries\n // without repoPath (and a per-node git object without a derivable repoRoot), so\n // dropping on missing repoPath would silently strip every submodule graph node.\n // Keep any submodule that carries both path and commit.\n if (!path || !commit) return null\n const result: GitSubmoduleStatus = {\n path,\n commit,\n dirty: readBoolean(submodule.dirty) ?? false,\n outOfSync: readBoolean(submodule.outOfSync, submodule.out_of_sync) ?? false,\n }\n const lastCheckedAt = readNumber(submodule.lastCheckedAt, submodule.last_checked_at)\n if (lastCheckedAt !== undefined) result.lastCheckedAt = lastCheckedAt\n if (repoPath) result.repoPath = repoPath\n const error = readString(submodule.error)\n if (error) result.error = error\n return result\n })\n .filter((entry): entry is GitSubmoduleStatus => entry !== null)\n return submodules.length > 0 ? submodules : undefined\n}\n\nexport function hasGitStatusEvidence(status: JsonRecord): boolean {\n // BUG FIX: a transit-reshaped git status that carries only a repoRoot/workspace\n // (e.g. cloud P2P stripped the branch/upstream/counters but kept the path) must\n // NOT be dropped — otherwise the node loses its git object and any submodules\n // hanging off it. Treat a present repoRoot/repo_root/workspace as evidence too.\n return readBoolean(status.isGitRepo) !== undefined\n || Boolean(readString(status.branch, status.upstream, status.upstreamStatus, status.upstream_status, status.headCommit))\n || Boolean(readString(status.repoRoot, status.repo_root, status.workspace))\n || readNumber(\n status.ahead,\n status.behind,\n status.staged,\n status.modified,\n status.untracked,\n status.deleted,\n status.renamed,\n status.lastCheckedAt,\n status.last_checked_at,\n ) !== undefined\n || (Array.isArray(status.submodules) && status.submodules.length > 0)\n}\n\nexport function normalizeGitStatus(\n status: JsonRecord,\n node: JsonRecord,\n options?: { lastCheckedAt?: number },\n): GitRepoStatus | undefined {\n const explicitIsGitRepo = readBoolean(status.isGitRepo)\n if (!Object.keys(status).length || !hasGitStatusEvidence(status)) return undefined\n const isGitRepo = explicitIsGitRepo ?? true\n const conflictFiles = Array.isArray(status.conflictFiles)\n ? status.conflictFiles.filter((entry): entry is string => typeof entry === 'string')\n : []\n const conflictCount = readNumber(status.conflicts) ?? conflictFiles.length\n const hasConflicts = readBoolean(status.hasConflicts) ?? conflictCount > 0\n // node.workspace is in the fallback chain so a transit node carrying its path only\n // on the node (not the inner git object) still yields a parentRepoRoot for submodules.\n const repoRoot = readString(status.repoRoot, status.repo_root, node.repoRoot, node.repo_root, status.workspace, node.workspace) || undefined\n const submodules = readGitSubmodules(status.submodules, repoRoot)\n const upstreamStatus = readString(status.upstreamStatus, status.upstream_status)\n const upstreamFetchedAt = readNumber(status.upstreamFetchedAt, status.upstream_fetched_at)\n const upstreamFetchError = readString(status.upstreamFetchError, status.upstream_fetch_error)\n const error = readString(status.error)\n const staged = readNumber(status.staged) ?? 0\n const modified = readNumber(status.modified) ?? 0\n const untracked = readNumber(status.untracked) ?? 0\n const deleted = readNumber(status.deleted) ?? 0\n const renamed = readNumber(status.renamed) ?? 0\n const lastCheckedAt = options?.lastCheckedAt ?? readNumber(status.lastCheckedAt, status.last_checked_at)\n return {\n workspace: readString(status.workspace, node.workspace) || '',\n repoRoot: repoRoot ?? null,\n isGitRepo,\n branch: readString(status.branch) ?? null,\n headCommit: readString(status.headCommit) ?? null,\n headMessage: readString(status.headMessage) ?? null,\n upstream: readString(status.upstream) ?? null,\n upstreamStatus: (upstreamStatus as GitUpstreamFreshness) ?? 'unchecked',\n ...(upstreamFetchedAt !== undefined ? { upstreamFetchedAt } : {}),\n ...(upstreamFetchError ? { upstreamFetchError } : {}),\n ahead: readNumber(status.ahead) ?? 0,\n behind: readNumber(status.behind) ?? 0,\n staged,\n modified,\n untracked,\n deleted,\n renamed,\n dirty: readBoolean(status.dirty, status.isDirty, status.is_dirty) ?? (staged + modified + untracked + deleted + renamed > 0 || hasConflicts),\n hasConflicts,\n conflictFiles,\n stashCount: readNumber(status.stashCount, status.stash_count) ?? 0,\n ...(lastCheckedAt !== undefined ? { lastCheckedAt } : {}),\n ...(submodules ? { submodules } : {}),\n // Deploy-lag visibility: daemonBuildBehind is computed by the reporting\n // daemon's git probe (build commit vs workspace/submodule HEAD). It must\n // survive relay reassembly or downstream staleDaemonBuild surfaces\n // (dashboard Status tab badge, MCP staleDaemonBuilds warning) never fire\n // for remote nodes.\n ...(status.daemonBuildBehind && typeof status.daemonBuildBehind === 'object'\n ? { daemonBuildBehind: status.daemonBuildBehind as unknown as DaemonBuildBehind }\n : {}),\n ...(error ? { error } : {}),\n }\n}\n\nexport function scoreGitStatusCandidate(git: GitRepoStatus | undefined): number {\n if (!git) return Number.NEGATIVE_INFINITY\n let score = 0\n if (git.isGitRepo === true) score += 50\n if (git.isGitRepo === false) score -= 10\n if (git.branch) score += 20\n if (git.headCommit) score += 20\n if (git.upstream) score += 10\n score += scoreGitUpstreamFreshness(git.upstreamStatus)\n if (typeof git.ahead === 'number') score += 2\n if (typeof git.behind === 'number') score += 2\n if (Array.isArray(git.submodules) && git.submodules.length > 0) score += 4 + git.submodules.length\n if (git.error) score -= 20\n return score\n}\n\n/**\n * Pick the best git status out of the four transit envelope slots a mesh node can\n * carry: lastGit.status, lastGit.result.status, lastProbe.git.status,\n * lastProbe.git.result.status. Returns undefined when none carry git evidence.\n */\nexport function pickBestTransitGitStatus(node: JsonRecord, options?: { lastCheckedAt?: number }): GitRepoStatus | undefined {\n const rawGit = readRecord(node.lastGit ?? node.last_git)\n const gitResult = readRecord(rawGit.result)\n const directStatus = readRecord(rawGit.status)\n const nestedStatus = readRecord(gitResult.status)\n const rawProbe = readRecord(node.lastProbe ?? node.last_probe)\n const probeGit = readRecord(rawProbe.git)\n const probeGitResult = readRecord(probeGit.result)\n const probeDirectStatus = readRecord(probeGit.status)\n const probeNestedStatus = readRecord(probeGitResult.status)\n let best: { git: GitRepoStatus; score: number } | null = null\n for (const status of [directStatus, nestedStatus, probeDirectStatus, probeNestedStatus]) {\n const normalized = normalizeGitStatus(status, node, options)\n if (!normalized) continue\n const score = scoreGitStatusCandidate(normalized)\n if (!best || score > best.score) best = { git: normalized, score }\n }\n return best?.git\n}\n","/**\n * Canonical mesh-session record normalizer shared by the cloud (web-core) mesh\n * paths. Parses an already-transit-shaped session record into a typed\n * RepoMeshSessionStatus.\n */\n\nimport { readBoolean, readRecord, readString } from './json'\nimport type { RepoMeshSessionStatus } from './types'\n\n/**\n * Build a deterministic synthetic session id from a record that has no explicit\n * id. Two transit refreshes of the same logical session produce the same id so\n * downstream dedupe stays stable across refreshes (a random id would create a new\n * node every poll). Derived from the stable identifying fields available on the\n * record; prefixed \"synthetic:\" so callers can tell it apart from a real id.\n */\nfunction deriveSyntheticSessionId(record: ReturnType<typeof readRecord>): string | undefined {\n const parts = [\n readString(record.workspace),\n readString(record.providerType, record.provider),\n readString(record.role),\n readString(record.state, record.status),\n readString(record.title),\n readString(record.createdAt, record.created_at),\n readString(record.startedAt, record.started_at),\n ].filter((part): part is string => Boolean(part))\n if (parts.length === 0) return undefined\n return `synthetic:${parts.join('|')}`\n}\n\n/**\n * Session-id equivalence — the sessionId counterpart of daemonIdsEquivalent /\n * meshNodeIdMatches. A session id is SINGLE-FORM: one canonical UUID minted once\n * via crypto.randomUUID() in the provider instance and carried verbatim across\n * daemons, with no node/daemon-id style serialization variants. Equivalence is\n * therefore an exact match after trimming, never matching an absent/empty id\n * against another absent/empty id. Routing every mesh comparison site through\n * this one predicate keeps that single-form policy in one place (and gives any\n * future session-id aliasing a single seam) instead of scattering raw `===`.\n */\nexport function sessionIdsEquivalent(a: string | null | undefined, b: string | null | undefined): boolean {\n const idA = readString(a)\n const idB = readString(b)\n if (!idA || !idB) return false\n return idA === idB\n}\n\nexport function normalizeMeshSessionRecord(entry: unknown): RepoMeshSessionStatus | null {\n const record = readRecord(entry)\n // BUG FIX: cloud transit can reshape/strip the explicit id field. Fall back\n // through sessionId → session_id → id, then to a DETERMINISTIC synthetic id\n // derived from record content so the session survives the round trip instead\n // of being dropped (and so dedupe stays stable across refreshes). Return null\n // ONLY when the record carries no identifying fields at all.\n const sessionId = readString(record.sessionId, record.session_id, record.id)\n ?? deriveSyntheticSessionId(record)\n if (!sessionId) return null\n return {\n sessionId,\n ...(readString(record.providerType, record.provider) ? { providerType: readString(record.providerType, record.provider) } : {}),\n ...(readString(record.state, record.status) ? { state: readString(record.state, record.status) } : {}),\n ...(readString(record.chatStatus, record.chat_status) ? { chatStatus: readString(record.chatStatus, record.chat_status) } : {}),\n ...(readString(record.lifecycle) ? { lifecycle: readString(record.lifecycle) as RepoMeshSessionStatus['lifecycle'] } : {}),\n ...(readString(record.surfaceKind, record.surface_kind) ? { surfaceKind: readString(record.surfaceKind, record.surface_kind) as RepoMeshSessionStatus['surfaceKind'] } : {}),\n ...(readString(record.recoveryState, record.recovery_state) ? { recoveryState: readString(record.recoveryState, record.recovery_state) } : {}),\n ...(readString(record.workspace) ? { workspace: readString(record.workspace) } : {}),\n ...(readString(record.title) ? { title: readString(record.title) } : {}),\n ...(readString(record.role) ? { role: readString(record.role) } : {}),\n ...(readBoolean(record.isSelfCoordinator, record.is_self_coordinator) !== undefined ? { isSelfCoordinator: readBoolean(record.isSelfCoordinator, record.is_self_coordinator) } : {}),\n ...(readString(record.statusNote, record.status_note) ? { statusNote: readString(record.statusNote, record.status_note) } : {}),\n ...(readString(record.createdAt, record.created_at) ? { createdAt: readString(record.createdAt, record.created_at) } : {}),\n ...(readString(record.startedAt, record.started_at) ? { startedAt: readString(record.startedAt, record.started_at) } : {}),\n ...(readString(record.lastActivityAt, record.last_activity_at) ? { lastActivityAt: readString(record.lastActivityAt, record.last_activity_at) } : {}),\n ...(readBoolean(record.isCached, record.is_cached) !== undefined ? { isCached: readBoolean(record.isCached, record.is_cached) } : {}),\n }\n}\n","/**\n * Canonical mesh-node identity normalizer shared by daemon-core (standalone /\n * local IPC) and web-core (cloud / P2P transit) — the node-id counterpart of\n * session-normalize.ts.\n *\n * A mesh node record can carry its stable identifier under THREE different field\n * names depending on the serialization path it travelled, all with the same\n * value:\n * - `id` — config canonical form (mesh registry / persisted config)\n * - `nodeId` — runtime/wire camelCase form (inline-cache de-serialization,\n * mesh_status output via readStringValue(node.nodeId, node.id))\n * - `node_id` — SQLite DB column form leaked onto the object\n *\n * Comparing only `node.id` (or a 2-way `id ?? nodeId` that omits `node_id`)\n * against a target id silently drops nodes that arrived in another form — e.g. an\n * inline-cached worktree node, leaving a target-routed task permanently pending\n * with a misleading `no_node_satisfies_required_tags` skip. This module is the\n * single 3-way source of truth so every comparison site absorbs all three forms.\n */\n\nimport { readString } from './json'\nimport type { MeshNodeIdentified } from './types'\n\n/**\n * Read a mesh node's stable identifier, absorbing any of the three\n * serialization forms (`id` / `nodeId` / `node_id`). Returns undefined when the\n * record carries no usable id in any form.\n */\nexport function normalizeMeshNodeId(node: MeshNodeIdentified | null | undefined): string | undefined {\n const record = (node && typeof node === 'object' ? node : {}) as MeshNodeIdentified\n return readString(record.id, record.nodeId, record.node_id)\n}\n\n/**\n * Whether a mesh node record matches the given candidate id, comparing the\n * node's normalized id (any form) against the candidate. False when either side\n * is empty — never matches an absent id against an absent candidate.\n */\nexport function meshNodeIdMatches(\n node: MeshNodeIdentified | null | undefined,\n candidateId: string | null | undefined,\n): boolean {\n if (!candidateId) return false\n const trimmed = candidateId.trim()\n if (!trimmed) return false\n return normalizeMeshNodeId(node) === trimmed\n}\n","/**\n * MeshNodeFacts — the versioned per-machine RUNTIME facts bundle a reporting\n * daemon ships wholesale (design: root repo\n * docs/design/2026-07-25-deploy-lag-visibility.md §(a)).\n *\n * The mirror-defect class (a field reaching the dashboard for self nodes but\n * not remote ones, or vice versa) came from every fact being plumbed\n * field-by-field through six reassembly layers. The bundle rule that kills the\n * class: producers build it with ONE builder (daemon-core buildLocalNodeFacts —\n * used by BOTH the reporter envelope and the self-node stamp), and every relay\n * layer passes the object through OPAQUELY — never rebuild it field-by-field.\n * schemaVersion lets future fields ride through old relays untouched.\n *\n * Slots are deliberately NOT part of the bundle: they are coordinator-owned\n * config (REMOTE-NODE-SLOTS-COORDINATOR-LOCAL), not a reported runtime fact.\n */\n\nexport interface MeshNodeFactsDaemonBuild {\n /** Full build commit baked into the running daemon (40-hex). */\n commit?: string\n commitShort?: string\n version?: string\n builtAt?: string\n}\n\n/**\n * One rolling quota window, structurally identical to daemon-core's\n * `QuotaWindow`. Redeclared here rather than imported because this package is a\n * dependency-free leaf (see the header of index.ts) and must never import\n * daemon-core — the dependency arrow points the other way. daemon-core's\n * richer type stays assignable to this one, so the producer passes its snapshot\n * straight through with no mapping layer to drift.\n */\nexport interface MeshNodeFactsQuotaWindow {\n usedPercent: number\n windowMinutes: number\n resetsAt: number | null\n}\n\n/**\n * A provider's quota snapshot as reported by the node that owns the credentials.\n *\n * `status` is the field that matters to a reader: 'ok' means the windows are\n * usable, anything else means they are not. A node that CANNOT read a quota\n * still reports an entry (status 'unavailable'/'error' + metadata.failureKind)\n * rather than omitting the provider — an absent entry means \"this node never\n * told us\", a present failing entry means \"this node looked and could not\n * tell\", and a reader that cannot distinguish those two cannot diagnose\n * anything. Extra provider-specific fields (buckets, monthly) ride through via\n * the index signature.\n */\nexport interface MeshNodeFactsProviderQuota {\n provider: string\n status: string\n session: MeshNodeFactsQuotaWindow | null\n weekly: MeshNodeFactsQuotaWindow | null\n /** 30-day billing-style window, only for providers that report one\n * (cursor-cli). Promoted from the index signature 2026-08-24 so readers\n * can render it typed — an 'ok' cursor snapshot often carries ONLY this\n * axis, and a reader that looks at session/weekly alone misreads a\n * healthy reading as a failure. */\n monthly?: MeshNodeFactsQuotaWindow | null\n /** Per-pool quota buckets, only for providers whose plan has more than one\n * pool (antigravity-cli: Gemini vs Claude/GPT groups, each with a 5h and\n * a weekly bucket). `session`/`weekly` above collapse these to the WORST\n * bucket per window (the routing-safe headline); the buckets carry the\n * per-pool detail a reader should surface. Promoted from the index\n * signature 2026-08-24, same reasoning as `monthly`. */\n buckets?: Array<{\n name?: string\n usedPercent?: number\n windowMinutes?: number\n resetsAt?: number | null\n [extra: string]: unknown\n }> | null\n /** Unix ms of the snapshot itself — older than the bundle's reportedAt. */\n updatedAt: number\n error: string | null\n /**\n * `accountEmail` is PII and rides this bundle because the bundle is\n * P2P/local only — it must never be added to a server-bound payload. See\n * daemon-core `QuotaMetadata.accountEmail` and the regression suite that\n * pins its absence from every server allow-list.\n */\n metadata?: {\n failureKind?: string\n source?: string\n planType?: string | null\n accountEmail?: string | null\n /**\n * True when `session`/`weekly` are NOT this snapshot's own reading but a\n * retained last-good reading carried forward by daemon-core's\n * `carryForwardLastGoodWindows` (quota/refresh.ts) after a TRANSIENT\n * fetch failure (expired token, network blip, rate limit). `status` on\n * this same entry is the fresh failure, not 'ok' — the numbers are real,\n * just not from THIS tick. A reader should label them (e.g. \"· refreshing\")\n * rather than presenting them as a freshly measured value.\n */\n lastGoodWindows?: boolean\n /**\n * Unix ms when the reporting node last ATTEMPTED a refresh of this\n * provider — deliberately distinct from `updatedAt`, which dates the\n * DATA. They differ for file-source providers (claude-cli reports its\n * statusline snapshot's capture time, codex-cli the rollout entry's),\n * whose `updatedAt` does not move while the source file is unchanged\n * however often it is successfully re-read.\n *\n * A reader judging FRESHNESS wants `updatedAt`. This field answers the\n * different question \"is that node still looking?\", which is what makes\n * \"3h old but re-checked a minute ago\" distinguishable from \"3h old and\n * nobody has looked since\". Absent on entries written by daemons\n * predating the field.\n */\n fetchedAt?: number\n [extra: string]: unknown\n }\n [extra: string]: unknown\n}\n\n/**\n * One provider's enablement state on the reporting machine — see\n * `MeshNodeFacts.providerEnablement`.\n *\n * Both fields are REQUIRED booleans on the wire even though the underlying\n * config defaults are asymmetric (`enabled` defaults false, `quotaEnabled`\n * defaults true). The producer resolves those defaults before stamping, so a\n * reader never re-derives them — a second copy of the default rules is exactly\n * the drift this shape avoids. Absence is expressed by omitting the whole\n * provider entry (or the whole bundle field), never by a missing sub-field.\n */\nexport interface MeshNodeFactsProviderEnablement {\n /** \"This machine uses provider X\" — gates launching and mesh claims. */\n enabled: boolean\n /** \"...and its quota is probed here\" — an independent user opt-out. */\n quotaEnabled: boolean\n}\n\nexport interface MeshNodeFacts {\n schemaVersion: number\n reportedAt: number\n daemonBuild?: MeshNodeFactsDaemonBuild\n providerVersions?: Record<string, string>\n /**\n * Verified-channel PIN per provider type: which provider MANIFEST the node\n * actually loads. NOT the same as `providerVersions`, which is the CLI\n * BINARY version — a node can run kimi-code 1.2.3 while pinned to kimi\n * spec 1.0.0. Keep them separate; folding them would repeat the\n * multi-identifier confusion behind the canon-identity defect class.\n *\n * This is what makes a remote node's pin knowable. Provider fixes do not\n * propagate on their own (the pin advances only on an explicit\n * activation, by design), so without this field a node that never adopted\n * a published fix looks exactly like one that did.\n *\n * A missing entry means \"no pin\", never a fabricated value.\n */\n providerSpecPins?: Record<string, string>\n platform?: string\n arch?: string\n machineNickname?: string\n /**\n * Per-provider quota snapshots, keyed by QuotaProvider id ('claude-cli',\n * 'codex-cli', 'cursor-cli', 'kimi'). Consumed by ROUTING as well as observation: the\n * coordinator's quota gate / spread bonus (daemon-core mesh-quota-routing.ts,\n * thresholds in RepoMeshPolicy.quotaRouting) reads exactly this shape, so\n * field renames here are a routing-contract change, not a cosmetic one.\n * Both consumers fail open on missing/stale data.\n *\n * Freshness is `Date.now() - reportedAt` (the bundle stamp) plus each\n * entry's own `updatedAt`; there is deliberately NO ttl/expiry field here,\n * because refresh cadence is owned by the reporting node and the delivery\n * cadence by whoever calls git_status. Neither end is in a position to\n * assert a TTL, so readers judge age themselves (the routing consumer's\n * rule: quotaSnapshotAgeMs in daemon-core mesh-quota-routing.ts).\n */\n quota?: Record<string, MeshNodeFactsProviderQuota>\n /**\n * Per-provider ENABLEMENT state on the reporting machine, keyed the same\n * way as `quota`. Exists because `quota` alone cannot answer \"why is there\n * no snapshot\": a provider that is disabled — on either axis — is pruned\n * from the quota cache entirely (daemon-core quota/refresh.ts drops it and\n * refuses to restore it from disk), so a deliberate opt-out and a\n * never-yet-measured provider both arrive as the SAME absent entry. On the\n * node that owns the config that ambiguity is resolvable by reading the\n * config; for every OTHER node in the mesh it was not resolvable at all,\n * which is what this field fixes.\n *\n * The two axes mirror ProviderLoader exactly and are INDEPENDENT:\n * `enabled` is \"this machine uses provider X\" (gates launching and mesh\n * claims), `quotaEnabled` gates ONLY the quota probe — a machine can use a\n * provider and still opt out of having its usage read.\n *\n * ★An ABSENT bundle field means \"this node did not tell us\" — a daemon too\n * old to send it — and must NEVER be read as \"disabled\". The consumer\n * (daemon-core mesh-quota-routing.ts classifyAbsentQuotaReason) keeps its\n * unclassified fallback for exactly that case; treating absence as\n * disabled would invent a fail-closed verdict out of a missing field.\n *\n * Booleans keyed by provider type only — no free text, no credentials.\n */\n providerEnablement?: Record<string, MeshNodeFactsProviderEnablement>\n /** Future fields ride through opaquely — do not enumerate them in relays. */\n [extra: string]: unknown\n}\n\n/**\n * Validate the minimal envelope shape and pass EVERYTHING else through\n * untouched. Returns undefined for anything that is not a v1+ bundle so\n * callers skip the stamp instead of shipping garbage.\n */\nexport function normalizeMeshNodeFacts(raw: unknown): MeshNodeFacts | undefined {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return undefined\n const record = raw as Record<string, unknown>\n const schemaVersion = Number(record.schemaVersion)\n const reportedAt = Number(record.reportedAt)\n if (!Number.isFinite(schemaVersion) || schemaVersion < 1) return undefined\n if (!Number.isFinite(reportedAt) || reportedAt <= 0) return undefined\n return { ...record, schemaVersion, reportedAt } as MeshNodeFacts\n}\n\n/**\n * Provider types with a SHIPPED quota fetcher — the providers whose quota can\n * actually be read on a node today.\n *\n * This must mirror `REFRESHERS` in daemon-core's `quota/refresh.ts`, which is\n * the runtime authority: a provider absent from REFRESHERS is never probed, so\n * offering it a quota switch anywhere would promise a control that does\n * nothing. It lives here, in the dependency-free leaf, for the same reason\n * `formatQuotaAccount` does — the machine page and the new-install surfaces are\n * in web-core, the fetchers and the `adhdev setup` wizard reach it from\n * daemon-core, and the dependency arrow only runs one way. This list previously\n * existed as a hand-copied literal in web-core's ProvidersTab; that copy is now\n * derived from this one.\n *\n * Deliberately NOT necessarily the same set as the `QuotaProvider` union in\n * daemon-core's quota/types.ts: that union is the set of valid keys a snapshot\n * can be carried under, while membership HERE means \"a fetcher exists\".\n *\n * Known non-members and why, so this is not re-litigated per surface:\n * - cursor-cli — permanently impossible; no personal usage API exists\n *\n * ★grok-cli WAS listed here as impossible and is not: that verdict came from\n * probing `api.x.ai` / `management-api.x.ai` (the team-API billing axis, which\n * genuinely rejects a CLI OAuth token) and from reading `grok --help`, where\n * the `/usage` view does not appear because it is a TUI slash command. The\n * subscription quota is served by the CLI's own chat proxy — see the endpoint\n * provenance note in daemon-core `quota/fetchers/grok.ts`.\n *\n * ★antigravity-cli was likewise twice judged impossible, from reading\n * `agy --help` where the usage view does not appear because it is a TUI view.\n * Its quota comes from the SHARED Gemini Code Assist backend\n * (`daily-cloudcode-pa.googleapis.com/v1internal:retrieveUserQuotaSummary` —\n * the host `agy` itself uses; the unprefixed `cloudcode-pa` host 429s Google\n * AI Pro Antigravity accounts), and its credential lives in the OS keyring,\n * not the stale on-disk token file — see the provenance note in daemon-core\n * `quota/fetchers/antigravity.ts`. Supported on macOS and Windows; other\n * platforms report `unsupported` rather than guess at a keyring backend\n * nobody has verified.\n *\n * ★Adding a provider here without adding its fetcher to REFRESHERS re-creates\n * exactly the \"switch that does nothing\" this constant prevents.\n */\nexport const QUOTA_SUPPORTED_PROVIDERS: readonly string[] = [\n 'antigravity-cli',\n 'claude-cli',\n 'codex-cli',\n 'cursor-cli',\n 'grok-cli',\n 'kimi',\n 'opencode',\n]\n\n/** Whether this provider's quota can be probed at all — see QUOTA_SUPPORTED_PROVIDERS. */\nexport function supportsQuota(providerType: string | undefined | null): boolean {\n return !!providerType && QUOTA_SUPPORTED_PROVIDERS.includes(providerType)\n}\n\n/**\n * The account/plan label for a provider quota row: \"you@example.com · Plus\".\n *\n * Lives HERE, in the dependency-free leaf, because both renderers need it and\n * they cannot share code any other way: the dashboards are in web-core and the\n * `adhdev quota` CLI is in daemon-core, and the dependency arrow runs\n * web-core → daemon-core, never back. Duplicating the formatter in the CLI is\n * what produced the drift this function exists to prevent — the CLI showed no\n * account at all while the UI showed one.\n *\n * Both halves are optional and independent: codex reports both, kimi reports\n * neither, and Claude Code exposes no account at all. Returns null when there\n * is nothing to say, so a provider without an account renders no empty slot and\n * no \"unknown\" placeholder — the absence is simply invisible, in every surface.\n *\n * ★The email is PII travelling on a P2P-only path. Rendering it locally is\n * fine; it must never be forwarded to a server payload or a push body. See\n * daemon-core QuotaMetadata.accountEmail and the server-boundary suite.\n */\nexport function formatQuotaAccount(quota: MeshNodeFactsProviderQuota | undefined): string | null {\n const meta = quota?.metadata\n const email = typeof meta?.accountEmail === 'string' ? meta.accountEmail.trim() : ''\n const plan = typeof meta?.planType === 'string' ? meta.planType.trim() : ''\n const parts = [email, plan].filter(Boolean)\n return parts.length > 0 ? parts.join(' · ') : null\n}\n\n/**\n * Stable built-in provider order for a DEFAULTED node priority (no operator\n * order known): these first when present, then the rest alphabetically. The\n * `mesh_init` providerPriority suggestion leads with the same list.\n */\nexport const BUILTIN_PROVIDER_PREFERENCE: readonly string[] = ['claude-cli', 'codex-cli', 'gemini-cli']\n\n/** Order provider types by BUILTIN_PROVIDER_PREFERENCE, then alphabetically (de-duplicated). */\nexport function orderProvidersByBuiltinPreference(types: readonly unknown[]): string[] {\n const unique = [...new Set(types.map((t) => (typeof t === 'string' ? t.trim() : '')).filter(Boolean))]\n const rank = (t: string) => {\n const i = BUILTIN_PROVIDER_PREFERENCE.indexOf(t)\n return i < 0 ? BUILTIN_PROVIDER_PREFERENCE.length : i\n }\n return unique.sort((a, b) => rank(a) - rank(b) || a.localeCompare(b))\n}\n\n/**\n * The provider order a node with NO providerPriority and NO capability slots\n * defaults to, from its own facts bundle: the providers it reports enabled\n * (`providerEnablement[type].enabled === true` — the reporting machine's own\n * verdict), narrowed to the CLIs it reports detected (`providerVersions`, the\n * detection pass that stamps binary versions) when any enabled one is listed\n * there. Ordered by BUILTIN_PROVIDER_PREFERENCE.\n *\n * The single rule for every reader — daemon-core auto-launch / slot resolution,\n * the MCP launch readiness + type-omitted launch, the `adhdev mesh` CLI — so a\n * node is not \"launch ready\" on one surface and `missing_provider_priority` on\n * another. Returns [] when nothing usable is reported.\n */\nexport function defaultProviderPriorityFromNodeFacts(facts: unknown): string[] {\n const f = facts && typeof facts === 'object' && !Array.isArray(facts) ? facts as Record<string, unknown> : null\n const enablement = f?.providerEnablement\n if (!enablement || typeof enablement !== 'object' || Array.isArray(enablement)) return []\n const enabled = Object.entries(enablement as Record<string, unknown>)\n .filter(([, v]) => !!v && typeof v === 'object' && (v as Record<string, unknown>).enabled === true)\n .map(([type]) => type)\n const versions = f?.providerVersions\n const detected = versions && typeof versions === 'object' && !Array.isArray(versions)\n ? enabled.filter((type) => {\n const v = (versions as Record<string, unknown>)[type]\n return typeof v === 'string' && !!v.trim()\n })\n : []\n return orderProvidersByBuiltinPreference(detected.length ? detected : enabled)\n}\n","/**\n * Canonical workspace-path normalizer for mesh node/session scope comparison,\n * shared by daemon-core (standalone / local IPC) and any other core that has to\n * tell a base node apart from a co-located worktree clone whose ONLY structural\n * difference is its distinct workspace root.\n *\n * One physical daemon can host a base node plus several worktree nodes. Session\n * records, queue claims, and read_chat requests are scoped to a node by matching\n * the session's actual workspace against the node's declared workspace. Those two\n * paths can arrive in different but equivalent spellings (back/forward slashes,\n * trailing separators, Windows case-insensitivity), so a raw string compare would\n * either falsely separate equal paths or fail to engage at all.\n *\n * This folds separator style, trailing slashes, and case into a single comparable\n * form. It was previously a module-private copy in daemon-core's\n * mesh-events-coordinator.ts (WTCLAIM fix-B); promoting it here keeps the one\n * comparison rule identical across the enqueue→claim path, the mesh_status\n * per-node session filter, and the read_chat node scope guard. Pure string ops —\n * no Node/DOM APIs — so it stays a valid mesh-shared leaf.\n */\nexport function normalizeMeshWorkspaceForCompare(dir?: string | null): string {\n if (typeof dir !== 'string') return ''\n return dir.trim().replace(/[\\\\/]+/g, '/').replace(/\\/+$/, '').toLowerCase()\n}\n\n/**\n * Whether two workspace paths refer to the same workspace root after\n * normalization. Returns false when either side is empty — an unknown workspace\n * never \"matches\" another, so callers must decide separately whether an unknown\n * workspace should be treated permissively (the WTCLAIM convention: unknown →\n * do not block).\n */\nexport function meshWorkspacesEquivalent(a?: string | null, b?: string | null): boolean {\n const left = normalizeMeshWorkspaceForCompare(a)\n const right = normalizeMeshWorkspaceForCompare(b)\n if (!left || !right) return false\n return left === right\n}\n","/**\n * Canonical coordinator/daemon-id form normalizer shared by daemon-core (the mesh\n * reconcile loop, pending-event queue, and MCP surface) — the daemon-id counterpart\n * of node-normalize.ts.\n *\n * A daemon answers to the SAME machine under three interchangeable id forms, all\n * derived from one `mach_<hex>` machine id:\n * - bare — `mach_<hex>` (loadConfig().machineId; stamped by the local\n * queue-assignment dispatch path)\n * - cloud — `daemon_mach_<hex>` (the coordinator mesh node's config-form\n * daemonId, which the MCP layer's resolveCoordinatorDaemonId\n * prefers and stamps onto a worker's meshCoordinatorDaemonId)\n * - standalone — `standalone_mach_<hex>` (a standalone daemon's status instanceId)\n *\n * A worker's completion event is scoped (`coordinator_daemon_id`) with whichever\n * form the dispatch path happened to stamp, but the coordinator that later drains /\n * surfaces that event resolves its OWN id through a different path and frequently\n * holds a DIFFERENT form. Because the scope filter is an exact-string match\n * (`coordinator_daemon_id IS NULL OR IN (...)` in SQL, `.includes()` in JS), a\n * completion stamped `daemon_mach_X` is silently skipped by a coordinator whose\n * self-id set only contains bare `mach_X` (or standalone form) — the event never\n * surfaces and the coordinator is never auto-notified, while NULL-scoped events\n * (e.g. worktree bootstrap) always pass via the `IS NULL` branch.\n *\n * This module is the single source of truth that collapses the three forms to one\n * machine core and EXPANDS a self-id set to every equivalent form, so a scope match\n * succeeds regardless of which form stamped the event. Expansion stays WITHIN a\n * single machine core (`daemon_mach_X` only ever expands to other `mach_X` forms),\n * so an event scoped to a DIFFERENT coordinator is never falsely claimed.\n */\n\nimport { readString } from './json'\n\nconst DAEMON_ID_PREFIXES = ['daemon_', 'standalone_'] as const\n\n/**\n * A daemon DO addressed by a raw 64-hex DO id (`idFromString`) rather than by a\n * canonical name (`idFromName(\"daemon_mach_<hex>\")`). Decide by FORMAT, not by\n * length — the canonical name is 43+ chars, so a `length > 32` heuristic would\n * misclassify it. Mirrors the server's session-routing `isRawDoId`.\n */\nexport function isRawDaemonDoId(id: string | null | undefined): boolean {\n const trimmed = readString(id)\n return !!trimmed && /^[0-9a-f]{64}$/i.test(trimmed)\n}\n\n/** The machine-evidence fields a real daemon reports about its hardware. */\nexport interface DaemonMachineEvidence {\n machineNickname?: string | null\n nickname?: string | null\n hostname?: string | null\n platform?: string | null\n machineId?: string | null\n machine?: { hostname?: string | null; platform?: string | null } | null\n sessions?: unknown[] | null\n}\n\n/**\n * A phantom daemon entry — a UI surface must not offer it as a real machine.\n *\n * Symptom block for the raw-DO-id ghost (GHOST-MACHINE-REGISTRATIONS). When the\n * `X-ADHDEV-Daemon` instanceId header is missing or unparseable, the /ws handler\n * falls back to a random DO name, so every reconnect mints a FRESH raw 64-hex DO\n * id. Those keys accumulate as hardware-less entries that render as a bare hash\n * where a machine name belongs.\n *\n * BOTH conditions are required, and the second is what keeps this safe:\n * 1. the id is a raw DO id — no `daemon_`/`standalone_` canonical prefix.\n * 2. no machine evidence at all — no nickname, hostname, platform, registered\n * machineId, and no sessions.\n *\n * A legacy / not-yet-reauthed daemon that ACTUALLY reports itself fails (2) and\n * therefore still renders, still attaches, and still routes — dropping on (1)\n * alone would make real daemons disappear from the picker. This is strictly a\n * PRESENTATION filter: routing tables (server `lastStatuses`, P2P relay) keep\n * the entry, because the raw key still resolves via `idFromString`.\n *\n * The server applies the same rule to its dashboard payloads via\n * `_unresolvedIdentity` (UserSession.isPhantomMachineEntry). That marker is\n * server-internal and never reaches the browser, and the client daemon store\n * never evicts an entry once injected — so a client surface reading the merged\n * P2P/WS store must re-derive the verdict from the entry SHAPE. This function is\n * that shared rule.\n */\nexport function isPhantomDaemonEntry(\n entry: (DaemonMachineEvidence & { id?: string | null }) | null | undefined,\n): boolean {\n if (!entry) return false\n if (!isRawDaemonDoId(entry.id)) return false\n const hasMachineEvidence = Boolean(\n readString(entry.machineNickname)\n || readString(entry.nickname)\n || readString(entry.hostname)\n || readString(entry.platform)\n || readString(entry.machine?.hostname)\n || readString(entry.machine?.platform)\n || readString(entry.machineId)\n || (Array.isArray(entry.sessions) && entry.sessions.length > 0),\n )\n return !hasMachineEvidence\n}\n\n/**\n * Reduce any daemon-id form to its machine core: strips a leading `daemon_` /\n * `standalone_` prefix, leaving the bare `mach_<hex>` (or returning a non-prefixed\n * id unchanged). Returns undefined for an empty/absent id.\n */\nexport function machineCoreFromDaemonId(id: string | null | undefined): string | undefined {\n const trimmed = readString(id)\n if (!trimmed) return undefined\n for (const prefix of DAEMON_ID_PREFIXES) {\n if (trimmed.startsWith(prefix)) {\n const core = trimmed.slice(prefix.length).trim()\n return core || undefined\n }\n }\n return trimmed\n}\n\n/**\n * Canonicalize any daemon-id form to the single CANON producer form\n * `daemon_mach_<core>` (the cloud `daemon_` form).\n *\n * CANON-IDENTITY double-dispatch root cause: the coordinator daemon id is stamped\n * onto a worker dispatch by TWO independent producers — the MCP-side\n * resolveCoordinatorDaemonId (which prefers the coordinator mesh node's config-form\n * `daemon_mach_X` daemonId) and the daemon-core queue dispatch (which stamps the\n * bare `loadConfig().machineId` = `mach_X`). When the SAME coordinator dispatches\n * the same task down both paths, the two worker sessions are stamped with two\n * DIFFERENT coordinator-id forms; a raw-string dedup that should recognise \"this\n * task is already dispatched by me\" fails, and the task runs twice.\n *\n * The durable fix is comparator-side (daemonIdsEquivalent / expandDaemonIdForms),\n * but unifying every PRODUCER on one canonical form shrinks the surface so even a\n * raw `===` agrees. The canon is the cloud `daemon_` form because that is what the\n * coordinator mesh node's config-form daemonId already carries and what the cloud\n * P2P signaling layer registers a daemon under — so canonicalizing the bare/standalone\n * fallback forms makes them consistent with the already-working primary path.\n *\n * Only a `mach_<…>` core is rewritten; an arbitrary/non-machine id (e.g. a custom\n * node id) is returned unchanged so it is never ballooned into a spurious `daemon_`\n * form. Idempotent. Returns undefined for an empty/absent id.\n */\nexport function canonicalDaemonId(id: string | null | undefined): string | undefined {\n const core = machineCoreFromDaemonId(id)\n if (!core) return undefined\n if (!core.startsWith('mach_')) return core\n return `daemon_${core}`\n}\n\n/** True when both ids resolve to the same machine core — i.e. they are the same\n * daemon under different id forms. False when either side is empty. */\nexport function daemonIdsEquivalent(a: string | null | undefined, b: string | null | undefined): boolean {\n const coreA = machineCoreFromDaemonId(a)\n const coreB = machineCoreFromDaemonId(b)\n if (!coreA || !coreB) return false\n return coreA === coreB\n}\n\n/**\n * Expand a set of coordinator/daemon ids to every equivalent form, so an\n * exact-string scope filter (SQL `IN (...)` or JS `.includes()`) matches a\n * completion stamped in any form of the same machine. The original ids are kept in\n * their input order and FIRST (callers that treat `[0]` as the primary — e.g.\n * per-daemon JSONL file naming — keep their original primary); the derived\n * `mach_<hex>` / `daemon_mach_<hex>` / `standalone_mach_<hex>` forms are appended.\n *\n * Derived prefixed forms are emitted ONLY for a core that looks like a real machine\n * id (`mach_<…>`), so arbitrary/test ids (e.g. `node-daemon-id`) are passed through\n * untouched and never balloon into spurious forms. Result is de-duplicated.\n */\nexport function expandDaemonIdForms(\n ids: string | null | undefined | ReadonlyArray<string | null | undefined>,\n): string[] {\n const list = Array.isArray(ids) ? ids : ids != null ? [ids] : []\n const out: string[] = []\n const seen = new Set<string>()\n const add = (value: string | undefined): void => {\n if (!value || seen.has(value)) return\n seen.add(value)\n out.push(value)\n }\n // Pass 1: originals first, in input order (preserve caller's primary at [0]).\n for (const raw of list) add(readString(raw))\n // Pass 2: derived machine-core forms for any id that resolves to a `mach_` core.\n for (const raw of list) {\n const core = machineCoreFromDaemonId(readString(raw))\n if (!core || !core.startsWith('mach_')) continue\n add(core)\n for (const prefix of DAEMON_ID_PREFIXES) add(`${prefix}${core}`)\n }\n return out\n}\n","/**\n * Canonical compact git-shape summarizer used by debug/log surfaces on both the\n * cloud (daemon-cloud mesh command summarizer) and standalone (daemon-core router\n * RepoMeshStatusDebug) paths. Produces a small, log-safe projection of a git\n * status record — commit SHAs are truncated to 12 chars.\n *\n * Transport-specific envelope unwrapping (result / result.status / top-level)\n * stays in the caller; this takes an already-unwrapped status record.\n */\n\nimport { readBoolean, readNumber, readRecord, readString } from './json'\n\nexport function summarizeGitShape(status: unknown): Record<string, unknown> | null {\n const record = readRecord(status)\n if (!Object.keys(record).length) return null\n const submodules = Array.isArray(record.submodules)\n ? record.submodules.map((entry: unknown) => {\n const sub = readRecord(entry)\n return {\n path: readString(sub.path) ?? null,\n commit: readString(sub.commit)?.slice(0, 12) ?? null,\n dirty: readBoolean(sub.dirty) ?? false,\n outOfSync: readBoolean(sub.outOfSync, sub.out_of_sync) ?? false,\n }\n })\n : []\n return {\n isGitRepo: readBoolean(record.isGitRepo),\n workspace: readString(record.workspace) ?? null,\n repoRoot: readString(record.repoRoot, record.repo_root) ?? null,\n branch: readString(record.branch) ?? null,\n upstream: readString(record.upstream) ?? null,\n upstreamStatus: readString(record.upstreamStatus, record.upstream_status) ?? null,\n headCommit: readString(record.headCommit, record.head_commit)?.slice(0, 12) ?? null,\n ahead: readNumber(record.ahead) ?? null,\n behind: readNumber(record.behind) ?? null,\n dirtyCounts: {\n staged: readNumber(record.staged) ?? 0,\n modified: readNumber(record.modified) ?? 0,\n untracked: readNumber(record.untracked) ?? 0,\n deleted: readNumber(record.deleted) ?? 0,\n renamed: readNumber(record.renamed) ?? 0,\n },\n lastCheckedAt: readNumber(record.lastCheckedAt, record.last_checked_at) ?? null,\n submoduleCount: submodules.length,\n submodules,\n }\n}\n","/**\n * Projection of a daemon `git_diff_file` answer into the per-file row the MCP\n * `git_diff` tool and the cloud git-diff shortcut both return: the diff text\n * capped at `maxLines` (with a visible truncation marker), plus the file's\n * change metadata from the diff summary.\n */\n\nimport { readRecord } from './json'\n\nexport interface GitFileDiffRow {\n path: string\n old_path?: string | null\n status?: string\n diff: string\n truncated: boolean\n binary: boolean\n error?: string\n}\n\n/** Cap diff text at `maxLines`; a truncated diff ends with a `... (truncated)` marker line. */\nfunction truncateDiffText(text: string, maxLines: number): { diff: string; truncated: boolean } {\n const lines = text.split('\\n')\n const truncated = lines.length > maxLines\n return {\n diff: truncated ? lines.slice(0, maxLines).join('\\n') + '\\n... (truncated)' : text,\n truncated,\n }\n}\n\n/** One changed file's row from its `git_diff_file` answer (either `{ diff: {...} }` or the bare diff record). */\nexport function projectFileDiffRow(\n file: { path: string; oldPath?: string | null; status?: string },\n rawResult: unknown,\n maxLines: number,\n): GitFileDiffRow {\n const raw = readRecord(rawResult)\n const d = readRecord(raw.diff ?? rawResult)\n const text = typeof d.diff === 'string' ? d.diff : ''\n const { diff, truncated } = truncateDiffText(text, maxLines)\n return {\n path: file.path,\n old_path: file.oldPath ?? null,\n status: file.status ?? 'M',\n diff,\n truncated,\n binary: typeof d.binary === 'boolean' ? d.binary : false,\n }\n}\n","/**\n * Brain-routing (task difficulty → provider/model/thinking) types.\n *\n * The coordinator classifies each task it enqueues by execution difficulty, and a\n * per-difficulty \"brain\" preset resolves that into a concrete provider / model /\n * thinking-level for the launched session. The goal is token economy: an `easy`\n * task runs on a cheaper model at low reasoning effort; a `difficult` task gets a\n * stronger model at high effort. This picks the single brain that *executes* a\n * task, stored machine-local (`~/.adhdev/meshes.json`).\n */\n\n/** The fixed difficulty axis the coordinator classifies a task into. */\nexport type MeshTaskDifficulty = 'easy' | 'medium' | 'difficult' | 'freeform'\n\nexport const MESH_TASK_DIFFICULTIES: MeshTaskDifficulty[] = ['easy', 'medium', 'difficult', 'freeform']\n\n/**\n * A per-difficulty brain preset: which provider / model / thinking level a task of\n * that difficulty should run on. Every field is optional — a preset may set only a\n * model (keep the routed provider) or only a thinking level. Applied at enqueue:\n * an explicit model/thinkingLevel on the task always wins over the preset.\n */\nexport interface BrainSlot {\n /** Optional provider type, e.g. 'claude-cli' | 'codex-cli'. Absent → keep the tag/priority-routed provider. */\n provider?: string\n /** Optional model, e.g. 'opus' | 'sonnet' | 'haiku'. Best-effort at launch (initialModel). */\n model?: string\n /** Optional standard thinking level, 'low' | 'medium' | 'high'. Best-effort (initialThinkingLevel). */\n thinkingLevel?: 'low' | 'medium' | 'high'\n}\n\n/**\n * Per-difficulty brain bindings for ONE mesh, stored machine-local in\n * `~/.adhdev/meshes.json` under that mesh's entry (`meshes[].difficultyBrains`).\n * The scope is per mesh: two meshes on the same\n * machine hold independent presets, so one can pin `difficult` to a cheaper model\n * without changing what any other mesh runs. (It formerly sat at the config root\n * keyed by difficulty alone — and since this map picks the MODEL a task runs on,\n * that meant the shipped defaults, and any one mesh's override, applied to every\n * mesh on the machine.) A difficulty absent from the map has no preset — the task\n * runs with no difficulty-derived model/thinking (ordinary routing).\n */\nexport type DifficultyBrainMap = Partial<Record<MeshTaskDifficulty, BrainSlot>>\n\n/** True for a recognized difficulty value. */\nexport function isMeshTaskDifficulty(value: unknown): value is MeshTaskDifficulty {\n return typeof value === 'string' && (MESH_TASK_DIFFICULTIES as string[]).includes(value)\n}\n\n/**\n * Shipped difficulty presets: NONE. Operator-authored capability slots are the\n * authority: easy < medium < difficult is a hard minimum (freeform is explicitly\n * unconstrained), while the preset map only supplies optional launch axes.\n *\n * WHY THIS IS EMPTY (it formerly shipped easy→haiku/low, medium→sonnet/medium,\n * difficult→opus/high):\n *\n * 1. WRONG AXIS. `opus`/`sonnet`/`haiku` are Claude model families, but the\n * preset was stamped on a task at ENQUEUE time — before routing has chosen\n * a node, let alone a provider. A `difficult` task therefore carried\n * `model: 'opus'` even when it landed on kimi / codex / antigravity. The\n * CODEX-400 guard (model-provider-compat.ts) exists ONLY to strip these\n * Claude aliases back off before a non-Anthropic launch — a workaround for\n * a value that should never have been stamped provider-blind.\n *\n * 2. IT FOUGHT THE SLOTS. Operators express model choice per node via\n * capability slots (`mesh_node_slots` action \"set\"), which know the provider. A\n * mesh-wide preset that also picks a model duplicated that decision from a\n * position with strictly less information, and needed the modelSource\n * ('explicit' vs 'preset') precedence machinery plus a fail-closed\n * slot-model guard just to keep the slot winning.\n *\n * Removing the shipped defaults does NOT remove the feature: the map is still\n * honored, so an operator who deliberately sets presets (difficulty_brains_set)\n * keeps exactly that behavior. It only stops the mesh from inventing a model\n * nobody configured. A node WITH slots is unaffected (its slots already decided);\n * a node WITHOUT slots now launches on the provider's own default model instead\n * of a Claude alias picked blind.\n */\nexport const DEFAULT_DIFFICULTY_BRAINS: DifficultyBrainMap = {}\n\n/** Normalize a raw thinking level to the standard union, or undefined. */\nexport function normalizeThinkingLevel(value: unknown): 'low' | 'medium' | 'high' | undefined {\n const v = typeof value === 'string' ? value.trim().toLowerCase() : ''\n return v === 'low' || v === 'medium' || v === 'high' ? v : undefined\n}\n\n/** Normalize a raw BrainSlot (trim strings, drop empties, clamp thinkingLevel). */\nexport function normalizeBrainSlot(raw: unknown): BrainSlot {\n const r = (raw && typeof raw === 'object') ? raw as Record<string, unknown> : {}\n const provider = typeof r.provider === 'string' ? r.provider.trim() : ''\n const model = typeof r.model === 'string' ? r.model.trim() : ''\n const thinkingLevel = normalizeThinkingLevel(r.thinkingLevel)\n return {\n ...(provider ? { provider } : {}),\n ...(model ? { model } : {}),\n ...(thinkingLevel ? { thinkingLevel } : {}),\n }\n}\n\n/** Normalize a raw DifficultyBrainMap, dropping unknown keys and empty slots. */\nexport function normalizeDifficultyBrainMap(raw: unknown): DifficultyBrainMap {\n const out: DifficultyBrainMap = {}\n if (!raw || typeof raw !== 'object') return out\n for (const key of MESH_TASK_DIFFICULTIES) {\n const slot = normalizeBrainSlot((raw as Record<string, unknown>)[key])\n if (slot.provider || slot.model || slot.thinkingLevel) out[key] = slot\n }\n return out\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Node capability slots (node capability slots design, 2026-07-09)\n//\n// A node's \"Preferred AI tools\" list is redefined as an ordered array of\n// capability slots. Each slot bundles what used to be scattered across\n// providerPriority (order), a per-provider maxParallel cap, and the\n// the owning mesh's difficultyBrains (difficulty → model/thinking). Slot order =\n// preference. This single profile is the source of truth for task routing and\n// orchestrator-proposed edits.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * One capability slot on a mesh node. Extends the BrainSlot shape\n * (provider/model/thinkingLevel) with the difficulty range it handles, capability\n * tags, and a per-slot parallelism cap.\n */\nexport interface NodeCapabilitySlot {\n /** Provider type this slot uses, e.g. 'claude-cli' | 'codex-cli'. Required (a slot is defined by its provider). */\n provider: string\n /** Optional model, e.g. 'opus' | 'sonnet' | 'haiku'. Best-effort at launch. */\n model?: string\n /**\n * Optional thinking level. The provider's own vocabulary (e.g. low/medium/high,\n * or codex's low/medium/high/max) passed through verbatim — best-effort at\n * launch. A string, not the standard union, so provider-declared levels like\n * 'max' are not dropped.\n */\n thinkingLevel?: string\n /**\n * Difficulty grades this slot handles. On an explicit-slot node these form a\n * hard minimum: higher grades may run lower tasks, but lower grades never run\n * higher tasks. Empty/absent is ungraded and only unconstrained freeform tasks\n * use it; legacy providerPriority-derived slots remain backward-compatible.\n */\n difficulty?: MeshTaskDifficulty[]\n /** Capability tags this slot satisfies (matched against a task's requiredTags). */\n capability?: string[]\n /** Per-node·per-slot max concurrent tasks. Omit = no per-slot cap. */\n maxParallel?: number\n}\n\n/** Normalize a raw NodeCapabilitySlot; returns null when it has no usable provider. */\nexport function normalizeNodeCapabilitySlot(raw: unknown): NodeCapabilitySlot | null {\n const r = (raw && typeof raw === 'object') ? raw as Record<string, unknown> : {}\n const provider = typeof r.provider === 'string' ? r.provider.trim() : ''\n if (!provider) return null\n const model = typeof r.model === 'string' ? r.model.trim() : ''\n // Pass the provider's own thinking-level vocabulary through verbatim (don't\n // clamp to low/medium/high — a provider may declare 'max' etc.).\n const thinkingLevel = typeof r.thinkingLevel === 'string' ? r.thinkingLevel.trim() : ''\n const difficulty = Array.isArray(r.difficulty)\n ? (r.difficulty.filter(isMeshTaskDifficulty) as MeshTaskDifficulty[])\n : []\n const capability = Array.isArray(r.capability)\n ? r.capability.filter((t): t is string => typeof t === 'string' && !!t.trim()).map(t => t.trim())\n : []\n const maxParallelNum = Number(r.maxParallel)\n const maxParallel = Number.isFinite(maxParallelNum) && maxParallelNum > 0 ? Math.floor(maxParallelNum) : undefined\n return {\n provider,\n ...(model ? { model } : {}),\n ...(thinkingLevel ? { thinkingLevel } : {}),\n ...(difficulty.length ? { difficulty } : {}),\n ...(capability.length ? { capability } : {}),\n ...(maxParallel !== undefined ? { maxParallel } : {}),\n }\n}\n\n/** Normalize a raw slot array, dropping provider-less entries. */\nexport function normalizeNodeCapabilitySlots(raw: unknown): NodeCapabilitySlot[] {\n if (!Array.isArray(raw)) return []\n const out: NodeCapabilitySlot[] = []\n for (const entry of raw) {\n const slot = normalizeNodeCapabilitySlot(entry)\n if (slot) out.push(slot)\n }\n return out\n}\n\n/**\n * Back-compat migration: derive capability slots from the legacy fields when a\n * node has no explicit `slots`. Order follows providerPriority; difficulty/model/\n * thinking are folded in from the OWNING MESH's difficultyBrains (each difficulty\n * attaches to the slot whose provider the brain preset names, or — when the brain\n * has no provider — to every slot as a shared model/thinking default for that\n * difficulty).\n *\n * (Legacy nodes' per-provider `maxParallel` cap has been migrated onto\n * `slots[].maxParallel` at config-load time, so it is no longer folded in here.)\n *\n * Returns [] when there's nothing to derive (caller then keeps legacy behavior:\n * first available provider).\n */\nexport function deriveSlotsFromLegacy(input: {\n providerPriority?: string[]\n difficultyBrains?: DifficultyBrainMap\n}): NodeCapabilitySlot[] {\n const priority = Array.isArray(input.providerPriority)\n ? input.providerPriority.filter((p): p is string => typeof p === 'string' && !!p.trim()).map(p => p.trim())\n : []\n if (priority.length === 0) return []\n\n // Brain presets keyed by the provider they name (provider-specific), plus a\n // provider-agnostic list applied to every slot as a shared default.\n const brains = input.difficultyBrains || {}\n const byProvider = new Map<string, Array<{ difficulty: MeshTaskDifficulty; model?: string; thinkingLevel?: 'low' | 'medium' | 'high' }>>()\n const shared: Array<{ difficulty: MeshTaskDifficulty; model?: string; thinkingLevel?: 'low' | 'medium' | 'high' }> = []\n for (const diff of MESH_TASK_DIFFICULTIES) {\n const b = brains[diff]\n if (!b) continue\n const entry = { difficulty: diff, model: b.model, thinkingLevel: b.thinkingLevel }\n if (b.provider) {\n const list = byProvider.get(b.provider) ?? []\n list.push(entry)\n byProvider.set(b.provider, list)\n } else {\n shared.push(entry)\n }\n }\n\n return priority.map((provider): NodeCapabilitySlot => {\n // Provider-specific brain first, else the shared default, else nothing.\n const specific = byProvider.get(provider) || []\n const applied = specific.length ? specific : shared\n const difficulty = applied.map(a => a.difficulty)\n // Fold model/thinking from the applied presets: take the first that sets each.\n const model = applied.find(a => a.model)?.model\n const thinkingLevel = applied.find(a => a.thinkingLevel)?.thinkingLevel\n return {\n provider,\n ...(model ? { model } : {}),\n ...(thinkingLevel ? { thinkingLevel } : {}),\n ...(difficulty.length ? { difficulty } : {}),\n }\n })\n}\n\n/**\n * The reverse direction of deriveSlotsFromLegacy: derive the legacy\n * `providerPriority` order from capability slots — each slot's provider, in\n * first-appearance order, de-duplicated. Slot order = preference is the settled\n * slots semantics (node capability slots design, 2026-07-09), so this is what readers of the\n * legacy `policy.providerPriority` field must fall back to when a node declares\n * slots but no explicit providerPriority (otherwise such a node reads as\n * unlaunchable even though its slots fully determine the preference order).\n *\n * Accepts the raw `policy.slots` value (normalized internally). Returns [] when\n * there's nothing to derive (caller then keeps legacy behavior: no priority).\n */\nexport function deriveProviderPriorityFromSlots(slots: unknown): string[] {\n const seen = new Set<string>()\n const out: string[] = []\n for (const slot of normalizeNodeCapabilitySlots(slots)) {\n if (seen.has(slot.provider)) continue\n seen.add(slot.provider)\n out.push(slot.provider)\n }\n return out\n}\n","/**\n * CLI auto-detect → capability-slot PROPOSAL generator.\n *\n * Detection of installed CLI providers already exists per node (the status\n * snapshot's `availableProviders`), and applying a slot profile already exists\n * (`mesh_node_slots` action \"set\", dry-run by default). What was missing is the bit in\n * between: turning \"these CLIs are installed on this node\" into a concrete\n * `NodeCapabilitySlot[]` draft the operator can review. This module is that\n * bridge, and nothing more — it is a PURE proposal generator. It never writes;\n * the caller feeds its output into the existing dry-run/approve tools.\n *\n * ─── Why the mapping is a static table ───────────────────────────────────────\n *\n * Provider manifests carry NO difficulty or capability-grade information. The\n * fields that look like they might (`modelOptions`, `thinkingLevelOptions`)\n * describe what a provider ACCEPTS, not what it is GOOD AT — a provider listing\n * `opus` says nothing about whether opus should get the hard tasks. So there is\n * no honest way to derive difficulty from the manifest today.\n *\n * The table below is therefore seeded from the operator's real, in-use slot\n * configuration rather than from a guess. That makes it a starting point with\n * actual provenance, and it is deliberately isolated in ONE constant so the\n * planned usage-data-driven replacement has a single, obvious swap point.\n *\n * Kept in the dependency-free mesh-shared leaf because both daemon-core (which\n * has the detection data) and mcp-server (which owns the propose/apply tools)\n * need it, and it is pure data + pure functions on plain objects.\n */\nimport {\n normalizeNodeCapabilitySlot,\n type MeshTaskDifficulty,\n type NodeCapabilitySlot,\n} from './brain-routing'\n\n/**\n * One provider's seeded slot recipe. A provider may map to MORE THAN ONE slot\n * (claude-cli does: a wide sonnet slot plus a narrow opus slot for the hard\n * work), which is why the table's values are arrays.\n */\nexport interface CliSlotRecipe {\n /** Optional model to pin on the slot. Best-effort at launch. */\n model?: string\n /** Optional thinking level, in the provider's own vocabulary. */\n thinkingLevel?: string\n /** Difficulty range this slot handles. Empty = general-purpose. */\n difficulty?: MeshTaskDifficulty[]\n /** Per-slot concurrency cap. */\n maxParallel?: number\n /**\n * Set when this recipe is an unvalidated guess rather than a transcription\n * of a slot the operator actually runs. Surfaced on the proposal so the\n * reviewer knows which lines to scrutinize.\n */\n provisional?: boolean\n /** Short human-readable justification, echoed into the proposal. */\n rationale?: string\n}\n\n/**\n * ★ THE MAPPING TABLE — the single swap point.\n *\n * Seeded (2026-08-03) from the operator's live slot configuration, on the\n * reasoning that a transcription of what is actually in production beats an\n * invented heuristic. Replace wholesale once usage data (success rate, cost,\n * turn latency per provider×difficulty) can drive it.\n *\n * Every entry reflects a real configured slot. A provider absent from the table\n * falls back to {@link UNKNOWN_CLI_SLOT_RECIPE}, the only `provisional` recipe.\n */\nexport const CLI_SLOT_RECIPES: Readonly<Record<string, readonly CliSlotRecipe[]>> = Object.freeze<Record<string, readonly CliSlotRecipe[]>>({\n 'claude-cli': [\n {\n model: 'sonnet',\n thinkingLevel: 'high',\n difficulty: ['medium', 'easy'],\n maxParallel: 5,\n rationale: 'Primary workhorse — widest parallelism for routine work.',\n },\n {\n model: 'opus',\n thinkingLevel: 'high',\n difficulty: ['difficult'],\n maxParallel: 1,\n rationale: 'Reserved for hard tasks; capped at 1 to bound cost.',\n },\n ],\n 'kimi': [\n {\n model: 'kimi-code/k3',\n difficulty: ['medium', 'difficult'],\n maxParallel: 2,\n rationale: 'Independent second opinion on mid/hard work.',\n },\n ],\n 'codex-cli': [\n {\n difficulty: ['medium', 'difficult', 'freeform'],\n maxParallel: 2,\n rationale: 'Broad range including freeform; no model pin.',\n },\n ],\n 'antigravity-cli': [\n {\n model: 'Gemini 3.1 Pro (High)',\n difficulty: ['easy'],\n maxParallel: 2,\n rationale: 'Cheap capacity for easy tasks.',\n },\n ],\n 'cursor-cli': [\n {\n model: 'auto',\n difficulty: ['easy'],\n maxParallel: 1,\n rationale: 'Easy tasks only; auto model selection.',\n },\n ],\n})\n\n/**\n * Fallback for a detected CLI provider absent from {@link CLI_SLOT_RECIPES}.\n * Deliberately timid: one general-purpose slot at the lowest parallelism, so an\n * unrecognized provider can be used but never silently soaks up the queue.\n */\nexport const UNKNOWN_CLI_SLOT_RECIPE: Readonly<CliSlotRecipe> = Object.freeze<CliSlotRecipe>({\n difficulty: ['medium'],\n maxParallel: 1,\n provisional: true,\n rationale: 'Unrecognized provider — conservative default (medium, maxParallel 1). Review before relying on it.',\n})\n\n/** A detected, installed CLI provider on one node — the generator's input. */\nexport interface DetectedCliProvider {\n /** Provider type id, e.g. 'claude-cli'. */\n type: string\n /** Human-readable name, for display in the proposal. */\n displayName?: string\n /** Detected version, when known. Display only — never affects the mapping. */\n version?: string\n}\n\n/** One proposed slot plus why it was proposed. */\nexport interface ProposedSlotEntry {\n slot: NodeCapabilitySlot\n /** True when the provider had no table entry and took the conservative fallback. */\n unknownProvider: boolean\n /** True when the recipe behind this slot is flagged as an unvalidated estimate. */\n provisional: boolean\n rationale?: string\n}\n\n/** The full slot proposal for one node, including what a write would DESTROY. */\nexport interface SlotProposal {\n /** The draft slot list — a WHOLESALE replacement for the node's policy.slots. */\n proposedSlots: NodeCapabilitySlot[]\n /** Per-slot provenance, index-aligned with `proposedSlots`. */\n entries: ProposedSlotEntry[]\n /** Provider types detected but not present in the mapping table. */\n unknownProviders: string[]\n /** Provider types whose proposal rests on an unvalidated estimate. */\n provisionalProviders: string[]\n /**\n * Slots currently configured on the node that the proposal does NOT\n * reproduce — i.e. what applying this proposal would DELETE. Slot writes are\n * wholesale replacements, so an operator-hand-tuned slot absent from the\n * detection-derived draft is silently destroyed unless it is named here.\n */\n droppedSlots: NodeCapabilitySlot[]\n /** Provider types that appear in `droppedSlots` but in no proposed slot at all. */\n droppedProviders: string[]\n /** True when applying the proposal would remove at least one existing slot. */\n destructive: boolean\n}\n\n/** Stable key identifying a slot's identity for current-vs-proposed diffing. */\nfunction slotKey(slot: NodeCapabilitySlot): string {\n return [\n slot.provider,\n slot.model ?? '',\n slot.thinkingLevel ?? '',\n [...(slot.difficulty ?? [])].sort().join('|'),\n [...(slot.capability ?? [])].sort().join('|'),\n slot.maxParallel ?? '',\n ].join('\\u0000')\n}\n\n/** Dedupe detected providers by type, preserving first-seen order. */\nfunction dedupeDetected(detected: readonly DetectedCliProvider[]): DetectedCliProvider[] {\n const seen = new Set<string>()\n const out: DetectedCliProvider[] = []\n for (const d of detected) {\n const type = typeof d?.type === 'string' ? d.type.trim() : ''\n if (!type || seen.has(type)) continue\n seen.add(type)\n out.push({ ...d, type })\n }\n return out\n}\n\n/**\n * Build a capability-slot proposal from a node's detected CLI providers.\n *\n * Pure and total: zero detections yields an empty proposal (never throws), which\n * the caller should treat as \"nothing to propose\" rather than \"replace the\n * node's slots with nothing\".\n *\n * `currentSlots` is optional but strongly recommended — it is the only way the\n * returned proposal can report what a wholesale write would destroy.\n */\nexport function buildSlotProposal(\n detected: readonly DetectedCliProvider[],\n currentSlots: readonly NodeCapabilitySlot[] = [],\n): SlotProposal {\n const providers = dedupeDetected(detected ?? [])\n const proposedSlots: NodeCapabilitySlot[] = []\n const entries: ProposedSlotEntry[] = []\n const unknownProviders: string[] = []\n const provisionalProviders: string[] = []\n\n for (const provider of providers) {\n const known = CLI_SLOT_RECIPES[provider.type]\n const recipes: readonly CliSlotRecipe[] = known ?? [UNKNOWN_CLI_SLOT_RECIPE]\n const isUnknown = !known\n if (isUnknown) unknownProviders.push(provider.type)\n\n let providerProvisional = false\n for (const recipe of recipes) {\n // Normalize through the SAME normalizer the daemon applies on write, so\n // a proposal can never preview a shape the write would reshape.\n const slot = normalizeNodeCapabilitySlot({\n provider: provider.type,\n model: recipe.model,\n thinkingLevel: recipe.thinkingLevel,\n difficulty: recipe.difficulty,\n maxParallel: recipe.maxParallel,\n })\n if (!slot) continue\n const provisional = recipe.provisional === true\n if (provisional) providerProvisional = true\n proposedSlots.push(slot)\n entries.push({\n slot,\n unknownProvider: isUnknown,\n provisional,\n ...(recipe.rationale ? { rationale: recipe.rationale } : {}),\n })\n }\n if (providerProvisional) provisionalProviders.push(provider.type)\n }\n\n // What a wholesale write would destroy: every currently-configured slot with\n // no exact counterpart in the draft.\n const proposedKeys = new Set(proposedSlots.map(slotKey))\n const droppedSlots = currentSlots.filter(slot => !proposedKeys.has(slotKey(slot)))\n const proposedProviders = new Set(proposedSlots.map(s => s.provider))\n const droppedProviders = [...new Set(\n droppedSlots.map(s => s.provider).filter(p => !proposedProviders.has(p)),\n )]\n\n return {\n proposedSlots,\n entries,\n unknownProviders,\n provisionalProviders,\n droppedSlots,\n droppedProviders,\n destructive: droppedSlots.length > 0,\n }\n}\n","\nexport function interpolateString(template: string, ctx: Record<string, unknown>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) => {\n const val = ctx[key];\n return val !== undefined ? String(val) : `{{${key}}}`;\n });\n}\n","/**\n * Canonical Repo Mesh coordinator tool-name registry — the single source of truth\n * the three surfaces must agree on:\n *\n * 1. mcp-server `ALL_MESH_TOOLS` (the published MCP tool schemas),\n * 2. daemon-core `coordinator-prompt.ts` `TOOLS_SECTION` (what the coordinator LLM\n * is told it can call), and\n * 3. the `NN tools` doc comments in the mesh-tools barrels.\n *\n * mcp-server does not depend on daemon-core's internal prompt, and daemon-core cannot\n * import mcp-server (dependency direction: daemon-core ← mcp-server). This dependency-\n * free leaf is the only place both can reference, so the 6-6 consistency test\n * (daemon-core coordinator-prompt.test.ts) and mcp-server both assert against THIS\n * list. Adding a new mesh tool means adding its name here first; the tests then force\n * the schema + prompt + barrel comment to catch up, which is exactly the regression\n * gate that let coordinator-prompt drift 14 tools behind the schema before.\n *\n * Order mirrors mcp-server `ALL_MESH_TOOLS` for easy visual diffing, but the consistency\n * checks are set-based (order-insensitive).\n */\nexport const CANONICAL_MESH_TOOL_NAMES = [\n 'mesh_status',\n 'mesh_route_preview',\n 'mesh_list_nodes',\n // Batch before task, mirroring ALL_MESH_TOOLS.\n 'mesh_enqueue_batch',\n 'mesh_enqueue_task',\n 'mesh_view_queue',\n 'mesh_queue_cancel',\n 'mesh_queue_requeue',\n 'mesh_send_task',\n 'mesh_read_chat',\n 'mesh_read_debug',\n 'mesh_read_terminal',\n 'mesh_send_keys',\n 'mesh_launch_session',\n 'mesh_git_status',\n 'mesh_read_node_logs',\n 'mesh_fast_forward_node',\n 'mesh_restart_daemon',\n 'mesh_checkpoint',\n 'mesh_approve',\n 'mesh_answer_question',\n 'mesh_list_pending_approvals',\n 'mesh_create',\n 'mesh_add_node',\n 'mesh_clone_node',\n 'mesh_remove_node',\n 'mesh_cleanup_worktree_nodes',\n 'mesh_refine_node',\n 'mesh_refine_batch',\n 'mesh_config',\n 'mesh_init',\n 'mesh_cleanup_sessions',\n 'mesh_task_history',\n // Deprecated alias of mesh_task_history (2026-10-08: the kind/since/node query\n // axes moved onto mesh_task_history). Still published for one release so older\n // coordinator prompts keep working; drop it — here, in ALL_MESH_TOOLS, the\n // dispatch table and the prompt index — in the next release.\n 'mesh_ledger_query',\n 'mesh_note',\n 'mesh_reconcile_ledger',\n 'mesh_mission_upsert',\n 'mesh_mission_list',\n 'mesh_review_inbox',\n 'mesh_node_slots',\n] as const;\n\nexport type CanonicalMeshToolName = typeof CANONICAL_MESH_TOOL_NAMES[number];\n\n/** The count the `NN tools` barrel doc comments and consistency test assert against. */\nexport const CANONICAL_MESH_TOOL_COUNT = CANONICAL_MESH_TOOL_NAMES.length;\n\n/**\n * Tool names retired by the 2026-09-26 tool-surface consolidation (60 → 48).\n * Every capability behind them is still reachable: each retired name maps to the\n * merged tool plus the discriminator argument that selects the same behaviour.\n *\n * mcp-server answers a call to a retired name with an error naming the\n * replacement (it does NOT forward silently — a coordinator running an old\n * prompt must learn the new spelling), and the daemon-core coordinator prompt\n * test asserts none of these names is advertised anywhere in the prompt.\n *\n * `args` is the discriminator to add; every other argument keeps its name.\n * `note` carries any extra guidance when an argument moved in a rename.\n */\nexport const RETIRED_MESH_TOOLS: Readonly<Record<string, {\n readonly tool: CanonicalMeshToolName;\n readonly args: Readonly<Record<string, string>>;\n readonly note?: string;\n}>> = {\n mesh_node_slots_set: { tool: 'mesh_node_slots', args: { action: 'set' } },\n mesh_node_slots_list: { tool: 'mesh_node_slots', args: { action: 'list' } },\n mesh_node_slots_propose: { tool: 'mesh_node_slots', args: { action: 'propose' } },\n mesh_record_note: { tool: 'mesh_note', args: { action: 'record' } },\n mesh_forget_note: { tool: 'mesh_note', args: { action: 'forget' } },\n mesh_reinit: { tool: 'mesh_init', args: { mode: 'reinit' } },\n mesh_refine_config: { tool: 'mesh_config', args: { kind: 'refine' } },\n mesh_change_impact_config: { tool: 'mesh_config', args: { kind: 'change_impact' } },\n mesh_write_mesh_json_config: { tool: 'mesh_config', args: { kind: 'mesh_json' } },\n mesh_plan_onboarding: { tool: 'mesh_create', args: { mode: 'plan' } },\n mesh_prune_stale_direct: { tool: 'mesh_cleanup_sessions', args: { mode: 'prune_stale_direct' } },\n};\n\nconst COORDINATOR_PROMPT_APPEND_REMOVED = 'Per-machine coordinator prompt files are no longer read. For a standing instruction on this project\\'s coordinator, put it in the repo\\'s .adhdev/mesh.json coordinator.systemPromptAppend (mesh_config kind \"mesh_json\"), or record a durable lesson with mesh_note.';\n\n/**\n * Tool names removed outright (no merged replacement), mapped to the guidance a\n * coordinator on an old prompt needs to do the same job with the remaining tools.\n */\nexport const REMOVED_MESH_TOOLS: Readonly<Record<string, string>> = {\n mesh_magi_review: 'For a multi-perspective review, send the same question to 2-3 workers on different providers with mesh_send_task, wait for their report_completion, then synthesize the answers yourself.',\n mesh_magi_collect: 'Worker answers arrive as report_completion events; synthesize them yourself.',\n mesh_magi_kind_panel: 'There are no review panels any more; pick the workers per review with mesh_send_task.',\n mesh_magi_kind_panel_set: 'There are no review panels any more; pick the workers per review with mesh_send_task.',\n mesh_magi_kind_panel_list: 'There are no review panels any more; pick the workers per review with mesh_send_task.',\n // 2026-10-08: was a pure alias — mesh_refine_node's default dry-run returns the same plan.\n mesh_refine_plan: 'Call mesh_refine_node with the same node_id and no execute: its default dry-run returns the same Refinery plan and executes nothing.',\n // 2026-10-08: the per-machine coordinator-prompts/ file layer was removed (assistant-layer design §11 Q2).\n mesh_coordinator_prompt_append: COORDINATOR_PROMPT_APPEND_REMOVED,\n mesh_coordinator_prompt_append_get: COORDINATOR_PROMPT_APPEND_REMOVED,\n mesh_coordinator_prompt_append_set: COORDINATOR_PROMPT_APPEND_REMOVED,\n};\n\n/**\n * The error text for a call to a retired or removed tool name, or null when\n * `name` is neither. One wording shared by every MCP mode so the redirect reads\n * the same wherever an old prompt calls it.\n */\nexport function retiredMeshToolError(name: string): string | null {\n if (Object.prototype.hasOwnProperty.call(REMOVED_MESH_TOOLS, name)) {\n return `Tool \"${name}\" was removed. ${REMOVED_MESH_TOOLS[name]}`;\n }\n const entry = Object.prototype.hasOwnProperty.call(RETIRED_MESH_TOOLS, name) ? RETIRED_MESH_TOOLS[name] : undefined;\n if (!entry) return null;\n const discriminator = Object.entries(entry.args).map(([k, v]) => `${k}: \"${v}\"`).join(', ');\n return `Tool \"${name}\" was retired (merged into ${entry.tool}). Call ${entry.tool} with ${discriminator} and the same other arguments.`\n + (entry.note ? ` ${entry.note}` : '');\n}\n","/**\n * OFFLINE-NODE-STATUS-REFRESH — the status-origin probe marker.\n *\n * A remote `git_status` (or any relayed/dispatched mesh command) that originates from\n * an explicit_refresh / mesh_status aggregate carries this marker inside its ARGS. The\n * daemon-cloud dispatch wrapper and MCP relay handler read it to grant the SHORT\n * connect-wait budget so a single offline (powered-off) peer no longer blocks the whole\n * status assembly for ~90s.\n *\n * It is deliberately an args marker rather than adding `git_status` to the global\n * probe-class command set: a user-driven / targeted `git_status` (no marker) must keep\n * waiting out the full connect deadline for a slow relay to open (rc.503 intent). Only a\n * status-origin probe opts into the short budget.\n *\n * The key is `_`-prefixed so it travels alongside the real args (workspace,\n * refreshUpstream, includeSubmodules, …) and is ignored by the git_status handler; the\n * dispatch/relay sites strip it defensively before the command executes so it never\n * reaches a handler that echoes unknown args.\n *\n * This dependency-free leaf is the single source of truth shared by daemon-core (the\n * aggregate probe producer), mcp-server (the MCP relay producer), and daemon-cloud (the\n * dispatch/relay consumer) so the key cannot drift between producer and consumer.\n */\nexport const STATUS_PROBE_ARG_KEY = '_statusProbe' as const;\n\n/** Stamp the status-origin probe marker onto a command's args (non-mutating). */\nexport function withStatusProbeMarker(\n args: Record<string, unknown> = {},\n): Record<string, unknown> {\n return { ...args, [STATUS_PROBE_ARG_KEY]: true };\n}\n\n/** True when the args carry the status-origin probe marker. */\nexport function argsCarryStatusProbeMarker(args: unknown): boolean {\n return (\n !!args &&\n typeof args === 'object' &&\n (args as Record<string, unknown>)[STATUS_PROBE_ARG_KEY] === true\n );\n}\n\n/**\n * Return a shallow copy of args with the internal marker removed so it never leaks to\n * the executing command handler. Returns the original reference when no marker is\n * present (avoids an allocation on the common path).\n */\nexport function stripStatusProbeMarker(\n args: Record<string, unknown>,\n): Record<string, unknown> {\n if (!argsCarryStatusProbeMarker(args)) return args;\n const { [STATUS_PROBE_ARG_KEY]: _drop, ...rest } = args;\n return rest;\n}\n","/**\n * Mesh RPC frame chunking — split/reassemble oversized mesh envelopes.\n *\n * WHY THIS EXISTS\n * The mesh DataChannel path (`daemon-mesh-manager`) writes every RPC envelope as a\n * SINGLE `dc.sendMessage(JSON.stringify(envelope))` frame. That was fine while every\n * mesh arg was small text, but a coordinator dispatching an IMAGE to a worker puts a\n * multi-MB base64 part inside `args` — far past what one DataChannel frame carries, so\n * the send throws or the frame is dropped and the dispatch silently dies.\n *\n * The dashboard P2P path already solved exactly this problem and has been running in\n * production: `packages/daemon-cloud/src/daemon-p2p/data-channel-router.ts` (send +\n * reassemble) and `packages/web-cloud/src/p2p.ts` (browser side). This module is a PORT\n * of that proven scheme onto the mesh envelope shape — deliberately NOT a new protocol.\n * The boundary values are carried over unchanged (see the constants below for why each\n * one is what it is).\n *\n * It lives in mesh-shared because it is pure string/JSON work with no transport, no\n * Node API and no DOM API — the same reason the normalizers live here. `daemon-cloud`\n * (sender/receiver) is the only current consumer, but keeping it in the pure leaf means\n * the standalone side can reassemble with the identical code rather than a hand-synced\n * copy, which is the drift bug class this package was created to kill.\n *\n * FAILURE POLICY (DoD): reassembly never degrades silently. A malformed, out-of-range,\n * over-budget or unparseable chunk stream yields an explicit typed failure that the\n * caller turns into an RPC error — never a partially-applied or truncated envelope.\n */\n\n/**\n * Inline ceiling: an envelope whose JSON is at or below this goes out as one frame,\n * exactly as before this module existed. 60_000 (not 65_536) matches the dashboard\n * path and leaves headroom under the common 64KiB SCTP message limit so the frame is\n * never the thing that trips a transport-level cap.\n */\nexport const MESH_MAX_INLINE_FRAME_BYTES = 60_000\n\n/**\n * Per-chunk payload slice, in CHARACTERS. Ported unchanged from the dashboard path.\n *\n * Why 16_000 chars is safe under a 60_000-BYTE ceiling, with ~3.75x of headroom:\n * `splitMeshFrame` slices the ALREADY-SERIALIZED outer frame, so the text being cut\n * is JSON output — control characters are pre-expanded to `\\u00XX` ASCII before they\n * ever reach the slicer. Re-escaping that slice inside the chunk envelope can at worst\n * double the backslashes. Measured worst cases for a 16_000-char slice:\n * backslashes / astral emoji → 32,073 bytes\n * Korean (3-byte, unescaped) → 48,073 bytes ← densest observed\n * plain ASCII → 16,073 bytes\n * All are under MESH_MAX_INLINE_FRAME_BYTES. `splitMeshFrame` still MEASURES each\n * envelope and shrinks on overflow, so the guarantee is enforced rather than assumed\n * if either constant is ever retuned — but at these values that path is unreachable,\n * which is exactly what `assertMeshChunkConstantsAreSafe` pins down.\n */\nexport const MESH_CHUNK_PAYLOAD_CHARS = 16_000\n\n/**\n * Hard cap on chunk count for one frame. 1024 × ~16KB ≈ 16MB of transferable payload,\n * which comfortably covers a screenshot while bounding what a single peer can make the\n * receiver buffer. Exceeding it is an explicit refusal, never a truncated send.\n */\nexport const MESH_MAX_CHUNKS = 1024\n\n/**\n * Reassembly budget for one frame, in bytes. Bounds receiver memory independently of\n * chunk count so a peer cannot send 1024 maximally-large chunks to force an oversized\n * allocation. Mirrors the dashboard receiver's MAX_REASSEMBLED_JSON_BYTES.\n */\nexport const MESH_MAX_REASSEMBLED_BYTES = 16_000_000\n\n/**\n * How long a partially-received frame is retained. A sender that dies mid-stream must\n * not pin receiver memory forever; the partial is swept and the frame simply never\n * completes (the RPC's own deadline then reports it).\n */\nexport const MESH_CHUNK_TTL_MS = 60_000\n\n/** Envelope `kind` for a chunk of a larger mesh frame. */\nexport const MESH_CHUNK_KIND = 'rpc_chunk'\n\nexport interface MeshChunkEnvelope {\n v: number\n kind: typeof MESH_CHUNK_KIND\n /** Groups the chunks of one logical frame. */\n chunkId: string\n /** 0-based position of this chunk. */\n index: number\n /** Total chunk count for this frame; constant across the group. */\n total: number\n /** The slice of the original envelope JSON. */\n data: string\n}\n\nexport type MeshChunkSplitResult =\n | { ok: true; chunks: MeshChunkEnvelope[] }\n | { ok: false; reason: 'too_many_chunks' | 'chunk_too_large'; detail: string }\n\nexport type MeshChunkAcceptResult =\n /** Chunk stored; the frame is not complete yet. */\n | { status: 'partial'; received: number; total: number }\n /** Final chunk landed and the frame parsed cleanly. */\n | { status: 'complete'; frame: unknown }\n /** Explicitly rejected — the caller must surface this, never ignore it. */\n | { status: 'failed'; reason: MeshChunkFailureReason; detail: string; chunkId: string }\n\nexport type MeshChunkFailureReason =\n | 'malformed_chunk'\n | 'too_many_chunks'\n | 'inconsistent_total'\n | 'duplicate_chunk_mismatch'\n | 'budget_exceeded'\n | 'reassembled_parse_failed'\n\n/** UTF-8 byte length without assuming Buffer or TextEncoder is present. */\nexport function meshUtf8ByteLength(value: string): number {\n if (typeof TextEncoder !== 'undefined') return new TextEncoder().encode(value).byteLength\n let bytes = 0\n for (let i = 0; i < value.length; i += 1) {\n const code = value.charCodeAt(i)\n if (code < 0x80) bytes += 1\n else if (code < 0x800) bytes += 2\n else if (code >= 0xd800 && code <= 0xdbff) { bytes += 4; i += 1 }\n else bytes += 3\n }\n return bytes\n}\n\n/**\n * Worst-case size of one chunk envelope at the current constants.\n *\n * Exported so the safety margin documented on MESH_CHUNK_PAYLOAD_CHARS is a CHECKED\n * invariant rather than a comment that rots. The densest slice the splitter can produce\n * is 3-byte unescaped text (JSON.stringify leaves non-ASCII as-is), so that is what this\n * measures. If someone raises MESH_CHUNK_PAYLOAD_CHARS or lowers the frame ceiling past\n * the safe point, the accompanying test fails loudly instead of the overflow only\n * showing up as dropped frames on a live mesh.\n */\nexport function measureWorstCaseChunkEnvelopeBytes(): number {\n const densest = '한'.repeat(MESH_CHUNK_PAYLOAD_CHARS)\n return meshUtf8ByteLength(JSON.stringify(\n buildChunkEnvelope(Number.MAX_SAFE_INTEGER, 'x'.repeat(64), MESH_MAX_CHUNKS, MESH_MAX_CHUNKS, densest),\n ))\n}\n\n/** True when the serialized frame must be chunked rather than sent inline. */\nexport function meshFrameNeedsChunking(json: string): boolean {\n return meshUtf8ByteLength(json) > MESH_MAX_INLINE_FRAME_BYTES\n}\n\nfunction buildChunkEnvelope(\n version: number, chunkId: string, index: number, total: number, data: string,\n): MeshChunkEnvelope {\n return { v: version, kind: MESH_CHUNK_KIND, chunkId, index, total, data }\n}\n\n/**\n * Split a serialized mesh envelope into chunk envelopes.\n *\n * Each slice is measured AS ITS FINAL SERIALIZED ENVELOPE and shrunk (×0.8, as in the\n * dashboard implementation) until it fits the inline ceiling — so multi-byte UTF-8 and\n * the envelope overhead are both accounted for rather than assumed away. `total` is\n * stamped only after the full split is known, so every chunk in a group agrees.\n */\nexport function splitMeshFrame(json: string, chunkId: string, version: number): MeshChunkSplitResult {\n const slices: string[] = []\n let offset = 0\n while (offset < json.length) {\n let end = Math.min(json.length, offset + MESH_CHUNK_PAYLOAD_CHARS)\n // Measure against MESH_MAX_CHUNKS as the `total` placeholder: it is the widest the\n // field can serialize to, so a slice that fits here still fits once the real (never\n // larger) total is stamped in below.\n while (end > offset) {\n const candidate = json.slice(offset, end)\n const probe = JSON.stringify(buildChunkEnvelope(version, chunkId, slices.length, MESH_MAX_CHUNKS, candidate))\n if (meshUtf8ByteLength(probe) <= MESH_MAX_INLINE_FRAME_BYTES) break\n const shrunk = Math.max(1, Math.floor((end - offset) * 0.8))\n if (offset + shrunk >= end) { end -= 1; continue }\n end = offset + shrunk\n }\n if (end <= offset) {\n return { ok: false, reason: 'chunk_too_large', detail: 'a single character did not fit the chunk envelope budget' }\n }\n slices.push(json.slice(offset, end))\n if (slices.length > MESH_MAX_CHUNKS) {\n return {\n ok: false,\n reason: 'too_many_chunks',\n detail: `frame needs more than ${MESH_MAX_CHUNKS} chunks (${meshUtf8ByteLength(json)} bytes)`,\n }\n }\n offset = end\n }\n if (slices.length === 0) {\n return { ok: false, reason: 'chunk_too_large', detail: 'refusing to chunk an empty frame' }\n }\n const total = slices.length\n return { ok: true, chunks: slices.map((data, index) => buildChunkEnvelope(version, chunkId, index, total, data)) }\n}\n\ninterface MeshChunkBuffer {\n total: number\n chunks: string[]\n received: number\n bytesReceived: number\n createdAt: number\n}\n\n/**\n * Receiver-side reassembly buffer, one per peer connection.\n *\n * Keyed by chunkId only — callers construct one assembler per peer, so chunk groups\n * from different peers can never collide in the same map.\n */\nexport class MeshChunkAssembler {\n private readonly buffers = new Map<string, MeshChunkBuffer>()\n\n constructor(private readonly now: () => number = () => Date.now()) {}\n\n /** True when the frame is a chunk envelope this assembler should handle. */\n static isChunkFrame(frame: unknown): boolean {\n return !!frame && typeof frame === 'object' && (frame as { kind?: unknown }).kind === MESH_CHUNK_KIND\n }\n\n /** Drop partials older than the TTL so a dead sender cannot pin memory. */\n private sweep(): void {\n const now = this.now()\n for (const [key, entry] of Array.from(this.buffers.entries())) {\n if (now - entry.createdAt > MESH_CHUNK_TTL_MS) this.buffers.delete(key)\n }\n }\n\n /** Discard any partial state for a peer (call on disconnect). */\n reset(): void {\n this.buffers.clear()\n }\n\n /** Number of frames currently mid-reassembly — for tests and diagnostics. */\n get pendingCount(): number {\n return this.buffers.size\n }\n\n /**\n * Accept one chunk envelope.\n *\n * Never throws and never returns a partially-applied frame: the result is exactly one\n * of partial / complete / failed, and `failed` carries a typed reason the transport\n * turns into an explicit RPC error.\n */\n accept(frame: unknown): MeshChunkAcceptResult {\n this.sweep()\n const raw = frame as Partial<MeshChunkEnvelope> | null\n const chunkId = typeof raw?.chunkId === 'string' ? raw.chunkId : ''\n const index = Number(raw?.index)\n const total = Number(raw?.total)\n const data = typeof raw?.data === 'string' ? raw.data : ''\n\n if (!chunkId || !Number.isInteger(index) || !Number.isInteger(total)\n || index < 0 || total <= 0 || index >= total || !data) {\n return {\n status: 'failed',\n reason: 'malformed_chunk',\n detail: `malformed chunk envelope (chunkId=${chunkId || '-'} index=${raw?.index} total=${raw?.total})`,\n chunkId,\n }\n }\n if (total > MESH_MAX_CHUNKS) {\n this.buffers.delete(chunkId)\n return {\n status: 'failed',\n reason: 'too_many_chunks',\n detail: `chunk total ${total} exceeds the ${MESH_MAX_CHUNKS} cap`,\n chunkId,\n }\n }\n\n let entry = this.buffers.get(chunkId)\n if (!entry) {\n entry = { total, chunks: new Array(total).fill(''), received: 0, bytesReceived: 0, createdAt: this.now() }\n this.buffers.set(chunkId, entry)\n } else if (entry.total !== total) {\n // The sender disagrees with itself about the frame's shape — the stream is\n // corrupt; drop it loudly rather than reassembling a mixed frame.\n this.buffers.delete(chunkId)\n return {\n status: 'failed',\n reason: 'inconsistent_total',\n detail: `chunk ${index} declares total ${total} but the group was opened with ${entry.total}`,\n chunkId,\n }\n }\n\n const existing = entry.chunks[index]\n if (existing) {\n // A benign retransmit repeats identical bytes. Different bytes for the same slot\n // means the ordering/identity guarantee is broken — refuse instead of picking one.\n if (existing === data) return { status: 'partial', received: entry.received, total: entry.total }\n this.buffers.delete(chunkId)\n return {\n status: 'failed',\n reason: 'duplicate_chunk_mismatch',\n detail: `chunk ${index} arrived twice with different content`,\n chunkId,\n }\n }\n\n const chunkBytes = meshUtf8ByteLength(data)\n if (entry.bytesReceived + chunkBytes > MESH_MAX_REASSEMBLED_BYTES) {\n this.buffers.delete(chunkId)\n return {\n status: 'failed',\n reason: 'budget_exceeded',\n detail: `reassembled frame would exceed ${MESH_MAX_REASSEMBLED_BYTES} bytes`,\n chunkId,\n }\n }\n\n entry.chunks[index] = data\n entry.received += 1\n entry.bytesReceived += chunkBytes\n if (entry.received < entry.total) {\n return { status: 'partial', received: entry.received, total: entry.total }\n }\n\n this.buffers.delete(chunkId)\n try {\n return { status: 'complete', frame: JSON.parse(entry.chunks.join('')) }\n } catch (error) {\n // Every slot is filled yet the join is not valid JSON — the frame is unusable.\n // Explicit failure, never a silent drop.\n return {\n status: 'failed',\n reason: 'reassembled_parse_failed',\n detail: `reassembled frame is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,\n chunkId,\n }\n }\n }\n}\n","/**\n * Semver precedence comparison — the single version-ordering primitive for the\n * daemon's upgrade paths.\n *\n * Why this exists: the upgrade path used to decide \"is this a no-op?\" with a\n * raw string equality check (`currentInstalled === latest`) and nothing else.\n * Equality answers \"is it the same version?\" but never \"which one is newer?\",\n * so any target that merely differed from the running build was installed —\n * including one that is OLDER. That is how a node running `1.0.49-rc.2`\n * silently got rolled back to `1.0.48`.\n *\n * String comparison cannot fix it either: `'1.0.49-rc.2' < '1.0.48'` is TRUE\n * lexicographically (the '4' in \"-rc.2\"'s prefix never gets that far — '9' vs\n * '8' at index 4 decides it, and even where it works `rc.10` sorts below\n * `rc.9`). Only field-wise numeric comparison with semver §11 prerelease rules\n * gives the right answer.\n *\n * This module is a PURE LEAF: zero imports, no I/O. It lives in mesh-shared\n * (fragmentation audit) so BOTH the OSS daemon and the proprietary Workers\n * server (`packages/server/src/utils/version-policy.ts`, previously a\n * byte-identical independent copy) can consume ONE implementation — the two\n * gate the same auto-update decision from opposite ends, and a drift between\n * them can produce an unbreakable update-nag loop (server says behind, daemon\n * gate refuses the \"upgrade\" as a rollback). daemon-core re-exports this from\n * its original `version-compare.ts` path, so existing imports keep working.\n *\n * NOTE ON PRERELEASE SEMANTICS: this is STRICT semver §11 — `1.0.49-rc.2` is\n * BELOW `1.0.49`, because a prerelease precedes its own release. That is the\n * correct rule for \"would installing this move me backwards?\", which is the\n * only question this module is used to answer. It deliberately differs from\n * `oss/packages/web-core/src/utils/version-update.ts`, whose\n * `isDaemonBehindTarget` treats an rc as up-to-date against its own base\n * release so the dashboard does not nag preview users with an update banner.\n * Those are two different questions; do not collapse them into one helper.\n */\n\n/** Parsed semver fields. Build metadata (`+…`) is discarded: it never affects precedence (§10). */\nexport interface ParsedSemver {\n readonly major: number;\n readonly minor: number;\n readonly patch: number;\n /** Dot-separated prerelease identifiers; empty for a release build. */\n readonly prerelease: readonly string[];\n}\n\nconst SEMVER_PATTERN = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/;\nconst NUMERIC_IDENTIFIER = /^\\d+$/;\n\n/**\n * Parse a semver string, tolerating a leading `v` (npm/CLI output carries it\n * inconsistently). Returns null for anything unparsable so callers can fail\n * closed rather than guess.\n */\nexport function parseSemver(version: unknown): ParsedSemver | null {\n if (typeof version !== 'string') return null;\n const match = version.trim().replace(/^v/, '').match(SEMVER_PATTERN);\n if (!match) return null;\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3]),\n prerelease: match[4] ? match[4].split('.') : [],\n };\n}\n\n/**\n * Semver §11 prerelease precedence: a release outranks its own prereleases;\n * numeric identifiers compare numerically (so rc.10 > rc.9) and rank below\n * alphanumeric ones; alphanumerics compare lexically; a shorter identifier\n * list ranks below an otherwise-equal longer one.\n */\nfunction comparePrerelease(a: readonly string[], b: readonly string[]): number {\n if (a.length === 0 && b.length === 0) return 0;\n // An empty prerelease list means \"release build\", which outranks any prerelease.\n if (a.length === 0) return 1;\n if (b.length === 0) return -1;\n for (let i = 0; i < Math.min(a.length, b.length); i += 1) {\n const idA = a[i];\n const idB = b[i];\n if (idA === idB) continue;\n const numA = NUMERIC_IDENTIFIER.test(idA);\n const numB = NUMERIC_IDENTIFIER.test(idB);\n if (numA && numB) return Number(idA) < Number(idB) ? -1 : 1;\n if (numA) return -1;\n if (numB) return 1;\n return idA < idB ? -1 : 1;\n }\n return a.length === b.length ? 0 : (a.length < b.length ? -1 : 1);\n}\n\n/**\n * Compare two versions by semver precedence.\n *\n * @returns -1 when `a` precedes `b`, 0 when equal, 1 when `a` succeeds `b`, and\n * **null when either side is unparsable** — callers MUST treat null as\n * \"direction unknown\" and fail closed rather than coercing it to a number\n * (`null` compares as `0` in JS numeric contexts, which would read as \"equal\").\n */\nexport function compareSemver(a: unknown, b: unknown): number | null {\n const pa = parseSemver(a);\n const pb = parseSemver(b);\n if (!pa || !pb) return null;\n if (pa.major !== pb.major) return pa.major < pb.major ? -1 : 1;\n if (pa.minor !== pb.minor) return pa.minor < pb.minor ? -1 : 1;\n if (pa.patch !== pb.patch) return pa.patch < pb.patch ? -1 : 1;\n return comparePrerelease(pa.prerelease, pb.prerelease);\n}\n\n/**\n * Would installing `target` move a daemon currently on `current` BACKWARDS?\n *\n * Returns false when the direction cannot be established (either version\n * unparsable) — an unknown direction must never block an upgrade, because the\n * cost of a false block (the whole fleet can no longer be upgraded) is far\n * higher than the cost of a missed downgrade guard. Equal versions are NOT a\n * downgrade, so a same-version reinstall stays allowed.\n */\nexport function isDowngrade(current: unknown, target: unknown): boolean {\n const direction = compareSemver(target, current);\n if (direction === null) return false;\n return direction < 0;\n}\n","/**\n * protocol/envelope — helpers shared by the three link protocols.\n *\n * Wiring-unification Phase A2 (docs/design/2026-09-23-wiring-unification.md).\n *\n * Every link (daemon↔server WS, dashboard↔UserSession WS, dashboard↔daemon\n * P2P DataChannel) is described the same way:\n *\n * - a `const` tuple of message-kind names per direction;\n * - a discriminated union of `{ type, ... }` frames derived from it;\n * - a `decode<Link><Direction>(raw)` parse-boundary function that checks the\n * `type` is a member and the frame carries the MINIMAL shape the union\n * promises (an object payload where one is required, the top-level fields\n * a payload-less frame is keyed by). Semantic validation — is this session\n * id known, is the SDP well formed — stays with the handler that owns it.\n *\n * mesh-shared is a dependency-free leaf, so payload types here are STRUCTURAL\n * mirrors of the richer daemon-core types (`RoutingSessionEntry`,\n * `DaemonStatusEventPayload`, ...): daemon-core, the server and the web assign\n * their richer types into these, never the other way round. A type-only import\n * of daemon-core would make the published `.d.ts` of this package reference a\n * package that depends on it — a cycle a leaf must not create.\n */\n\nexport type MessageId = string\n\n/** `{ type, payload }` frame with the optional correlation/ordering fields every link uses. */\nexport type Envelope<T extends string, P> = {\n type: T\n payload: P\n id?: MessageId\n timestamp?: number\n}\n\n/** Genuinely dynamic payloads (command arguments and results). Allowed by design; the union stays exhaustive on `type`. */\nexport type CommandPayload = Record<string, unknown>\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport function isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0\n}\n\nexport function isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n\nexport function makeTypeGuard<T extends readonly string[]>(names: T): (value: unknown) => value is T[number] {\n const set: ReadonlySet<string> = new Set(names)\n return (value: unknown): value is T[number] => typeof value === 'string' && set.has(value)\n}\n\n/**\n * Compile-time proof that a name tuple and a union have exactly the same\n * members. Used as `const _: AssertSameMembers<typeof NAMES, Union> = true`.\n */\nexport type AssertSameMembers<Tuple extends readonly string[], Union extends string> =\n [Exclude<Union, Tuple[number]>, Exclude<Tuple[number], Union>] extends [never, never] ? true : never\n\n/** Narrow a frame's `type` to a union member, or null. */\nexport function decodeTypeField<T extends string>(raw: unknown, isType: (value: unknown) => value is T): { type: T; frame: Record<string, unknown> } | null {\n if (!isRecord(raw)) return null\n if (!isType(raw.type)) return null\n return { type: raw.type, frame: raw }\n}\n\n/** Read the optional envelope fields a frame may carry, dropping malformed ones. */\nexport function readEnvelopeFields(frame: Record<string, unknown>): { id?: MessageId; timestamp?: number } {\n return {\n ...(isNonEmptyString(frame.id) ? { id: frame.id } : {}),\n ...(isFiniteNumber(frame.timestamp) ? { timestamp: frame.timestamp } : {}),\n }\n}\n","/**\n * protocol/daemon-server — the daemon ↔ Workers-server WebSocket link.\n *\n * Wiring-unification Phase A2 (docs/design/2026-09-23-wiring-unification.md §3 A2).\n *\n * Before this file the link shared NAME lists only (`ws-protocol.ts`), payloads\n * were `any` on both ends, `daemon_mesh_command` was sent by a raw `ws.send`\n * outside the typed funnel, and the P2P signaling names in the shared list\n * (`offer|answer|ice`) had drifted from the wire (`p2p_offer|p2p_answer|p2p_ice`)\n * without anything noticing, because nothing imported them.\n *\n * Two directions:\n * - `DaemonToServerMsg` — every frame the daemon writes to the server WS.\n * - `ServerToDaemonMsg` — every frame the server writes to a daemon WS. This\n * is a CLOSED control set plus one OPEN namespace: the public REST API\n * (`POST /api/v1/daemons/:id/command`, `daemonCommandSchema` = any string)\n * relays a caller-chosen command name as the frame `type`, so that member is\n * typed with a branded string rather than a literal list. The brand is what\n * keeps `msg.type === 'auth_ok'` narrowing to the control member instead of\n * collapsing into \"some string\".\n *\n * Payloads are structural mirrors of the daemon-core types the two ends assign\n * into them (see ./envelope.ts for why mesh-shared cannot import daemon-core).\n */\n\nimport type { AuthOkPlanLimits } from '../ws-protocol'\nimport type { SessionStatus } from '../session-status'\nimport {\n type CommandPayload,\n type Envelope,\n type MessageId,\n type AssertSameMembers,\n isRecord,\n isNonEmptyString,\n makeTypeGuard,\n readEnvelopeFields,\n} from './envelope'\n\n// ─── Status events (mirror of daemon-core `DaemonStatusEventName`) ─────────\n\n/**\n * Daemon-originated status events. The daemon relays these to the server\n * (push notifications, webhooks) AND over P2P (dashboard). Mirror of\n * daemon-core `DaemonStatusEventName`; the server pins the two equal at compile\n * time (UserSession.ts), so adding a member here without adding it there — or\n * vice versa — fails `tsc`.\n */\nexport const DAEMON_STATUS_EVENT_NAMES = [\n 'agent:generating_started',\n 'agent:waiting_approval',\n 'agent:waiting_choice',\n 'agent:generating_completed',\n 'agent:stopped',\n 'monitor:no_progress',\n] as const\nexport type DaemonStatusEventName = typeof DAEMON_STATUS_EVENT_NAMES[number]\nexport const isDaemonStatusEventName = makeTypeGuard(DAEMON_STATUS_EVENT_NAMES)\n\n/**\n * Server-bound status event. Content boundary: identifiers, enums, counters\n * and booleans only — plus the approved approval-modal exception\n * (`modalMessage`/`modalButtons`, CLAUDE.md \"Push notification exception\").\n * Mirror of daemon-core `DaemonStatusEventPayload`.\n */\nexport type DaemonStatusEventWirePayload = {\n event: DaemonStatusEventName\n timestamp: number\n targetSessionId?: string\n providerType?: string\n providerSessionId?: string\n workspaceName?: string\n duration?: number\n elapsedSec?: number\n modalMessage?: string\n modalButtons?: string[]\n surfaceHidden?: boolean\n muted?: boolean\n}\n\n// ─── Status report (mirror of daemon-core `CloudStatusReportPayload`) ──────\n\n/** Routing-only session entry the daemon reports over the server WS. Mirror of daemon-core `RoutingSessionEntry`. */\nexport type RoutingSessionWireEntry = {\n id: string\n parentId: string | null\n providerType: string\n providerName: string\n kind: string\n transport: string\n status: SessionStatus\n workspace: string | null\n cdpConnected?: boolean\n surfaceHidden?: boolean\n muted?: boolean\n}\n\n/** Counters and enums only — never a peer id or address. Mirror of daemon-core `P2PStatusSummary`. */\nexport type P2PStatusWireSummary = {\n available: boolean\n state: string\n peers: number\n screenshotActive?: boolean\n direct?: number\n relay?: number\n unknownTransport?: number\n directTotal?: number\n relayTotal?: number\n}\n\n/**\n * seqscribe replication health — pre-bucketed counters and booleans only,\n * never a topic name or peer id. Mirror of daemon-core `SeqscribeStatusSummary`\n * (which should derive from this once shared-types is on the protocol).\n */\nexport type SeqscribeStatusWireSummary = {\n topics: number\n peers: number\n peersReady: number\n pendingBucket: number\n consumerLagBucket: number\n queueBucket: number\n fgenAgeBucket: number\n quarantined: boolean\n authority: boolean\n transcriptPublish?: boolean\n transcriptPublishedBucket?: number\n transcriptPublishFailedBucket?: number\n transcriptDedupedBucket?: number\n transcriptOversizedBucket?: number\n transcriptDroppedBucket?: number\n}\n\nexport type CloudStatusReportWirePayload = {\n sessions: RoutingSessionWireEntry[]\n p2p?: P2PStatusWireSummary\n seqscribe?: SeqscribeStatusWireSummary\n timestamp: number\n}\n\n// ─── Release / update vocabulary (mirror of daemon-core shared-types) ──────\n\nexport const RELEASE_CHANNELS = ['stable', 'preview'] as const\nexport type ReleaseChannelWire = typeof RELEASE_CHANNELS[number]\nexport const NPM_UPDATE_TAGS = ['latest', 'next'] as const\nexport type NpmUpdateTagWire = typeof NPM_UPDATE_TAGS[number]\nexport const VERSION_UPDATE_REASONS = ['force_update_below', 'major_minor_mismatch', 'patch_mismatch', 'daemon_ahead'] as const\nexport type VersionUpdateReasonWire = typeof VERSION_UPDATE_REASONS[number]\n\n/** Mirror of daemon-core `VersionUpdatePolicy`. */\nexport type VersionUpdatePolicyWire = {\n channel: ReleaseChannelWire\n npmTag: NpmUpdateTagWire\n targetVersion: string\n minVersion?: string\n updateCommand: string\n}\n\nexport type StatusHeartbeatWirePayload = {\n timestamp?: number\n p2pPeers?: number\n}\n\n// ─── Auth ──────────────────────────────────────────────────────────────────\n\n/** What the daemon says about itself at auth time (`ServerConnectionOptions.cliInfo`). */\nexport type DaemonAuthIdentity = {\n type: string\n version: string\n platform: string\n hostname?: string\n machineId?: string\n /** Canonical mesh identity `daemon_<machineId>`; the server keys its DO and status by it. */\n instanceId: string\n}\n\nexport type DaemonAuthWirePayload = {\n token: string\n daemon: DaemonAuthIdentity\n}\n\nexport type IceServerWireEntry = {\n urls: string | string[]\n username?: string\n credential?: string\n}\n\nexport type AuthOkWirePayload = {\n message?: string\n plan: string\n iceServers: IceServerWireEntry[]\n turnenabled: boolean\n serverVersion: string\n releaseChannel?: ReleaseChannelWire\n updatePolicy?: VersionUpdatePolicyWire\n machineNickname: string | null\n seqscribeFleetSecret?: string\n seqscribeFleetSecretVersion?: number\n limits: AuthOkPlanLimits\n}\n\nexport type AuthErrorWirePayload = {\n reason: string\n message: string\n limit?: number\n current?: number\n}\n\n/** `machine_evicted` / `force_disconnect` / `token_revoked` — a reason token plus human text, then the socket closes. */\nexport type DisconnectNoticeWirePayload = {\n reason: string\n message: string\n}\n\nexport type VersionMismatchWirePayload = {\n current: string\n latest: string\n required: false\n reason: VersionUpdateReasonWire\n channel: ReleaseChannelWire\n npmTag: NpmUpdateTagWire\n updatePolicy: VersionUpdatePolicyWire\n updateCommand: string\n}\n\nexport type ForceUpdateRequiredWirePayload = {\n current: string\n latest: string\n minVersion: string\n required: true\n reason: VersionUpdateReasonWire\n channel: ReleaseChannelWire\n npmTag: NpmUpdateTagWire\n updatePolicy: VersionUpdatePolicyWire\n updateCommand: string\n forceUpdateBelow?: string\n message: string\n}\n\n// ─── Commands and results ──────────────────────────────────────────────────\n\nexport type CommandResultWirePayload = {\n requestId: MessageId\n success: boolean\n source?: string\n} & Record<string, unknown>\n\nexport type DaemonErrorWirePayload = {\n message?: string\n detail?: unknown\n}\n\n// ─── P2P signaling (dashboard ↔ daemon through the server) ─────────────────\n\nexport const P2P_SIGNAL_TYPES = ['p2p_ready', 'p2p_offer', 'p2p_answer', 'p2p_ice'] as const\nexport type P2PSignalType = typeof P2P_SIGNAL_TYPES[number]\nexport const isP2PSignalType = makeTypeGuard(P2P_SIGNAL_TYPES)\n\n/** Signals the daemon originates (it is the WebRTC offerer). */\nexport const DAEMON_P2P_SIGNAL_TYPES = ['p2p_offer', 'p2p_ice'] as const\nexport type DaemonP2PSignalType = typeof DAEMON_P2P_SIGNAL_TYPES[number]\nexport const isDaemonP2PSignalType = makeTypeGuard(DAEMON_P2P_SIGNAL_TYPES)\n\nexport type P2POfferWirePayload = { sdp: string; type: string; peerId: string }\nexport type P2PIceWirePayload = { candidate: string; mid: string; peerId: string }\n\n/**\n * A dashboard-originated signal as relayed to the daemon. `peerId` is stamped\n * by UserSession/SharedSession, `sharePermission` and `shareTargetSessionId`\n * (the one session a share link may see) only by SharedSession (server\n * authority, never the client). Field names follow the browser/node-datachannel\n * spellings both ends already read.\n */\nexport type RelayedP2PSignalWirePayload = {\n peerId?: string\n daemonId?: string\n sharePermission?: string\n shareTargetSessionId?: string\n sdp?: string\n type?: string\n candidate?: string\n mid?: string\n sdpMid?: string | null\n sdpMLineIndex?: number | null\n}\n\nexport const MESH_P2P_SIGNAL_TYPES = ['mesh_p2p_ready', 'mesh_p2p_offer', 'mesh_p2p_answer', 'mesh_p2p_ice'] as const\nexport type MeshP2PSignalType = typeof MESH_P2P_SIGNAL_TYPES[number]\nexport const isMeshP2PSignalType = makeTypeGuard(MESH_P2P_SIGNAL_TYPES)\n\n/** Daemon→daemon signal as delivered to the target daemon: the sender's args plus the server-stamped canonical sender id. */\nexport type MeshP2PSignalWirePayload = { senderDaemonId: string } & Record<string, unknown>\n\n// ─── Daemon → Server ───────────────────────────────────────────────────────\n\nexport const DAEMON_TO_SERVER_TYPES = [\n 'auth',\n 'status_report',\n 'status_heartbeat',\n 'status_event',\n 'command_result',\n 'error',\n 'agent_event',\n 'daemon_mesh_command',\n 'p2p_offer',\n 'p2p_ice',\n] as const\nexport type DaemonToServerType = typeof DAEMON_TO_SERVER_TYPES[number]\nexport const isDaemonToServerType = makeTypeGuard(DAEMON_TO_SERVER_TYPES)\n\nexport type DaemonAuthMsg = Envelope<'auth', DaemonAuthWirePayload>\nexport type StatusReportMsg = Envelope<'status_report', CloudStatusReportWirePayload>\nexport type StatusHeartbeatMsg = Envelope<'status_heartbeat', StatusHeartbeatWirePayload>\nexport type DaemonStatusEventMsg = Envelope<'status_event', DaemonStatusEventWirePayload>\nexport type CommandResultMsg = Envelope<'command_result', CommandResultWirePayload>\nexport type DaemonErrorMsg = Envelope<'error', DaemonErrorWirePayload>\n/** Agent-level event forwarded verbatim to the `agent:status` webhook (throttled server-side). Dynamic by design. */\nexport type AgentEventMsg = Envelope<'agent_event', CommandPayload>\nexport type DaemonP2POfferMsg = Envelope<'p2p_offer', P2POfferWirePayload>\nexport type DaemonP2PIceMsg = Envelope<'p2p_ice', P2PIceWirePayload>\n/**\n * Daemon→daemon signaling relay request. Fields are TOP-LEVEL (no `payload`):\n * this is the wire shape the live fleet speaks, kept as-is so mixed-version\n * daemons and servers keep interoperating during a rollout.\n */\nexport type DaemonMeshCommandMsg = {\n type: 'daemon_mesh_command'\n requestId: string\n targetDaemonId: string\n command: MeshP2PSignalType\n args: Record<string, unknown>\n timestamp: number\n}\n\nexport type DaemonToServerMsg =\n | DaemonAuthMsg\n | StatusReportMsg\n | StatusHeartbeatMsg\n | DaemonStatusEventMsg\n | CommandResultMsg\n | DaemonErrorMsg\n | AgentEventMsg\n | DaemonMeshCommandMsg\n | DaemonP2POfferMsg\n | DaemonP2PIceMsg\n\nconst _daemonToServerNamesCoverUnion: AssertSameMembers<typeof DAEMON_TO_SERVER_TYPES, DaemonToServerMsg['type']> = true\nvoid _daemonToServerNamesCoverUnion\n\n/** Members that carry a `payload` object (everything except `daemon_mesh_command`). */\nexport type DaemonToServerPayloadType = Exclude<DaemonToServerMsg, DaemonMeshCommandMsg>['type']\nexport type DaemonToServerPayloadOf<T extends DaemonToServerPayloadType> = Extract<DaemonToServerMsg, { type: T }>['payload']\n\n/**\n * Parse boundary for the server: is `raw` a frame this link accepts from a daemon?\n * Checks membership and the minimal envelope shape; `auth` additionally needs a\n * token string because nothing downstream can proceed without one.\n */\nexport function decodeDaemonToServer(raw: unknown): DaemonToServerMsg | null {\n if (!isRecord(raw) || !isDaemonToServerType(raw.type)) return null\n if (raw.type === 'daemon_mesh_command') {\n // Handler-side validation replies with a correlated `daemon_mesh_result`\n // error, so only the discriminant is checked here.\n return {\n type: 'daemon_mesh_command',\n requestId: typeof raw.requestId === 'string' ? raw.requestId : String(raw.requestId ?? ''),\n targetDaemonId: typeof raw.targetDaemonId === 'string' ? raw.targetDaemonId : '',\n command: raw.command as MeshP2PSignalType,\n args: isRecord(raw.args) ? raw.args : {},\n timestamp: typeof raw.timestamp === 'number' ? raw.timestamp : Date.now(),\n }\n }\n if (!isRecord(raw.payload)) return null\n if (raw.type === 'auth' && !isNonEmptyString(raw.payload.token)) return null\n return { type: raw.type, payload: raw.payload, ...readEnvelopeFields(raw) } as DaemonToServerMsg\n}\n\n// ─── Server → Daemon ───────────────────────────────────────────────────────\n\nexport const SERVER_TO_DAEMON_CONTROL_TYPES = [\n 'auth_ok',\n 'auth_error',\n 'machine_evicted',\n 'force_disconnect',\n 'token_revoked',\n 'version_mismatch',\n 'force_update_required',\n 'command',\n 'agent_command',\n 'resolve_action',\n 'daemon_mesh_result',\n 'p2p_ready',\n 'p2p_offer',\n 'p2p_answer',\n 'p2p_ice',\n 'mesh_p2p_ready',\n 'mesh_p2p_offer',\n 'mesh_p2p_answer',\n 'mesh_p2p_ice',\n] as const\nexport type ServerToDaemonControlType = typeof SERVER_TO_DAEMON_CONTROL_TYPES[number]\nexport const isServerToDaemonControlType = makeTypeGuard(SERVER_TO_DAEMON_CONTROL_TYPES)\n\n/** Optional routing fields the server stamps on relayed commands. */\ntype ServerRelayFields = { id?: MessageId; source?: string; timestamp?: number }\n\nexport type AuthOkMsg = Envelope<'auth_ok', AuthOkWirePayload>\nexport type AuthErrorMsg = Envelope<'auth_error', AuthErrorWirePayload>\nexport type MachineEvictedMsg = Envelope<'machine_evicted', DisconnectNoticeWirePayload>\nexport type ForceDisconnectMsg = Envelope<'force_disconnect', DisconnectNoticeWirePayload>\nexport type TokenRevokedMsg = Envelope<'token_revoked', DisconnectNoticeWirePayload>\nexport type VersionMismatchMsg = Envelope<'version_mismatch', VersionMismatchWirePayload>\nexport type ForceUpdateRequiredMsg = Envelope<'force_update_required', ForceUpdateRequiredWirePayload>\n/** Wrapped command: `payload.command` names the command, `payload.args` carries it. */\nexport type ServerCommandMsg = Envelope<'command', { command: string; args?: CommandPayload } & Record<string, unknown>> & ServerRelayFields\nexport type ServerAgentCommandMsg = Envelope<'agent_command', { action: string } & Record<string, unknown>> & ServerRelayFields\nexport type ServerResolveActionMsg = Envelope<'resolve_action', CommandPayload> & ServerRelayFields\nexport type ServerP2PSignalMsg = Envelope<P2PSignalType, RelayedP2PSignalWirePayload> & ServerRelayFields\nexport type ServerMeshP2PSignalMsg = Envelope<MeshP2PSignalType, MeshP2PSignalWirePayload> & ServerRelayFields\n/** Correlated ack/nack of a `daemon_mesh_command` (top-level, no payload). */\nexport type DaemonMeshResultMsg = {\n type: 'daemon_mesh_result'\n requestId: string\n success: boolean\n result?: unknown\n error?: string\n}\n\nexport type ServerToDaemonControlMsg =\n | AuthOkMsg\n | AuthErrorMsg\n | MachineEvictedMsg\n | ForceDisconnectMsg\n | TokenRevokedMsg\n | VersionMismatchMsg\n | ForceUpdateRequiredMsg\n | ServerCommandMsg\n | ServerAgentCommandMsg\n | ServerResolveActionMsg\n | DaemonMeshResultMsg\n | ServerP2PSignalMsg\n | ServerMeshP2PSignalMsg\n\nconst _serverToDaemonControlNamesCoverUnion: AssertSameMembers<typeof SERVER_TO_DAEMON_CONTROL_TYPES, ServerToDaemonControlMsg['type']> = true\nvoid _serverToDaemonControlNamesCoverUnion\n\ndeclare const directCommandBrand: unique symbol\n/**\n * A command name relayed as the frame `type` — the OPEN namespace the REST API\n * and `shortcuts` routes feed (`read_chat`, `send_chat`, `stop_cli`, `git_*`,\n * `clone_mesh_node`, `terminal_exec`, ...). The daemon routes it by name\n * through its command router. Branded so it cannot be confused with a control\n * member at the type level; `decodeServerToDaemon` is the only producer.\n */\nexport type DaemonDirectCommandType = string & { readonly [directCommandBrand]?: true }\n\nexport type ServerDirectCommandMsg = {\n type: DaemonDirectCommandType\n payload: CommandPayload\n id?: MessageId\n source?: string\n timestamp?: number\n}\n\nexport type ServerToDaemonMsg = ServerToDaemonControlMsg | ServerDirectCommandMsg\nexport type ServerToDaemonType = ServerToDaemonMsg['type']\n\nexport function isServerDirectCommandMsg(msg: ServerToDaemonMsg): msg is ServerDirectCommandMsg {\n return !isServerToDaemonControlType(msg.type)\n}\n\n/** Members of the control set that carry a `payload` object. */\nexport type ServerToDaemonPayloadType = Exclude<ServerToDaemonControlMsg, DaemonMeshResultMsg>['type']\nexport type ServerToDaemonPayloadOf<T extends ServerToDaemonPayloadType> = Extract<ServerToDaemonControlMsg, { type: T }>['payload']\n\n/** Command types a daemon must never receive as a direct command: they are daemon→server frames or reserved envelope words. */\nconst DIRECT_COMMAND_TYPE_PATTERN = /^[a-z][a-z0-9_:.-]{0,63}$/\n\nexport function isDaemonDirectCommandType(value: unknown): value is DaemonDirectCommandType {\n return typeof value === 'string' && DIRECT_COMMAND_TYPE_PATTERN.test(value) && !isServerToDaemonControlType(value)\n}\n\n/**\n * Parse boundary for the daemon: is `raw` a frame this link accepts from the server?\n * Control members are checked for their discriminant and envelope shape; the\n * payload-less `daemon_mesh_result` reply needs its `requestId`; any other well-formed\n * command name becomes a `ServerDirectCommandMsg`.\n */\nexport function decodeServerToDaemon(raw: unknown): ServerToDaemonMsg | null {\n if (!isRecord(raw) || typeof raw.type !== 'string') return null\n const relay = {\n ...readEnvelopeFields(raw),\n ...(isNonEmptyString(raw.source) ? { source: raw.source } : {}),\n }\n if (raw.type === 'daemon_mesh_result') {\n if (!isNonEmptyString(raw.requestId)) return null\n const base = { requestId: raw.requestId, success: raw.success === true }\n return {\n type: 'daemon_mesh_result',\n ...base,\n ...('result' in raw ? { result: raw.result } : {}),\n ...(typeof raw.error === 'string' ? { error: raw.error } : {}),\n }\n }\n if (!isRecord(raw.payload)) return null\n if (isServerToDaemonControlType(raw.type)) {\n return { type: raw.type, payload: raw.payload, ...relay } as ServerToDaemonControlMsg\n }\n if (!isDaemonDirectCommandType(raw.type)) return null\n return { type: raw.type, payload: raw.payload, ...relay }\n}\n","/**\n * protocol/dashboard-server — the dashboard ↔ UserSessionDO WebSocket link,\n * plus the share-viewer ↔ SharedSessionDO link the same dashboard bundle speaks.\n *\n * Wiring-unification Phase A2 (docs/design/2026-09-23-wiring-unification.md §3 A2).\n *\n * Before this file web-cloud `ws.ts` declared its own `IncomingWSMessage`\n * union and `WSEventType`, the server built every outbound frame as an object\n * literal, and the two disagreed: the server's `connected` frame was missing\n * from the dashboard's type, while the dashboard typed `plan_limit_error`,\n * `plan_limit_warning`, `daemon_screenshot` and `agent_event` that no server\n * path has emitted since the dashboard WS command relay was removed. Those four\n * are gone; `connected` is in.\n *\n * Content boundary: this link is server WS. It carries routing metadata,\n * signaling and the approved approval-modal text only (`modalMessage` /\n * `modalButtons`). Chat content rides the P2P link (./dashboard-daemon-p2p.ts).\n */\n\nimport {\n type Envelope,\n type AssertSameMembers,\n isRecord,\n makeTypeGuard,\n readEnvelopeFields,\n} from './envelope'\nimport {\n DAEMON_STATUS_EVENT_NAMES,\n type DaemonStatusEventName,\n type P2PIceWirePayload,\n type P2POfferWirePayload,\n type P2PStatusWireSummary,\n type SeqscribeStatusWireSummary,\n type ReleaseChannelWire,\n type VersionUpdatePolicyWire,\n type VersionUpdateReasonWire,\n} from './daemon-server'\n\n// ─── Status events as delivered to a dashboard ─────────────────────────────\n\n/** Server-originated events the dashboard receives in addition to the daemon set. */\nexport const SERVER_STATUS_EVENT_NAMES = [\n 'daemon:disconnect',\n 'team:session_viewed',\n 'team:view_request',\n 'team:view_request_approved',\n 'team:view_request_rejected',\n] as const\n\n/** Mirror of daemon-core `DashboardStatusEventName`; pinned equal by the server at compile time. */\nexport const DASHBOARD_STATUS_EVENT_NAMES = [...DAEMON_STATUS_EVENT_NAMES, ...SERVER_STATUS_EVENT_NAMES] as const\nexport type DashboardStatusEventName = DaemonStatusEventName | typeof SERVER_STATUS_EVENT_NAMES[number]\nexport const isDashboardStatusEventName = makeTypeGuard(DASHBOARD_STATUS_EVENT_NAMES)\n\nconst _dashboardStatusEventNamesCoverUnion: AssertSameMembers<typeof DASHBOARD_STATUS_EVENT_NAMES, DashboardStatusEventName> = true\nvoid _dashboardStatusEventNamesCoverUnion\n\n/**\n * Sanitized status event as the server relays it (UserSession\n * `buildDashboardStatusEvent`). Mirror of daemon-core\n * `DashboardStatusEventPayload` minus the P2P-only structured prompt fields\n * (`interactivePrompt`/`promptId`/`multiSelect`), which the WS relay never\n * carries — they are agent-authored content.\n */\nexport type DashboardStatusEventWirePayload = {\n event: DashboardStatusEventName\n timestamp: number\n daemonId?: string\n providerType?: string\n targetSessionId?: string\n duration?: number\n elapsedSec?: number\n modalMessage?: string\n modalButtons?: string[]\n requestId?: string\n requesterName?: string\n targetName?: string\n orgId?: string\n permission?: string\n shareUrl?: string\n shareToken?: string\n viewerName?: string\n}\n\n// ─── Bootstrap ─────────────────────────────────────────────────────────────\n\n/**\n * Cold-start machine card. Mirror of daemon-core `DashboardBootstrapDaemonEntry`\n * (which extends `Partial<CloudDaemonSummaryEntry>`), field for field, so the\n * server's entry assigns in and the dashboard's daemon-core-typed consumer\n * assigns out without a cast.\n */\nexport type BootstrapDaemonWireEntry = {\n id: string\n type?: string\n machineId?: string\n platform?: string\n hostname?: string\n nickname?: string\n version?: string\n p2p?: P2PStatusWireSummary\n seqscribe?: SeqscribeStatusWireSummary\n cdpConnected?: boolean\n serverVersion?: string\n releaseChannel?: ReleaseChannelWire\n updateChannel?: ReleaseChannelWire\n updatePolicy?: VersionUpdatePolicyWire\n updateCommand?: string\n versionMismatch?: boolean\n versionUpdateRequired?: boolean\n versionUpdateReason?: VersionUpdateReasonWire\n timestamp?: number\n}\n\nexport const SYSTEM_ANNOUNCEMENT_TYPES = ['info', 'warning', 'critical'] as const\nexport type SystemAnnouncementTypeWire = typeof SYSTEM_ANNOUNCEMENT_TYPES[number]\n\n/** Admin-authored banner; `null` clears it. Mirror of server `ActiveSystemAnnouncement` / web-cloud `SystemAnnouncement`. */\nexport type SystemAnnouncementWire = {\n id: string\n message: string\n type: SystemAnnouncementTypeWire\n createdAt: string | null\n expiresAt: string | null\n}\n\nexport type DashboardBootstrapWirePayload = {\n daemons: BootstrapDaemonWireEntry[]\n announcement?: SystemAnnouncementWire | null\n}\n\nexport type DashboardConnectedWirePayload = {\n message?: string\n peerId: string\n plan: string\n dashboardCount: number\n}\n\n/** Daemon auth rejection relayed to the owner's dashboards — enum reason and counters only (no server-authored sentence). */\nexport type DashboardAuthErrorWirePayload = {\n reason: string\n limit?: number\n current?: number\n}\n\nexport type SystemAnnouncementWirePayload = {\n announcement: SystemAnnouncementWire | null\n}\n\n// ─── Signaling payloads (server → dashboard, from the daemon offerer) ───────\n\nexport type DashboardP2POfferWirePayload = {\n daemonId: string\n peerId?: string\n sdp: string\n type: string\n}\n\nexport type DashboardP2PIceWirePayload = {\n daemonId: string\n peerId?: string\n candidate: string\n mid?: string\n sdpMid?: string | null\n sdpMLineIndex?: number | null\n}\n\n// ─── UserSession → Dashboard ───────────────────────────────────────────────\n\nexport const USER_SESSION_TO_DASHBOARD_TYPES = [\n 'connected',\n 'initial_state',\n 'daemon_status',\n 'status_event',\n 'system_announcement',\n 'auth_error',\n 'heartbeat',\n 'p2p_offer',\n 'p2p_ice',\n] as const\nexport type UserSessionToDashboardType = typeof USER_SESSION_TO_DASHBOARD_TYPES[number]\nexport const isUserSessionToDashboardType = makeTypeGuard(USER_SESSION_TO_DASHBOARD_TYPES)\n\nexport type DashboardConnectedMsg = Envelope<'connected', DashboardConnectedWirePayload>\nexport type DashboardInitialStateMsg = Envelope<'initial_state', DashboardBootstrapWirePayload>\nexport type DashboardDaemonStatusMsg = Envelope<'daemon_status', DashboardBootstrapWirePayload>\nexport type DashboardStatusEventMsg = Envelope<'status_event', DashboardStatusEventWirePayload>\nexport type DashboardSystemAnnouncementMsg = Envelope<'system_announcement', SystemAnnouncementWirePayload>\nexport type DashboardAuthErrorMsg = Envelope<'auth_error', DashboardAuthErrorWirePayload>\n/**\n * Reply to the dashboard's heartbeat. Carries the cached announcement so a\n * stale banner self-corrects; the field is optional because the reply is first\n * of all a liveness signal and must not be dropped by an older server's\n * payload-less spelling.\n */\nexport type DashboardHeartbeatReplyMsg = Envelope<'heartbeat', Partial<SystemAnnouncementWirePayload>>\nexport type DashboardP2POfferMsg = Envelope<'p2p_offer', DashboardP2POfferWirePayload>\nexport type DashboardP2PIceMsg = Envelope<'p2p_ice', DashboardP2PIceWirePayload>\n\nexport type UserSessionToDashboardMsg =\n | DashboardConnectedMsg\n | DashboardInitialStateMsg\n | DashboardDaemonStatusMsg\n | DashboardStatusEventMsg\n | DashboardSystemAnnouncementMsg\n | DashboardAuthErrorMsg\n | DashboardHeartbeatReplyMsg\n | DashboardP2POfferMsg\n | DashboardP2PIceMsg\n\nconst _userSessionToDashboardNamesCoverUnion: AssertSameMembers<typeof USER_SESSION_TO_DASHBOARD_TYPES, UserSessionToDashboardMsg['type']> = true\nvoid _userSessionToDashboardNamesCoverUnion\n\nexport type UserSessionToDashboardPayloadOf<T extends UserSessionToDashboardType> = Extract<UserSessionToDashboardMsg, { type: T }>['payload']\n\n/** Parse boundary for the dashboard. A heartbeat reply is accepted without a payload (liveness first). */\nexport function decodeUserSessionToDashboard(raw: unknown): UserSessionToDashboardMsg | null {\n if (!isRecord(raw) || !isUserSessionToDashboardType(raw.type)) return null\n if (raw.type === 'heartbeat') {\n return { type: 'heartbeat', payload: isRecord(raw.payload) ? raw.payload : {}, ...readEnvelopeFields(raw) }\n }\n if (!isRecord(raw.payload)) return null\n return { type: raw.type, payload: raw.payload, ...readEnvelopeFields(raw) } as UserSessionToDashboardMsg\n}\n\n// ─── Dashboard → UserSession ───────────────────────────────────────────────\n\nexport const DASHBOARD_TO_USER_SESSION_TYPES = ['heartbeat', 'refresh', 'p2p_ready', 'p2p_answer', 'p2p_ice'] as const\nexport type DashboardToUserSessionType = typeof DASHBOARD_TO_USER_SESSION_TYPES[number]\nexport const isDashboardToUserSessionType = makeTypeGuard(DASHBOARD_TO_USER_SESSION_TYPES)\n\n/** Signals a dashboard (answerer) sends toward a daemon; `daemonId` routes, `peerId` identifies the tab. */\nexport const DASHBOARD_P2P_SIGNAL_TYPES = ['p2p_ready', 'p2p_answer', 'p2p_ice'] as const\nexport type DashboardP2PSignalType = typeof DASHBOARD_P2P_SIGNAL_TYPES[number]\nexport const isDashboardP2PSignalType = makeTypeGuard(DASHBOARD_P2P_SIGNAL_TYPES)\n\nexport type DashboardP2PReadyWirePayload = { daemonId: string; peerId: string }\nexport type DashboardP2PAnswerWirePayload = { daemonId: string; peerId: string; sdp: string; type: string }\nexport type DashboardP2PLocalIceWirePayload = {\n daemonId: string\n peerId: string\n candidate: string\n sdpMid: string | null\n sdpMLineIndex: number | null\n}\n\nexport type DashboardHeartbeatMsg = { type: 'heartbeat'; timestamp?: number }\nexport type DashboardRefreshMsg = { type: 'refresh' }\nexport type DashboardP2PReadyMsg = Envelope<'p2p_ready', DashboardP2PReadyWirePayload>\nexport type DashboardP2PAnswerMsg = Envelope<'p2p_answer', DashboardP2PAnswerWirePayload>\nexport type DashboardP2PLocalIceMsg = Envelope<'p2p_ice', DashboardP2PLocalIceWirePayload>\n\nexport type DashboardToUserSessionMsg =\n | DashboardHeartbeatMsg\n | DashboardRefreshMsg\n | DashboardP2PReadyMsg\n | DashboardP2PAnswerMsg\n | DashboardP2PLocalIceMsg\n\nconst _dashboardToUserSessionNamesCoverUnion: AssertSameMembers<typeof DASHBOARD_TO_USER_SESSION_TYPES, DashboardToUserSessionMsg['type']> = true\nvoid _dashboardToUserSessionNamesCoverUnion\n\nexport type DashboardToUserSessionPayloadOf<T extends DashboardP2PSignalType> = Extract<DashboardToUserSessionMsg, { type: T }>['payload']\n\n/** Parse boundary for UserSessionDO. Signals need a `daemonId` to route; without one there is nothing to do. */\nexport function decodeDashboardToUserSession(raw: unknown): DashboardToUserSessionMsg | null {\n if (!isRecord(raw) || !isDashboardToUserSessionType(raw.type)) return null\n if (raw.type === 'heartbeat') return { type: 'heartbeat', ...readEnvelopeFields(raw) }\n if (raw.type === 'refresh') return { type: 'refresh' }\n if (!isRecord(raw.payload) || typeof raw.payload.daemonId !== 'string') return null\n return { type: raw.type, payload: raw.payload, ...readEnvelopeFields(raw) } as DashboardToUserSessionMsg\n}\n\n// ─── SharedSession ↔ share viewer ──────────────────────────────────────────\n\nexport const SHARED_SESSION_TO_VIEWER_TYPES = [\n 'share:connected',\n 'share:revoked',\n 'share:expired',\n 'share:error',\n 'share:viewer_count',\n 'p2p_offer',\n 'p2p_ice',\n] as const\nexport type SharedSessionToViewerType = typeof SHARED_SESSION_TO_VIEWER_TYPES[number]\nexport const isSharedSessionToViewerType = makeTypeGuard(SHARED_SESSION_TO_VIEWER_TYPES)\n\n/** Frames on this link are FLAT (no `payload`), except the relayed signals. Kept as the viewer page reads them. */\nexport type ShareConnectedMsg = {\n type: 'share:connected'\n viewerId: string\n viewerName: string\n permission: string\n mode: string\n providerType: string\n targetSessionId?: string\n ownerName: string\n daemonId: string\n iceServers: unknown[]\n requiresAuth: boolean\n}\nexport type ShareRevokedMsg = { type: 'share:revoked' }\nexport type ShareExpiredMsg = { type: 'share:expired' }\nexport type ShareErrorMsg = { type: 'share:error'; error: string }\nexport type ShareViewerCountMsg = { type: 'share:viewer_count'; count: number; maxViewers: number }\n/**\n * Daemon signal relayed to the addressed viewer, payload as the daemon sent it;\n * `from` is the daemon DO id, which the viewer page folds in as `daemonId`.\n */\nexport type ShareRelayedP2POfferMsg = { type: 'p2p_offer'; payload: P2POfferWirePayload; from: string }\nexport type ShareRelayedP2PIceMsg = { type: 'p2p_ice'; payload: P2PIceWirePayload; from: string }\n\nexport type SharedSessionToViewerMsg =\n | ShareConnectedMsg\n | ShareRevokedMsg\n | ShareExpiredMsg\n | ShareErrorMsg\n | ShareViewerCountMsg\n | ShareRelayedP2POfferMsg\n | ShareRelayedP2PIceMsg\n\nconst _sharedSessionToViewerNamesCoverUnion: AssertSameMembers<typeof SHARED_SESSION_TO_VIEWER_TYPES, SharedSessionToViewerMsg['type']> = true\nvoid _sharedSessionToViewerNamesCoverUnion\n\nexport const VIEWER_TO_SHARED_SESSION_TYPES = ['p2p_ready', 'p2p_offer', 'p2p_answer', 'p2p_ice'] as const\nexport type ViewerToSharedSessionType = typeof VIEWER_TO_SHARED_SESSION_TYPES[number]\nexport const isViewerToSharedSessionType = makeTypeGuard(VIEWER_TO_SHARED_SESSION_TYPES)\n\n/** The viewer's signal as sent; the DO stamps `daemonId`/`peerId`/`sharePermission` before relaying. */\nexport type ViewerToSharedSessionMsg = Envelope<ViewerToSharedSessionType, Record<string, unknown>>\n\nconst _viewerToSharedSessionNamesCoverUnion: AssertSameMembers<typeof VIEWER_TO_SHARED_SESSION_TYPES, ViewerToSharedSessionMsg['type']> = true\nvoid _viewerToSharedSessionNamesCoverUnion\n\n/** Parse boundary for SharedSessionDO: signaling frames only. */\nexport function decodeViewerToSharedSession(raw: unknown): ViewerToSharedSessionMsg | null {\n if (!isRecord(raw) || !isViewerToSharedSessionType(raw.type)) return null\n const payload = isRecord(raw.payload) ? raw.payload : {}\n return { type: raw.type, payload, ...readEnvelopeFields(raw) }\n}\n","/**\n * protocol/dashboard-daemon-p2p — the dashboard ↔ daemon WebRTC DataChannel\n * link (`data` channel, JSON frames; screenshots ride the same channel as\n * binary and are not frames).\n *\n * Wiring-unification Phase A2 (docs/design/2026-09-23-wiring-unification.md §3 A2).\n *\n * Before this file ~20 kinds were matched as bare string literals on both ends\n * (web-cloud `p2p.ts`, daemon-cloud `data-channel-router.ts`), the shared\n * `DashboardP2PMessageKind` listed 12 of them and was imported by nothing, and\n * the daemon's file-operation replies carried no `type` at all — the browser\n * matched them by `id` as a fallthrough. They are now `response` frames.\n *\n * Chunking: any request frame may be split by the sender into\n * `<kind>_chunk` frames (`id`, `chunkId`, `index`, `total`, `data`) when it\n * exceeds `MESH_MAX_INLINE_FRAME_BYTES` (../rpc-chunking.ts). Each direction\n * reassembles BEFORE decoding, so the decoders see whole frames; the chunk\n * envelope is typed here so the splitter and the reassembler agree.\n *\n * Content boundary: this is the P2P plane — rich session data (chat, prompts,\n * transcripts, PTY output) is CORRECT here and must not be reduced.\n */\n\nimport {\n type CommandPayload,\n type MessageId,\n type AssertSameMembers,\n isRecord,\n isNonEmptyString,\n makeTypeGuard,\n} from './envelope'\nimport type { DaemonStatusEventWirePayload } from './daemon-server'\n\n// ─── Chunk envelope (both directions) ──────────────────────────────────────\n\nexport type ChunkFrame<T extends string> = {\n type: T\n /** Request id of the frame being split, when it has one. */\n id?: MessageId\n chunkId: string\n index: number\n total: number\n data: string\n}\n\nexport function isChunkType(value: unknown): value is `${string}_chunk` {\n return typeof value === 'string' && value.endsWith('_chunk') && value.length > '_chunk'.length\n}\n\nfunction readChunkFields(frame: Record<string, unknown>): Omit<ChunkFrame<string>, 'type'> | null {\n if (!isNonEmptyString(frame.chunkId)) return null\n if (!Number.isInteger(frame.index) || !Number.isInteger(frame.total)) return null\n if (typeof frame.data !== 'string') return null\n return {\n ...(isNonEmptyString(frame.id) ? { id: frame.id } : {}),\n chunkId: frame.chunkId,\n index: frame.index as number,\n total: frame.total as number,\n data: frame.data,\n }\n}\n\n// ─── Dashboard → Daemon ────────────────────────────────────────────────────\n\nexport const DASHBOARD_TO_DAEMON_P2P_TYPES = [\n 'ping',\n 'pong',\n 'command',\n 'input',\n 'pty_input',\n 'pty_resize',\n 'screenshot_start',\n 'screenshot_stop',\n 'subscribe',\n 'unsubscribe',\n 'seqscribe_session_interest',\n 'read',\n 'write',\n 'list',\n] as const\nexport type DashboardToDaemonP2PType = typeof DASHBOARD_TO_DAEMON_P2P_TYPES[number]\nexport const isDashboardToDaemonP2PType = makeTypeGuard(DASHBOARD_TO_DAEMON_P2P_TYPES)\n\nexport type DashboardToDaemonChunkType = `${DashboardToDaemonP2PType}_chunk`\nexport function isDashboardToDaemonChunkType(value: unknown): value is DashboardToDaemonChunkType {\n return isChunkType(value) && isDashboardToDaemonP2PType(value.slice(0, -'_chunk'.length))\n}\n\nexport type P2PPingMsg = { type: 'ping'; ts: number }\nexport type P2PPongMsg = { type: 'pong'; ts: number }\n/** A command routed through the daemon's command router; `commandType`/`data` are dynamic by design. */\nexport type P2PCommandMsg = { type: 'command'; id: MessageId; commandType: string; data: CommandPayload }\n/** Remote-desktop input (click/type/key) for the target session's IDE surface. */\nexport type P2PInputMsg = { type: 'input'; id: MessageId; action: string; params: CommandPayload; targetSessionId?: string }\n/** Raw PTY input. `sessionId` is canonical; `targetSessionId` is the accepted alias. */\nexport type P2PPtyInputMsg = { type: 'pty_input'; sessionId?: string; targetSessionId?: string; data: string }\nexport type P2PPtyResizeMsg = { type: 'pty_resize'; sessionId: string; cols: number; rows: number }\nexport type P2PScreenshotStartMsg = { type: 'screenshot_start'; targetSessionId: string }\nexport type P2PScreenshotStopMsg = { type: 'screenshot_stop'; targetSessionId?: string }\n/**\n * Topic subscription. `params` is topic-specific (daemon-core `SubscribeRequestMap`); `object` keeps every topic's interface assignable.\n * `wireVersion` is the dashboard wire version the page speaks (./dashboard-wire-version.ts).\n */\nexport type P2PSubscribeMsg = { type: 'subscribe'; topic: string; key: string; params: object; wireVersion?: number }\nexport type P2PUnsubscribeMsg = { type: 'unsubscribe'; topic: string; key: string }\n/** Which sessions this peer wants replicated over the seqscribe lane; also the peer's responder proof. */\nexport type P2PSessionInterestMsg = { type: 'seqscribe_session_interest'; sessionIds: readonly string[] }\nexport type P2PFileReadMsg = { type: 'read'; id: MessageId; path: string }\nexport type P2PFileWriteMsg = { type: 'write'; id: MessageId; path: string; content: string }\nexport type P2PFileListMsg = { type: 'list'; id: MessageId; path: string }\nexport type DashboardToDaemonChunkMsg = ChunkFrame<DashboardToDaemonChunkType>\n\nexport type DashboardToDaemonP2PMsg =\n | P2PPingMsg\n | P2PPongMsg\n | P2PCommandMsg\n | P2PInputMsg\n | P2PPtyInputMsg\n | P2PPtyResizeMsg\n | P2PScreenshotStartMsg\n | P2PScreenshotStopMsg\n | P2PSubscribeMsg\n | P2PUnsubscribeMsg\n | P2PSessionInterestMsg\n | P2PFileReadMsg\n | P2PFileWriteMsg\n | P2PFileListMsg\n\nconst _dashboardToDaemonNamesCoverUnion: AssertSameMembers<typeof DASHBOARD_TO_DAEMON_P2P_TYPES, DashboardToDaemonP2PMsg['type']> = true\nvoid _dashboardToDaemonNamesCoverUnion\n\n/** Request kinds the daemon answers by `id`; a frame without one cannot be answered and is dropped at the boundary. */\nconst DASHBOARD_REQUEST_TYPES = new Set<DashboardToDaemonP2PType>(['command', 'input', 'read', 'write', 'list'])\n\n/** Parse boundary for the daemon's chunk reassembler: one `<kind>_chunk` piece of a split request. */\nexport function decodeDashboardToDaemonP2PChunk(raw: unknown): DashboardToDaemonChunkMsg | null {\n if (!isRecord(raw) || !isDashboardToDaemonChunkType(raw.type)) return null\n const fields = readChunkFields(raw)\n return fields ? { type: raw.type, ...fields } : null\n}\n\n/**\n * Parse boundary for the daemon (after chunk reassembly): a whole request.\n * Chunk pieces are not requests and decode to null here; see\n * `decodeDashboardToDaemonP2PChunk`.\n */\nexport function decodeDashboardToDaemonP2P(raw: unknown): DashboardToDaemonP2PMsg | null {\n if (!isRecord(raw) || !isDashboardToDaemonP2PType(raw.type)) return null\n if (DASHBOARD_REQUEST_TYPES.has(raw.type) && !isNonEmptyString(raw.id)) return null\n return raw as DashboardToDaemonP2PMsg\n}\n\n// ─── Daemon → Dashboard ────────────────────────────────────────────────────\n\nexport const DAEMON_TO_DASHBOARD_P2P_TYPES = [\n 'ping',\n 'pong',\n 'p2p_evicted',\n 'status_event',\n 'topic_update',\n 'topic_update_chunk',\n 'session_output',\n 'session_output_chunk',\n 'session_io_error',\n 'command_result',\n 'command_result_chunk',\n 'response',\n 'transcript_topics_available',\n] as const\nexport type DaemonToDashboardP2PType = typeof DAEMON_TO_DASHBOARD_P2P_TYPES[number]\nexport const isDaemonToDashboardP2PType = makeTypeGuard(DAEMON_TO_DASHBOARD_P2P_TYPES)\n\n/** The server-bound event plus the P2P-only structured prompt (daemon-core `P2PStatusEventPayload`). */\nexport type P2PStatusEventWirePayload = DaemonStatusEventWirePayload & {\n interactivePrompt?: unknown\n promptId?: string\n multiSelect?: boolean\n}\n\n/** One topic update (daemon-core `TopicUpdateEnvelope`); consumers narrow by `topic`. */\nexport type TopicUpdateWireEnvelope = { topic: string; key: string }\n\nexport type P2PFileEntry = { name: string; type: string; size?: number }\n\nexport type P2PEvictedMsg = { type: 'p2p_evicted'; reason: string; maxconnections: number }\nexport type P2PStatusEventMsg = { type: 'status_event'; payload: P2PStatusEventWirePayload; timestamp: number }\nexport type P2PTopicUpdateMsg = { type: 'topic_update'; update: TopicUpdateWireEnvelope }\nexport type P2PTopicUpdateChunkMsg = ChunkFrame<'topic_update_chunk'>\nexport type P2PSessionOutputMsg = { type: 'session_output'; sessionId: string; data: string }\nexport type P2PSessionOutputChunkMsg = ChunkFrame<'session_output_chunk'> & { sessionId: string }\nexport type P2PSessionIoErrorMsg = { type: 'session_io_error'; sessionId: string; reason: string; error?: string }\n/** Result of a `command` frame. The router spreads the handler result in; `resultId` preserves a result-side `id`. */\nexport type P2PCommandResultMsg = { type: 'command_result'; id: MessageId; success: boolean; error?: string; resultId?: unknown } & Record<string, unknown>\nexport type P2PCommandResultChunkMsg = ChunkFrame<'command_result_chunk'>\n/** Result of an `input` or file (`read`/`write`/`list`) frame. */\nexport type P2PResponseMsg = {\n type: 'response'\n id: MessageId\n success: boolean\n result?: unknown\n error?: string\n content?: string\n entries?: P2PFileEntry[]\n}\n\n/**\n * `session.<id>.chat` topics that just became SUB-able for THIS peer (the\n * topic was defined, or the peer's declared session interest widened to it).\n * Sent only after the grant is in place, so a seqscribe SUB issued on receipt\n * is accepted; without it the browser can only guess when to re-SUB a refused\n * subscription. Topic names only — the P2P plane already carries the ids.\n */\nexport type P2PTranscriptTopicsAvailableMsg = { type: 'transcript_topics_available'; topics: string[] }\n\nexport type DaemonToDashboardP2PMsg =\n | P2PPingMsg\n | P2PPongMsg\n | P2PEvictedMsg\n | P2PStatusEventMsg\n | P2PTopicUpdateMsg\n | P2PTopicUpdateChunkMsg\n | P2PSessionOutputMsg\n | P2PSessionOutputChunkMsg\n | P2PSessionIoErrorMsg\n | P2PCommandResultMsg\n | P2PCommandResultChunkMsg\n | P2PResponseMsg\n | P2PTranscriptTopicsAvailableMsg\n\nconst _daemonToDashboardNamesCoverUnion: AssertSameMembers<typeof DAEMON_TO_DASHBOARD_P2P_TYPES, DaemonToDashboardP2PMsg['type']> = true\nvoid _daemonToDashboardNamesCoverUnion\n\n/** Parse boundary for the dashboard (after chunk reassembly). */\nexport function decodeDaemonToDashboardP2P(raw: unknown): DaemonToDashboardP2PMsg | null {\n if (!isRecord(raw)) return null\n if (!isDaemonToDashboardP2PType(raw.type)) return null\n switch (raw.type) {\n case 'ping':\n case 'pong':\n case 'p2p_evicted':\n return raw as DaemonToDashboardP2PMsg\n case 'status_event':\n return isRecord(raw.payload) ? (raw as DaemonToDashboardP2PMsg) : null\n case 'topic_update':\n return isRecord(raw.update) ? (raw as P2PTopicUpdateMsg) : null\n case 'topic_update_chunk':\n case 'command_result_chunk':\n case 'session_output_chunk': {\n const fields = readChunkFields(raw)\n if (!fields) return null\n if (raw.type === 'session_output_chunk') {\n return isNonEmptyString(raw.sessionId) ? { type: raw.type, sessionId: raw.sessionId, ...fields } : null\n }\n return { type: raw.type, ...fields }\n }\n case 'session_output':\n return isNonEmptyString(raw.sessionId) && typeof raw.data === 'string' ? (raw as P2PSessionOutputMsg) : null\n case 'session_io_error':\n return isNonEmptyString(raw.sessionId) ? (raw as P2PSessionIoErrorMsg) : null\n case 'command_result':\n case 'response':\n return isNonEmptyString(raw.id) ? (raw as DaemonToDashboardP2PMsg) : null\n case 'transcript_topics_available':\n return Array.isArray(raw.topics) && raw.topics.every((topic) => typeof topic === 'string')\n ? { type: raw.type, topics: raw.topics as string[] }\n : null\n }\n}\n\n/** Both directions, for the legacy `DashboardP2PMessageKind` name and the drift gate. */\nexport const DASHBOARD_P2P_MESSAGE_KINDS = [\n ...new Set<string>([...DASHBOARD_TO_DAEMON_P2P_TYPES, ...DAEMON_TO_DASHBOARD_P2P_TYPES]),\n] as ReadonlyArray<DashboardToDaemonP2PType | DaemonToDashboardP2PType>\n","/**\n * protocol/dashboard-wire-version — the dashboard ↔ daemon wire version.\n *\n * Both dashboards (cloud over P2P, standalone over WS) state the version they\n * speak on every topic subscribe; the daemon states its own on the standalone\n * hello, on every keyed snapshot frame, and in the `protocol_mismatch` reply it\n * sends INSTEAD of state when the two differ. There is no dual-format serving:\n * a mismatched pair renders no state at all —\n * - the page is older than the daemon → the page must reload (its bundle\n * cannot read the daemon's frames);\n * - the daemon is older than the page → the daemon must be updated.\n *\n * Bump this whenever a frame shape changes incompatibly; one release carries\n * the same value on both ends.\n * 1 — implicit (frames before versioning).\n * 2 — daemon.metadata deltas on the keyed-doc engine (2026-09-29).\n */\nexport const DASHBOARD_WIRE_VERSION = 2\n\nexport type DashboardWireCompat = 'ok' | 'reload_required' | 'daemon_update_required'\n\n/** How a page speaking `pageVersion` relates to a daemon speaking `daemonVersion` (absent = 1). */\nexport function compareDashboardWireVersion(pageVersion: number, daemonVersion: number | null | undefined): DashboardWireCompat {\n const daemon = typeof daemonVersion === 'number' && Number.isFinite(daemonVersion) ? daemonVersion : 1\n if (daemon === pageVersion) return 'ok'\n return daemon > pageVersion ? 'reload_required' : 'daemon_update_required'\n}\n","/**\n * ws-protocol — name-only aliases for the daemon↔server WS surface and the\n * daemon↔dashboard P2P DataChannel surface, plus the `auth_ok.payload.limits`\n * contract.\n *\n * Wiring-unification Phase A2: the typed frame unions now live in ./protocol\n * (one file per link, payloads included). This file keeps the symbols that\n * pre-dated them — `DaemonToServerWsMsg`, `ServerToDaemonWsMsg`,\n * `P2PSignalingWsMsg`, `DashboardP2PMessageKind` and the two name arrays —\n * DERIVED from the protocol unions rather than re-declared, so they cannot\n * drift again. Before this derivation the list here said `offer|answer|ice`\n * while the wire said `p2p_offer|p2p_answer|p2p_ice`, declared a `log` frame\n * nothing sent or handled, omitted `daemon_mesh_command` (sent by a raw\n * `ws.send`), and listed 12 of the ~27 P2P kinds — and nothing imported the\n * drifted members, so nothing noticed.\n */\n\nimport {\n DAEMON_TO_SERVER_TYPES,\n SERVER_TO_DAEMON_CONTROL_TYPES,\n type DaemonToServerType,\n type ServerToDaemonControlType,\n type P2PSignalType,\n type MeshP2PSignalType,\n type DashboardToDaemonP2PType,\n type DaemonToDashboardP2PType,\n} from './protocol';\n\n/** Messages the daemon sends UP to the Workers server over the WS bridge (see protocol/daemon-server.ts). */\nexport type DaemonToServerWsMsg = DaemonToServerType;\n\n/**\n * Server→daemon CONTROL messages (see protocol/daemon-server.ts). The server\n * additionally relays an open command namespace as the frame `type`\n * (`ServerDirectCommandMsg`), which is deliberately not a member here.\n */\nexport type ServerToDaemonWsMsg = ServerToDaemonControlType;\n\n/** P2P signaling relayed through the server WS — the `p2p_`/`mesh_p2p_` spellings the wire actually uses. */\nexport type P2PSignalingWsMsg = P2PSignalType | MeshP2PSignalType;\n\n/** Every dashboard↔daemon P2P DataChannel JSON kind, both directions (see protocol/dashboard-daemon-p2p.ts). */\nexport type DashboardP2PMessageKind = DashboardToDaemonP2PType | DaemonToDashboardP2PType;\n\nexport const DAEMON_TO_SERVER_WS_MSGS: readonly DaemonToServerWsMsg[] = DAEMON_TO_SERVER_TYPES;\n\nexport const SERVER_TO_DAEMON_WS_MSGS: readonly ServerToDaemonWsMsg[] = SERVER_TO_DAEMON_CONTROL_TYPES;\n\n\n\n/**\n * `auth_ok.payload.limits` — the plan-limit contract the server sends DOWN to\n * the daemon for client-side enforcement.\n *\n * WHY THIS EXISTS: the wire spelling is `maxP2Pconnections` (lowercase `c`),\n * inherited from `PlanLimits` in the proprietary server's plan-limits.ts. The\n * daemon-cloud consumer independently declared the same field as\n * `maxP2PConnections` (capital `C`) and assigned it from a `payload as any`\n * cast — so the two spellings NEVER met under a type, TypeScript had nothing\n * to compare, and the limit arrived as `undefined` at every comparison site.\n * `undefined !== -1` passes the \"is it unlimited?\" guard, then every\n * `count >= undefined` is false: enforcement silently degraded to unlimited on\n * all plans, in production, for months.\n *\n * The lesson is NOT \"pick a spelling\" — it is that a cross-package wire\n * contract asserted by hand on both ends with an `any` in between cannot fail\n * loudly. Both producer (server) and consumer (daemon-cloud) must now import\n * THIS symbol, so a rename breaks the build on both sides instead of silently\n * disabling a paid-plan limit. Use `normalizeAuthOkLimits()` at the parse\n * boundary; never re-spell these fields locally.\n */\nexport interface AuthOkPlanLimits {\n /** P2P concurrent connection count (-1 = unlimited). WIRE SPELLING — lowercase `c`. */\n maxP2Pconnections: number;\n /** Screenshot send interval floor (seconds). 0 = real-time. */\n screenshotIntervalSeconds: number;\n /** Daily screenshot usage budget (minutes). -1 = unlimited. */\n dailyScreenshotMinutes: number;\n /** Max connectable machines/daemons (-1 = unlimited). */\n maxMachines: number;\n}\n\n/**\n * Parse-boundary normalizer for `auth_ok.payload.limits`.\n *\n * Returns `null` when the payload carries no usable limits object, so callers\n * keep their existing \"no limits known yet\" branch. Individual non-numeric or\n * missing fields fall back to the UNLIMITED sentinel (-1) for count-style\n * limits and 0 for the interval floor, matching how each consumer already\n * treats \"no constraint\" — a malformed field must never be coerced to a\n * MORE restrictive value than the server intended, or a server-side schema\n * change would start throttling paying users.\n *\n * Accepts the capital-`C` misspelling as an input alias ONLY so a daemon\n * talking to a mixed-version fleet cannot regress; output is always the\n * canonical wire spelling.\n */\nexport function normalizeAuthOkLimits(raw: unknown): AuthOkPlanLimits | null {\n if (!raw || typeof raw !== 'object') return null;\n const src = raw as Record<string, unknown>;\n const num = (value: unknown, fallback: number): number =>\n typeof value === 'number' && Number.isFinite(value) ? value : fallback;\n return {\n maxP2Pconnections: num(\n src.maxP2Pconnections !== undefined ? src.maxP2Pconnections : src.maxP2PConnections,\n -1,\n ),\n screenshotIntervalSeconds: num(src.screenshotIntervalSeconds, 0),\n dailyScreenshotMinutes: num(src.dailyScreenshotMinutes, -1),\n maxMachines: num(src.maxMachines, -1),\n };\n}\n","export const CLAUDE_TUI_REVIEW_PAGE_NOT_FOCUSED_PREFIX = 'Claude TUI review page is not focused';\n\n/**\n * The answer keystrokes reached the terminal, but the daemon could not CONFIRM\n * the review page before its settle budget expired — the picker was still\n * showing our own bound question, not a foreign widget.\n *\n * This is deliberately a separate class from\n * CLAUDE_TUI_REVIEW_PAGE_NOT_FOCUSED_PREFIX, which means \"the screen is\n * something we do not own, so we refuse to press Enter into it\". Here the\n * screen IS ours and the input WAS delivered; only the confirmation is\n * missing. Resending would replay the whole keystroke sequence into a picker\n * that may have advanced in the meantime, so the UI for this class must NOT\n * invite a retry. See the daemon-side gate in\n * `providers/spec/cli-adapter.ts` (assertFocusedClaudeTuiReview) and the web\n * mapping in `web-core/src/hooks/useInteractivePrompt.ts`.\n */\nexport const CLAUDE_TUI_REVIEW_UNCONFIRMED_PREFIX = 'Claude TUI answer delivered but not confirmed';\n","/**\n * session-status — the ONE session status vocabulary.\n *\n * Wiring-unification Phase A1 (docs/design/2026-09-23-wiring-unification.md).\n *\n * Before this file, the same eleven-member union was declared three times in\n * daemon-core (`SessionStatus`, `ManagedStatus`, and a stale `AgentStatus`) and\n * five independent \"is it busy?\" sets disagreed with each other — for example\n * `waiting_approval` counted as busy in three of them and idle in the other\n * two. Every consumer now derives from here:\n *\n * - the canonical union `SessionStatus` and its member list `SESSION_STATUSES`;\n * - a behavioural CLASS per status (`SESSION_STATUS_CLASS`) — the only thing\n * send / dispatch / UI logic may branch on;\n * - an alias table for the raw spellings providers and status lanes still\n * emit (`running`, `streaming`, `no_progress`, …) so classification is total.\n *\n * This lives in mesh-shared (a dependency-free leaf) because web-core must not\n * value-import the daemon-core barrel, and the server has no daemon-core at all.\n */\n\nexport const SESSION_STATUSES = [\n 'idle',\n 'generating',\n 'waiting_approval',\n 'waiting_choice',\n 'finalizing',\n 'error',\n 'stopped',\n 'starting',\n 'panel_hidden',\n 'not_monitored',\n 'disconnected',\n] as const\n\nexport type SessionStatus = typeof SESSION_STATUSES[number]\n\nexport const RECENT_SESSION_BUCKETS = ['needs_attention', 'working', 'task_complete', 'idle'] as const\n\nexport type RecentSessionBucket = typeof RECENT_SESSION_BUCKETS[number]\n\n/**\n * Behavioural class of a status.\n *\n * working — the agent owns the turn; input is queued, not delivered.\n * blocked — the agent is waiting on a human decision (approval / choice);\n * alive, and the turn is not over.\n * ready — the agent will accept input now.\n * dead — the session will never accept input again.\n * unknown — the spelling is not one we classify (callers must fail safe).\n */\nexport type SessionStatusClass = 'working' | 'blocked' | 'ready' | 'dead' | 'unknown'\n\nexport const SESSION_STATUS_CLASS: Record<SessionStatus, Exclude<SessionStatusClass, 'unknown'>> = {\n generating: 'working',\n finalizing: 'working',\n starting: 'working',\n waiting_approval: 'blocked',\n waiting_choice: 'blocked',\n idle: 'ready',\n panel_hidden: 'ready',\n not_monitored: 'ready',\n error: 'dead',\n stopped: 'dead',\n disconnected: 'dead',\n}\n\n/**\n * Raw spellings that still reach status consumers from IDE/CDP providers, the\n * chat-tail status lane and legacy adapters, mapped onto the canonical member\n * that carries the same behavioural meaning. Keep this table exhaustive over\n * what the five pre-unification busy sets accepted; a spelling missing here\n * classifies as `unknown`, which every consumer must treat as \"do not assume\n * idle\".\n */\nexport const SESSION_STATUS_ALIASES: Readonly<Record<string, SessionStatus>> = {\n running: 'generating',\n streaming: 'generating',\n busy: 'generating',\n working: 'generating',\n loading: 'generating',\n loading_reference: 'generating',\n thinking: 'generating',\n active: 'generating',\n // Status-lane refinements of a turn that is still owned by the agent.\n no_progress: 'generating',\n long_generating: 'generating',\n initializing: 'starting',\n waiting: 'waiting_approval',\n}\n\nconst SESSION_STATUS_SET: ReadonlySet<string> = new Set(SESSION_STATUSES)\n\nexport function isSessionStatus(value: unknown): value is SessionStatus {\n return typeof value === 'string' && SESSION_STATUS_SET.has(value)\n}\n\n/** Canonical member for a raw status spelling, or null when unrecognised. */\nexport function normalizeSessionStatus(raw: unknown): SessionStatus | null {\n if (typeof raw !== 'string') return null\n const value = raw.trim().toLowerCase()\n if (SESSION_STATUS_SET.has(value)) return value as SessionStatus\n return SESSION_STATUS_ALIASES[value] ?? null\n}\n\nexport function classifySessionStatus(raw: unknown): SessionStatusClass {\n const status = normalizeSessionStatus(raw)\n return status ? SESSION_STATUS_CLASS[status] : 'unknown'\n}\n\nexport function isWorkingStatus(raw: unknown): boolean {\n return classifySessionStatus(raw) === 'working'\n}\n\nexport function isBlockedStatus(raw: unknown): boolean {\n return classifySessionStatus(raw) === 'blocked'\n}\n\nexport function isReadyStatus(raw: unknown): boolean {\n return classifySessionStatus(raw) === 'ready'\n}\n\nexport function isDeadStatus(raw: unknown): boolean {\n return classifySessionStatus(raw) === 'dead'\n}\n\n/**\n * \"Busy\" in the sense every pre-unification set meant: the agent cannot take a\n * new instruction right now, whether because it is working or because it is\n * blocked on a human. Dead sessions are NOT busy — they are gone, and callers\n * that need to distinguish must check `isDeadStatus` first.\n */\nexport function isBusyStatus(raw: unknown): boolean {\n const cls = classifySessionStatus(raw)\n return cls === 'working' || cls === 'blocked'\n}\n\nexport function statusesOfClass(cls: Exclude<SessionStatusClass, 'unknown'>): SessionStatus[] {\n return SESSION_STATUSES.filter((status) => SESSION_STATUS_CLASS[status] === cls)\n}\n\n/**\n * Mesh-record terminal spellings: a session RECORD in one of these is gone\n * (the vocabulary's `dead` class covers the canonical members; records also\n * carry `failed` / `terminated` / `exited` / `closed`).\n */\nexport const TERMINAL_SESSION_RECORD_STATUSES = ['stopped', 'failed', 'terminated', 'exited', 'closed'] as const\n\nexport function isTerminalSessionRecordStatus(raw: unknown): boolean {\n return typeof raw === 'string' && (TERMINAL_SESSION_RECORD_STATUSES as readonly string[]).includes(raw.trim().toLowerCase())\n}\n\n/**\n * THE \"idle — can take a task now\" predicate over a session state/record (its\n * top-level `status` and chat lane). Every idle-candidate check (queue drain,\n * auto-launch orphan sweep, dispatch pick) uses this one, so they cannot\n * disagree about which sessions are candidates.\n */\nexport function isIdleSessionState(state: unknown): boolean {\n const record = state && typeof state === 'object' ? state as { status?: unknown; activeChat?: { status?: unknown } } : {}\n const status = typeof record.status === 'string' ? record.status.trim().toLowerCase() : ''\n if (isTerminalSessionRecordStatus(status) || isDeadStatus(status)) return false\n return isReadyStatus(status) || record.activeChat?.status === 'waiting_input'\n}\n","/**\n * mesh-vocabulary — the ONE declaration of every mesh enum.\n *\n * Wiring-unification Phase A3 (docs/design/2026-09-23-wiring-unification.md).\n *\n * Before this file `MeshTaskStatus` was declared twice in daemon-core with\n * different members (one carried `in_progress`, which no task row ever held),\n * a third time in `repo-mesh-types.ts`, and loosened to `| string` in web-core;\n * the MCP tool schemas hand-copied the task-mode list six times. Every enum a\n * mesh tool, ledger row, queue entry or dashboard view branches on is declared\n * here once, as a `const` tuple, and the type is derived from it. JSON-schema\n * producers use `enumOf()` so the published schema cannot drift from the code.\n *\n * `MeshTaskDifficulty` / `MESH_TASK_DIFFICULTIES` already live in\n * ./brain-routing.ts and are re-exported here for one-stop discovery.\n */\n\nexport { MESH_TASK_DIFFICULTIES, type MeshTaskDifficulty } from './brain-routing'\n\nexport const MESH_TASK_STATUSES = ['pending', 'assigned', 'completed', 'failed', 'cancelled'] as const\nexport type MeshTaskStatus = typeof MESH_TASK_STATUSES[number]\n\nexport const MESH_TERMINAL_TASK_STATUSES = ['completed', 'failed', 'cancelled'] as const\nexport type MeshTerminalTaskStatus = typeof MESH_TERMINAL_TASK_STATUSES[number]\n\nexport const MESH_TASK_MODES = ['code_change', 'validation', 'live_debug_readonly', 'launch_app', 'convergence'] as const\nexport type MeshTaskMode = typeof MESH_TASK_MODES[number]\n\nexport const MESH_TASK_PRIORITIES = ['low', 'normal', 'high'] as const\nexport type MeshTaskPriority = typeof MESH_TASK_PRIORITIES[number]\n\nexport const MESH_THINKING_LEVELS = ['low', 'medium', 'high'] as const\nexport type MeshThinkingLevel = typeof MESH_THINKING_LEVELS[number]\n\n/**\n * How a message is delivered to a session that may be busy.\n *\n * 'when_idle' — DEFAULT. Never disturbs a running turn; a busy session's task\n * is queued and auto-delivered on its next idle transition.\n * 'interrupt' — Abort the in-flight turn (the provider's own stop control),\n * then deliver once the session settles to idle. The name is\n * deliberately blunt: the unfinished work is LOST. `immediate`\n * was rejected as a name because it reads like a gentle overlay.\n */\nexport const MESH_DELIVERY_MODES = ['when_idle', 'interrupt'] as const\nexport type MeshDeliveryMode = typeof MESH_DELIVERY_MODES[number]\n\n/**\n * What to do with a node's sessions when the node is removed. Declared here so daemon-core (`RepoMeshSessionCleanupMode`), the\n * web dashboard picker and the MCP schemas all read one list.\n */\nexport const MESH_SESSION_CLEANUP_MODES = ['preserve', 'stop', 'delete_stopped', 'stop_and_delete'] as const\nexport type MeshSessionCleanupMode = typeof MESH_SESSION_CLEANUP_MODES[number]\n\n/** Outcome a delegated worker may report through `report_completion`. */\nexport const WORKER_REPORT_OUTCOMES = ['completed', 'blocked', 'failed'] as const\nexport type WorkerReportOutcome = typeof WORKER_REPORT_OUTCOMES[number]\n\n/** Final branch state a worker reports (see coordinator convergence rules). */\nexport const WORKER_BRANCH_STATES = [\n 'merged_to_main',\n 'pushed_feature_branch_needs_merge',\n 'blocked_review',\n 'cleanup_candidate',\n 'not_mergeable',\n] as const\nexport type WorkerBranchState = typeof WORKER_BRANCH_STATES[number]\n\nfunction makeGuard<T extends readonly string[]>(values: T): (value: unknown) => value is T[number] {\n const set: ReadonlySet<string> = new Set(values)\n return (value: unknown): value is T[number] => typeof value === 'string' && set.has(value)\n}\n\nexport const isMeshTaskStatus = makeGuard(MESH_TASK_STATUSES)\nexport const isMeshTerminalTaskStatus = makeGuard(MESH_TERMINAL_TASK_STATUSES)\nexport const isMeshTaskMode = makeGuard(MESH_TASK_MODES)\nexport const isMeshTaskPriority = makeGuard(MESH_TASK_PRIORITIES)\nexport const isMeshDeliveryMode = makeGuard(MESH_DELIVERY_MODES)\nexport const isWorkerReportOutcome = makeGuard(WORKER_REPORT_OUTCOMES)\n\n/**\n * JSON-schema fragment for a string enum, derived from the tuple. Use this in\n * every MCP tool schema instead of spelling the member list again.\n */\nexport function enumOf<T extends readonly string[]>(\n values: T,\n description?: string,\n): { type: 'string'; enum: T[number][]; description?: string } {\n return {\n type: 'string',\n enum: [...values] as T[number][],\n ...(description ? { description } : {}),\n }\n}\n","/**\n * outbound-message — the one send-side unit crossing every transport.\n *\n * Wiring-unification Phase D (docs/design/2026-09-23-wiring-unification.md §6,\n * D1) / workstream D-web. Full type derivation in the scratchpad\n * `phase-D-plan.md` §1.1-§1.2 (`OutboundMessage`/`SendPolicy`/`SubmitOutcome`/\n * `SendRefusal`). `SendRefusal` is imported from here by Phase C1's\n * `turn-evidence.ts` (`RECLAIMING_SEND_REFUSALS`) — this file owns the type,\n * C1 owns which of its members reclaim a mesh dispatch attempt.\n *\n * Before this type, a chat send was represented by twelve different loose\n * request shapes (`{message, sendNow?, interrupt?}`, `{message, input}`,\n * mesh `agent_command` args, MCP tool args, ...) and parked messages had no\n * identity at all — the driver queue was keyed by exact text, so send-now,\n * cancel, interrupt and the web echo-retirement all recovered identity by\n * string matching. `OutboundMessage.messageId` is minted once, at the\n * ORIGIN, and is the identity every layer keys on afterwards: the wire\n * field in the `send_chat` command payload, the driver's queue key (daemon\n * side, Phase D-daemon), the web pending-store key (`pendingQueuedMessages.ts`)\n * and the echo-retirement key (`conversation-message-snapshot.ts`).\n *\n * This file is dependency-free by construction (mesh-shared leaf rule):\n * `InputEnvelopeWire`/`InputPartWire` are STRUCTURAL MIRRORS of daemon-core's\n * `InputEnvelope`/`InputPart` (`oss/packages/daemon-core/src/providers/\n * io-contracts.ts`), not re-exports — daemon-core assigns its richer type\n * into this one, never the other way round, so this package's published\n * `.d.ts` never references a package that depends on it.\n */\n\n// ─── Input envelope (structural mirror of daemon-core's InputEnvelope) ─────\n\nexport interface ContentAnnotationsWire {\n audience?: ('user' | 'assistant')[]\n priority?: number\n}\n\nexport interface TextInputPartWire {\n type: 'text'\n text: string\n}\n\nexport interface ImageInputPartWire {\n type: 'image'\n mimeType: string\n uri?: string\n data?: string\n alt?: string\n}\n\nexport interface AudioInputPartWire {\n type: 'audio'\n mimeType: string\n uri?: string\n data?: string\n transcript?: string\n}\n\nexport interface VideoInputPartWire {\n type: 'video'\n mimeType: string\n uri?: string\n data?: string\n transcript?: string\n posterUri?: string\n}\n\nexport interface ResourceInputPartWire {\n type: 'resource'\n uri: string\n mimeType?: string\n name?: string\n text?: string\n data?: string\n}\n\nexport interface ResourceLinkInputPartWire {\n type: 'resource_link'\n uri: string\n name: string\n title?: string\n description?: string\n mimeType?: string\n size?: number\n annotations?: ContentAnnotationsWire\n}\n\nexport type InputPartWire =\n | TextInputPartWire\n | ImageInputPartWire\n | AudioInputPartWire\n | VideoInputPartWire\n | ResourceLinkInputPartWire\n | ResourceInputPartWire\n\nexport interface InputEnvelopeWire {\n parts: InputPartWire[]\n textFallback: string\n metadata?: {\n source?: 'dashboard' | 'shortcut_api' | 'provider_script' | 'session_replay'\n clientTimestamp?: number\n }\n}\n\n// ─── OutboundMessage ────────────────────────────────────────────────────────\n\n/**\n * Who minted this `OutboundMessage`. Determines default policy and refusal\n * surface — 'mesh' origins get the mesh-specific `SendRefusal` reasons,\n * interactive origins get the interactive ones.\n *\n * `'api'`/`'cli'` are carried per the design doc's D1 type even though no\n * current call site produces them distinct from `'dashboard'`/`'mcp'`/\n * `'mesh'` (flagged as an open question in phase-D-plan.md §7.3 risk 5) —\n * kept here unchanged pending an owner decision; dropping a union member is\n * a decision for whoever lands D-daemon/D2, not this workstream.\n *\n * `'assistant'`: the assistant layer's `project_send` into a project\n * coordinator (docs/design/2026-10-07-assistant-layer.md §4.3 step 4). A label\n * only — it is not an auth signal and selects no policy of its own.\n */\nexport type OutboundMessageOrigin = 'dashboard' | 'mcp' | 'mesh' | 'api' | 'cli' | 'assistant'\n\n/**\n * How this message should be admitted when the session is not idle.\n * Replaces the loose `sendNow`/`interrupt`/`force`/`forceSend` booleans (and\n * mesh `delivery_mode`) with one closed union. `'queue'` is the default for\n * every origin.\n */\nexport type SendPolicy =\n | { mode: 'queue' }\n | { mode: 'send_now' }\n | { mode: 'interrupt' }\n\n/**\n * Every reason `submit()` can refuse a message, closed so callers branch on it\n * instead of matching free text.\n *\n * ★ This is THE `SendRefusal` (docs/design/2026-09-23-wiring-unification.md\n * §6 D1) — Phase C1's `turn-evidence.ts` imports `SendRefusal`/\n * `SEND_REFUSAL_REASONS` from this file (`RECLAIMING_SEND_REFUSALS`, the\n * subset that means a mesh dispatch attempt must be reclaimed rather than\n * retried) rather than declaring its own copy. Do not fork this vocabulary —\n * a member renamed or removed here must be re-checked against\n * `RECLAIMING_SEND_REFUSALS`'s three members (`session_exited`, `no_target`,\n * `unsupported_input`), which `satisfies readonly SendRefusal[]` there keeps\n * honest at compile time.\n */\nexport type SendRefusal =\n | 'not_ready'\n | 'send_in_flight'\n | 'not_generating'\n | 'not_supported'\n | 'platform_unsupported'\n | 'modal_parked'\n | 'interrupt_not_implemented'\n | 'interrupt_refused'\n | 'idle_timeout'\n | 'session_exited'\n | 'unsupported_input'\n | 'no_target'\n | 'bootstrap_pending'\n | 'duplicate_dispatch'\n | 'internal_error'\n\n/**\n * Which write path carried a delivered/queued message (Phase D2, additive\n * detail — callers branch on `kind`; `route` only refines the report):\n *\n * `pty` — the ordinary composer write (or the driver FIFO for `queued`);\n * `agent_queue` — the POSIX split write the CLI's OWN input queue takes while\n * a turn is generating (`send_now`). Written, not yet answered;\n * `interrupt` — the turn in flight was stopped first, then this body was\n * written (or re-parked) as a new turn;\n */\nexport type SubmitRoute = 'pty' | 'agent_queue' | 'interrupt'\n\n/** The stop key pressed by an `interrupt` submit (logs / operator display). */\nexport interface SubmitInterruptDetail {\n keyName: string\n /** 'declared' = spec-declared stop key whose busy→idle effect was never observed live. */\n confidence: 'proven' | 'declared'\n}\n\n/**\n * The one closed outcome shape every caller receives from `submit()`.\n *\n * The optional fields are additive DETAIL (Phase D2): `route`/`interrupt` say\n * how a message was written, `message` is a human-readable refusal line and\n * `restored` says whether a parked body that an out-of-band submit had claimed\n * is back in the driver queue (`false` = nothing holds it any more). None of\n * them changes what `kind` means.\n */\nexport type SubmitOutcome =\n | { kind: 'delivered'; route?: SubmitRoute; interrupt?: SubmitInterruptDetail }\n | { kind: 'queued'; position: number; route?: SubmitRoute; interrupt?: SubmitInterruptDetail }\n | { kind: 'duplicate'; of: string /* messageId */ }\n | { kind: 'refused'; reason: SendRefusal; message?: string; restored?: boolean }\n\n/**\n * The one send-side unit crossing every transport. `messageId` is minted at\n * the ORIGIN (never by the daemon) — this is what makes cross-transport\n * dedupe and identity-based claim/cancel/send-now possible.\n */\nexport interface OutboundMessage {\n messageId: string\n sessionId: string\n input: InputEnvelopeWire\n origin: OutboundMessageOrigin\n policy: SendPolicy\n createdAt: number\n /**\n * Present only for a mesh-dispatched message; lets the turn ledger\n * (Phase C) bind the send to the attempt without the sender needing to\n * know what an \"attempt\" is. Optional and inert until C lands.\n */\n meshAttemptRef?: string\n}\n\n// ─── Identity ───────────────────────────────────────────────────────────────\n\n/**\n * Mint a new `messageId`. `crypto.randomUUID` where available (browser and\n * modern Node); a counter fallback otherwise, since the only requirement is\n * uniqueness within one process/tab, not cryptographic strength.\n */\nlet outboundMessageIdCounter = 0\nexport function mintMessageId(now: number = Date.now()): string {\n try {\n // `globalThis.crypto` is not in the ES2022 lib (mesh-shared is DOM-free), so read it structurally.\n const cryptoRef = (typeof globalThis !== 'undefined'\n ? (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n : undefined)\n if (typeof cryptoRef?.randomUUID === 'function') return `msg_${cryptoRef.randomUUID()}`\n } catch {\n /* fall through to the counter fallback */\n }\n outboundMessageIdCounter += 1\n return `msg_${now}_${outboundMessageIdCounter}`\n}\n\n/** `messageId`s minted by this module always carry this prefix; used by the guard below. */\nconst MESSAGE_ID_PREFIX = 'msg_'\n\nexport function isMessageId(value: unknown): value is string {\n return typeof value === 'string' && value.length > MESSAGE_ID_PREFIX.length && value.startsWith(MESSAGE_ID_PREFIX)\n}\n\n// ─── Guards ─────────────────────────────────────────────────────────────────\n\nexport const OUTBOUND_MESSAGE_ORIGINS = ['dashboard', 'mcp', 'mesh', 'api', 'cli', 'assistant'] as const satisfies readonly OutboundMessageOrigin[]\n\nexport function isOutboundMessageOrigin(value: unknown): value is OutboundMessageOrigin {\n return typeof value === 'string' && (OUTBOUND_MESSAGE_ORIGINS as readonly string[]).includes(value)\n}\n\nexport const SEND_POLICY_MODES = ['queue', 'send_now', 'interrupt'] as const satisfies readonly SendPolicy['mode'][]\n\nexport function isSendPolicyMode(value: unknown): value is SendPolicy['mode'] {\n return typeof value === 'string' && (SEND_POLICY_MODES as readonly string[]).includes(value)\n}\n\nexport function isSendPolicy(value: unknown): value is SendPolicy {\n return !!value && typeof value === 'object' && isSendPolicyMode((value as { mode?: unknown }).mode)\n}\n\nexport const SEND_REFUSAL_REASONS = [\n 'not_ready',\n 'send_in_flight',\n 'not_generating',\n 'not_supported',\n 'platform_unsupported',\n 'modal_parked',\n 'interrupt_not_implemented',\n 'interrupt_refused',\n 'idle_timeout',\n 'session_exited',\n 'unsupported_input',\n 'no_target',\n 'bootstrap_pending',\n 'duplicate_dispatch',\n 'internal_error',\n] as const satisfies readonly SendRefusal[]\n\nexport function isSendRefusal(value: unknown): value is SendRefusal {\n return typeof value === 'string' && (SEND_REFUSAL_REASONS as readonly string[]).includes(value)\n}\n\nconst SUBMIT_OUTCOME_KINDS = ['delivered', 'queued', 'duplicate', 'refused'] as const\n\nexport function isSubmitOutcome(value: unknown): value is SubmitOutcome {\n if (!value || typeof value !== 'object') return false\n const kind = (value as { kind?: unknown }).kind\n if (typeof kind !== 'string' || !(SUBMIT_OUTCOME_KINDS as readonly string[]).includes(kind)) return false\n if (kind === 'queued') return typeof (value as { position?: unknown }).position === 'number'\n if (kind === 'duplicate') return typeof (value as { of?: unknown }).of === 'string'\n if (kind === 'refused') return isSendRefusal((value as { reason?: unknown }).reason)\n return true\n}\n\nfunction isInputPartWire(value: unknown): value is InputPartWire {\n if (!value || typeof value !== 'object') return false\n const type = (value as { type?: unknown }).type\n return type === 'text' || type === 'image' || type === 'audio' || type === 'video' || type === 'resource' || type === 'resource_link'\n}\n\nexport function isInputEnvelopeWire(value: unknown): value is InputEnvelopeWire {\n if (!value || typeof value !== 'object') return false\n const parts = (value as { parts?: unknown }).parts\n const textFallback = (value as { textFallback?: unknown }).textFallback\n return Array.isArray(parts) && parts.every(isInputPartWire) && typeof textFallback === 'string'\n}\n\n/** Minimal structural check for the wire boundary — not a full decoder (mesh-shared stays a pure leaf; semantic validation stays with the handler that owns it). */\nexport function isOutboundMessage(value: unknown): value is OutboundMessage {\n if (!value || typeof value !== 'object') return false\n const candidate = value as Partial<OutboundMessage>\n return isMessageId(candidate.messageId)\n && typeof candidate.sessionId === 'string' && candidate.sessionId.length > 0\n && isInputEnvelopeWire(candidate.input)\n && isOutboundMessageOrigin(candidate.origin)\n && isSendPolicy(candidate.policy)\n && typeof candidate.createdAt === 'number'\n}\n","/**\n * mission-brief — the goal/constraints/done-criteria/handoff a coordinator\n * attaches to a mission at `mesh_mission_upsert` time, and the deterministic\n * rendering of that brief into a dispatched task's worker-protocol footer\n * (wiring-unification Phase H2, `docs/design/2026-09-23-wiring-unification.md`\n * §7c).\n *\n * `mesh_mission_upsert` today carries only a free-text `goal` string — no\n * structured constraints, done-criteria or handoff notes, and nothing from a\n * mission ever reaches a dispatched worker's task body. This module is the\n * pure, dependency-free core: a normalized `MissionBrief` shape with length\n * caps (mirrors `report_completion.summary`'s \"prefer specifics\" discipline —\n * a brief is meant to be read by a worker mid-task, not skimmed by a human),\n * and a deterministic Markdown renderer capped at 1,200 chars so a mission\n * with many/long fields cannot blow a dispatched task's token budget.\n *\n * This module does NOT decide where the rendered block is inserted (that is\n * `worker-protocol.ts`'s `renderWorkerProtocolFooter`, which places it above\n * the marker line — see that file), and does NOT touch storage (H2's proposal\n * keeps `mesh_missions` as the row source; this is the shape callers upsert\n * into/read out of that row's `goal`/new `brief` columns).\n */\n\n/** Per-field caps. Generous enough for real content, small enough that four\n * arrays of them cannot silently balloon a rendered block past the render cap. */\nconst GOAL_MAX = 500\nconst LIST_ITEM_MAX = 200\nconst LIST_MAX_ITEMS = 12\n\n/** Total rendered-block cap (design doc H2 \"bounded payload\" discipline, mirrored from `listMeshMissionsForTool`). */\nexport const MISSION_BRIEF_RENDER_MAX_CHARS = 1200\n\nexport interface MissionBrief {\n /** What this mission is trying to accomplish. Required — an empty brief is not meaningful. */\n goal: string\n /** Hard constraints a worker must respect (e.g. \"do not touch daemon-core\", \"no npm install\"). */\n constraints?: string[]\n /** How to know the mission is actually done. */\n doneCriteria?: string[]\n /** Standing notes for whoever picks up mission work next. */\n handoffNotes?: string[]\n /** Paths this mission's tasks collectively own (H1 integration point — surfaced, not enforced here). */\n ownedPaths?: string[]\n}\n\nexport interface NormalizeMissionBriefResult {\n /** `null` when the input had no usable `goal` — callers should treat this as \"no brief\", not an empty one. */\n readonly brief: MissionBrief | null\n /** What was trimmed/dropped, for a caller that wants to warn (never thrown). */\n readonly truncated: ReadonlyArray<{ field: string; reason: 'field_too_long' | 'list_too_long' | 'item_too_long' }>\n}\n\nfunction truncateString(value: string, max: number): string {\n if (value.length <= max) return value\n return `${value.slice(0, max - 1).trimEnd()}…`\n}\n\nfunction normalizeStringList(\n value: unknown,\n field: string,\n truncated: Array<{ field: string; reason: 'field_too_long' | 'list_too_long' | 'item_too_long' }>,\n): string[] | undefined {\n if (value === undefined || value === null) return undefined\n if (!Array.isArray(value)) return undefined\n const items: string[] = []\n let itemTruncated = false\n for (const raw of value) {\n if (typeof raw !== 'string') continue\n const trimmed = raw.trim()\n if (!trimmed) continue\n if (trimmed.length > LIST_ITEM_MAX) itemTruncated = true\n items.push(truncateString(trimmed, LIST_ITEM_MAX))\n }\n if (itemTruncated) truncated.push({ field, reason: 'item_too_long' })\n if (items.length > LIST_MAX_ITEMS) {\n truncated.push({ field, reason: 'list_too_long' })\n return items.slice(0, LIST_MAX_ITEMS)\n }\n return items.length > 0 ? items : undefined\n}\n\n/**\n * Normalize a caller-supplied brief. Never throws. Returns `brief: null` when\n * there is no non-empty `goal` — the caller (e.g. `mesh_mission_upsert`'s\n * handler) decides whether that means \"reject\" or \"no brief attached\", this\n * module only normalizes shape.\n */\nexport function normalizeMissionBrief(input: unknown): NormalizeMissionBriefResult {\n const truncated: Array<{ field: string; reason: 'field_too_long' | 'list_too_long' | 'item_too_long' }> = []\n if (!input || typeof input !== 'object') {\n return { brief: null, truncated }\n }\n const raw = input as Record<string, unknown>\n\n const rawGoal = typeof raw.goal === 'string' ? raw.goal.trim() : ''\n if (!rawGoal) {\n return { brief: null, truncated }\n }\n if (rawGoal.length > GOAL_MAX) truncated.push({ field: 'goal', reason: 'field_too_long' })\n const goal = truncateString(rawGoal, GOAL_MAX)\n\n const constraints = normalizeStringList(raw.constraints, 'constraints', truncated)\n const doneCriteria = normalizeStringList(raw.doneCriteria ?? raw.done_criteria, 'doneCriteria', truncated)\n const handoffNotes = normalizeStringList(raw.handoffNotes ?? raw.handoff_notes, 'handoffNotes', truncated)\n const ownedPaths = normalizeStringList(raw.ownedPaths ?? raw.owned_paths, 'ownedPaths', truncated)\n\n const brief: MissionBrief = { goal }\n if (constraints) brief.constraints = constraints\n if (doneCriteria) brief.doneCriteria = doneCriteria\n if (handoffNotes) brief.handoffNotes = handoffNotes\n if (ownedPaths) brief.ownedPaths = ownedPaths\n\n return { brief, truncated }\n}\n\nfunction renderList(heading: string, items: readonly string[] | undefined): string[] {\n if (!items || items.length === 0) return []\n return [`${heading}:`, ...items.map(item => `- ${item}`)]\n}\n\n/**\n * Deterministic Markdown rendering of a brief, capped at\n * `MISSION_BRIEF_RENDER_MAX_CHARS`. Same field order every call (goal,\n * constraints, done criteria, owned paths, handoff notes) so a snapshot test\n * or a worker reading two renders of the same brief sees no drift. If the\n * assembled text exceeds the cap, trailing sections are dropped whole (never\n * mid-line) until it fits, and a final `(brief truncated)` marker is appended\n * — a worker should never receive a block cut off mid-sentence.\n */\nexport function renderMissionBriefBlock(brief: MissionBrief): string {\n const sections: string[] = [`Mission goal: ${brief.goal}`]\n sections.push(...renderList('Constraints', brief.constraints))\n sections.push(...renderList('Done when', brief.doneCriteria))\n sections.push(...renderList('Owned paths', brief.ownedPaths))\n sections.push(...renderList('Handoff notes', brief.handoffNotes))\n\n const full = sections.join('\\n')\n if (full.length <= MISSION_BRIEF_RENDER_MAX_CHARS) return full\n\n // Drop whole lines from the end until it fits, then append the marker\n // (itself budgeted into the cap so the final string never exceeds it).\n const marker = '\\n(brief truncated)'\n const budget = MISSION_BRIEF_RENDER_MAX_CHARS - marker.length\n const lines = full.split('\\n')\n let acc = ''\n for (const line of lines) {\n const next = acc ? `${acc}\\n${line}` : line\n if (next.length > budget) break\n acc = next\n }\n if (!acc) acc = truncateString(lines[0] ?? '', Math.max(budget, 0))\n return `${acc}${marker}`\n}\n","/**\n * worker-protocol — what a delegated worker is told, and what it may call.\n *\n * Wiring-unification Phase F1 (docs/design/2026-09-23-wiring-unification.md §7b).\n *\n * Measured 2026-09-23 on the live preview ledger: 635 worker attempts in 14\n * days, 3 `report_completion` calls. The worker MCP was delivered to every\n * provider and never used, because nothing ever told the worker it existed —\n * the dispatched task body carried no instruction and the coordinator prompt\n * did not mention the worker tools at all. The only text a worker saw about\n * its tools was the tool description.\n *\n * This module is the single source for BOTH sides of that contract:\n * - `WORKER_TOOLS` — exactly what `adhdev mcp --mode worker` advertises\n * (a parity test in mcp-server pins ListTools to this tuple);\n * - `renderWorkerProtocolFooter()` — the block appended to EVERY dispatched\n * task body, so a worker learns the protocol from the task itself;\n * - `renderCoordinatorWorkerSection()` — the matching paragraph the\n * coordinator prompt carries, so the coordinator expects structured reports\n * and stops polling for them.\n *\n * Wiring-unification Phase H2 adds an optional mission-brief block: when a\n * dispatched task belongs to a mission that carries a `MissionBrief`\n * (`./mission-brief.ts`), `renderWorkerProtocolFooter` renders it ABOVE the\n * `WORKER_PROTOCOL_FOOTER_MARKER` line. This is deliberate placement, not an\n * accident of insertion order: `hasWorkerProtocolFooter` / `stripWorkerProtocolFooter`\n * both key off the marker line alone, so a body with a brief block strips\n * identically to one without — the brief is authored content from the\n * coordinator's point of view (like the task message itself), never part of\n * the protocol contract the marker demarcates.\n */\n\nimport { renderMissionBriefBlock, type MissionBrief } from './mission-brief'\nimport { isMeshTaskDifficulty } from './brain-routing'\n\nexport const WORKER_TOOLS = [\n 'report_completion',\n 'progress_update',\n 'peer_context_pull',\n 'git_status',\n 'git_log',\n 'git_diff',\n] as const\n\nexport type WorkerTool = typeof WORKER_TOOLS[number]\n\nconst WORKER_TOOL_SET: ReadonlySet<string> = new Set(WORKER_TOOLS)\n\nexport function isWorkerTool(value: unknown): value is WorkerTool {\n return typeof value === 'string' && WORKER_TOOL_SET.has(value)\n}\n\n/** Stable marker line so a body is never footered twice and tests can find it. */\nexport const WORKER_PROTOCOL_FOOTER_MARKER = '--- adhdev worker protocol ---'\n\nexport interface WorkerProtocolFooterInput {\n taskId?: string\n taskMode?: string\n difficulty?: string\n readonly?: boolean\n /** Number of handoff notes enclosed above the footer, when any. */\n enclosedHandoffNotes?: number\n /** H2: the owning mission's brief, when this task belongs to one. Rendered above the marker line — see module doc. */\n missionBrief?: MissionBrief\n /**\n * Whether the worker MCP (the `WORKER_TOOLS` surface) was actually delivered\n * to the receiving session — the launch-time `deriveWorkerMcpDeliveryStatus`\n * outcome. `false` renders the no-tools variant: the worker is told to end\n * with a plain final summary instead of being sent hunting for tools it does\n * not hold. Absent = unknown (e.g. a remote session) — the tool variant,\n * which is what every worker launched with the default gate receives.\n */\n workerMcp?: boolean\n}\n\nexport function hasWorkerProtocolFooter(body: string): boolean {\n return typeof body === 'string' && body.includes(WORKER_PROTOCOL_FOOTER_MARKER)\n}\n\n/**\n * The protocol block appended to a dispatched task. Written for the model that\n * receives it: imperative, short, and explicit about what is NOT available so\n * the worker does not go looking for coordinator tools.\n */\nexport function renderWorkerProtocolFooter(input: WorkerProtocolFooterInput = {}): string {\n const briefBlock = input.missionBrief ? renderMissionBriefBlock(input.missionBrief) : null\n const lines: string[] = briefBlock ? [briefBlock, '', WORKER_PROTOCOL_FOOTER_MARKER] : [WORKER_PROTOCOL_FOOTER_MARKER]\n const scope: string[] = []\n if (input.taskId) scope.push(`task ${input.taskId}`)\n if (input.taskMode) scope.push(`mode ${input.taskMode}`)\n // MCP-usage-audit item 2: validate against the canonical difficulty set\n // (this package's own brain-routing vocabulary — never duplicated here)\n // rather than rendering an internal caller's typo or stale value verbatim.\n // The MCP tool-schema enum already blocks a bad value AT THE TOOLS; this\n // covers internal callers that can still construct a task with one.\n if (input.difficulty) {\n if (isMeshTaskDifficulty(input.difficulty)) {\n scope.push(`difficulty ${input.difficulty}`)\n } else {\n // eslint-disable-next-line no-console -- mesh-shared is a dependency-free\n // leaf with no logger abstraction; this is the one place that matters.\n console.warn(\n `[worker-protocol] task ${input.taskId ?? '(unknown)'}: dropping invalid difficulty '${input.difficulty}' `\n + `from the worker footer (expected one of easy, medium, difficult, freeform)`,\n )\n }\n }\n if (input.readonly) scope.push('read-only')\n if (scope.length) lines.push(`You are a delegated worker (${scope.join(', ')}).`)\n else lines.push('You are a delegated worker.')\n if (input.workerMcp === false) {\n lines.push(\n 'This session has NO adhdev worker tools (`report_completion`, `progress_update`, `peer_context_pull`, '\n + '`git_*`) — do not look for them. When your work is finished, blocked, or has failed, end your turn '\n + 'with a plain final summary: what you did, what you found, which files you changed, and where you '\n + 'left the branch. That final message is what the coordinator receives.',\n 'You have no coordinator tools (no `mesh_*`) by design: do not enqueue, dispatch, or restart anything. '\n + 'If you need a decision from the coordinator, say so plainly in your final summary — what is blocked '\n + 'and what you need — and stop.',\n )\n if (input.enclosedHandoffNotes && input.enclosedHandoffNotes > 0) {\n lines.push(\n `The ${input.enclosedHandoffNotes} handoff note(s) above were written by agents who touched this code before you; `\n + 'honour their conflict guidance and mention anything the next agent should know in your final summary.',\n )\n }\n return lines.join('\\n')\n }\n lines.push(\n 'When your work is finished, blocked, or has failed, call `report_completion` exactly once. '\n + 'Its `summary` is recorded verbatim as the authoritative record of this task — your terminal is not '\n + 'scraped for it — so state what you did, what you found, and where you left the branch.',\n 'For work that runs longer than a few minutes, call `progress_update` at natural checkpoints so the '\n + 'coordinator can see you are alive without polling.',\n '`peer_context_pull` shows what sibling tasks in this mission have reported; `git_status` / `git_diff` / '\n + '`git_log` inspect your own workspace — all three REQUIRE the absolute path to it as `workspace`.',\n 'Memos from the coordinator arrive appended to the response of whichever worker tool you call next; '\n + 'read them and follow them.',\n 'You have no coordinator tools (no `mesh_*`) by design: do not enqueue, dispatch, or restart anything. '\n + 'If you need a decision from the coordinator, finish with `report_completion` and outcome `blocked`, '\n + 'listing what you need in `blockers`.',\n 'On a code-changing task, `report_completion` with outcome `completed` requires `touched_files` — send '\n + '`[]` if you changed nothing, omitting the field is what gets refused. `blocked`/`failed` never need it, '\n + 'and a read-only task should omit it or send `[]`.',\n 'If `report_completion` is refused, the response carries `validationErrors` (or a `hint`) naming exactly '\n + 'what to fix — correct that field and call it again; a refusal records nothing.',\n )\n if (input.enclosedHandoffNotes && input.enclosedHandoffNotes > 0) {\n lines.push(\n `The ${input.enclosedHandoffNotes} handoff note(s) above were written by agents who touched this code before you; `\n + 'honour their conflict guidance and add your own in `handoff_notes` when you report.',\n )\n }\n return lines.join('\\n')\n}\n\n/**\n * The authored text of a dispatched body: everything before the footer marker.\n * Ledger descriptors, replay fixtures and tests compare authored text, never\n * the protocol block.\n */\nexport function stripWorkerProtocolFooter(body: string): string {\n if (typeof body !== 'string') return body\n const at = body.indexOf(WORKER_PROTOCOL_FOOTER_MARKER)\n if (at < 0) return body\n return body.slice(0, at).replace(/\\s+$/, '')\n}\n\n/**\n * Append the footer to a body that does not carry one yet. Idempotent.\n */\nexport function appendWorkerProtocolFooter(body: string, input: WorkerProtocolFooterInput = {}): string {\n if (hasWorkerProtocolFooter(body)) return body\n const trimmed = body.replace(/\\s+$/, '')\n return `${trimmed}\\n\\n${renderWorkerProtocolFooter(input)}`\n}\n\n/**\n * The paragraph the COORDINATOR prompt carries about its workers. Kept next to\n * the footer so the two halves of the protocol cannot drift apart.\n */\nexport function renderCoordinatorWorkerSection(): string {\n return [\n '## Workers',\n '',\n `Every task you dispatch is delivered with a worker protocol footer. Workers hold exactly these tools: ${WORKER_TOOLS.map((tool) => `\\`${tool}\\``).join(', ')} — and no \\`mesh_*\\` tools.`,\n '- A worker finishes by calling `report_completion`; its structured report (outcome, summary, touched files, branch state, handoff notes) is what reaches you as the completion event. Read that report — do not re-derive the outcome from `mesh_read_chat` or the terminal unless the report is missing.',\n '- `progress_update` from a worker arrives as a lightweight progress note. Do NOT poll `mesh_status`, `mesh_view_queue` or `mesh_read_chat` to check on a running worker; completion, progress, blocked and failure all arrive as events.',\n '- To reach a busy worker mid-task use `mesh_notify_worker`: the memo is delivered on the worker\\'s next tool call (or when it becomes idle). A worker that reports `blocked` is asking you for a decision — answer it with `mesh_send_task` to the same session.',\n '- `mesh_status` is for node health and capacity before delegating, never for progress.',\n '- A `code_change` task\\'s declared `owned_paths` (H1) is enforced at claim time: a second `code_change` task whose `owned_paths` overlaps an already-claimed task\\'s is refused rather than silently racing it. A worker\\'s `report_completion.touched_files` is compared against its own task\\'s declaration afterward and any mismatch is surfaced back to you as evidence — it is never a validation failure, since a worker often cannot know its exact final file list at enqueue time.',\n ].join('\\n')\n}\n","/**\n * assistant-protocol — the assistant layer's tool and daemon-verb names\n * (docs/design/2026-10-07-assistant-layer.md §4.4).\n *\n * The single source for both halves of the assistant contract, like\n * `WORKER_TOOLS` is for workers:\n * - `ASSISTANT_TOOLS` — exactly what `adhdev mcp --assistant` will advertise\n * (an mcp-server parity test pins ListTools to this tuple once that mode\n * lands);\n * - `ASSISTANT_TOOL_VERBS` — the daemon command each tool calls;\n * - the daemon-only verbs (launch / MCP-only pull / owner actions) that have\n * no tool.\n *\n * Assistant tools are a separate set from the mesh tools: none of these names\n * belongs in `CANONICAL_MESH_TOOL_NAMES`, and the coordinator/worker MCP modes\n * never publish them.\n */\n\nexport const ASSISTANT_TOOLS = [\n 'projects',\n 'project_status',\n 'project_send',\n 'project_read',\n 'project_add',\n 'discover_repos',\n 'memory',\n 'skill_view',\n 'skill_manage',\n 'project_note',\n] as const\n\nexport type AssistantTool = typeof ASSISTANT_TOOLS[number]\n\nconst ASSISTANT_TOOL_SET: ReadonlySet<string> = new Set(ASSISTANT_TOOLS)\n\nexport function isAssistantTool(value: unknown): value is AssistantTool {\n return typeof value === 'string' && ASSISTANT_TOOL_SET.has(value)\n}\n\n/** Daemon verb names (§4.4 table + the five verbs below it). */\nexport const ASSISTANT_VERB = {\n // tool verbs\n projects: 'assistant_projects',\n projectStatus: 'assistant_project_status',\n projectSend: 'assistant_project_send',\n projectRead: 'assistant_project_read',\n projectAdd: 'assistant_project_add',\n discoverRepos: 'assistant_discover_repos',\n memory: 'assistant_memory',\n skillView: 'assistant_skill_view',\n skillManage: 'assistant_skill_manage',\n projectNote: 'assistant_project_note',\n // assistant-side daemon verbs without a tool of the same name\n launch: 'launch_assistant',\n pendingRelays: 'assistant_pending_relays',\n // owner verbs (dashboard only)\n stagedResolve: 'assistant_staged_resolve',\n storeAdmin: 'assistant_store_admin',\n importSkills: 'assistant_import_skills',\n} as const\n\nexport type AssistantVerb = typeof ASSISTANT_VERB[keyof typeof ASSISTANT_VERB]\n\n/** The daemon verb each assistant tool calls. */\nexport const ASSISTANT_TOOL_VERBS: Readonly<Record<AssistantTool, AssistantVerb>> = {\n projects: ASSISTANT_VERB.projects,\n project_status: ASSISTANT_VERB.projectStatus,\n project_send: ASSISTANT_VERB.projectSend,\n project_read: ASSISTANT_VERB.projectRead,\n project_add: ASSISTANT_VERB.projectAdd,\n discover_repos: ASSISTANT_VERB.discoverRepos,\n memory: ASSISTANT_VERB.memory,\n skill_view: ASSISTANT_VERB.skillView,\n skill_manage: ASSISTANT_VERB.skillManage,\n project_note: ASSISTANT_VERB.projectNote,\n}\n\n/**\n * Tools annotated as writes; every other assistant tool is read-only. §4.4\n * lists the three store writes; project_send and project_add are here too\n * because they cause effects (a coordinator message or launch, a new\n * project), and MCP clients use readOnlyHint to skip confirmation.\n */\nexport const ASSISTANT_WRITE_TOOLS: readonly AssistantTool[] = ['memory', 'skill_manage', 'project_note', 'project_send', 'project_add']\n\n/** Owner-only verbs: never reachable from the assistant's MCP server (no `ipc`). */\nexport const ASSISTANT_OWNER_VERBS: readonly AssistantVerb[] = [\n ASSISTANT_VERB.stagedResolve,\n ASSISTANT_VERB.storeAdmin,\n ASSISTANT_VERB.importSkills,\n]\n\n/** The only assistant verbs accepted while an idle review turn is open (§4.10.7). */\nexport const ASSISTANT_REVIEW_TURN_VERBS: readonly AssistantVerb[] = [\n ASSISTANT_VERB.memory,\n ASSISTANT_VERB.skillView,\n ASSISTANT_VERB.skillManage,\n ASSISTANT_VERB.projectNote,\n]\n\n/**\n * Env var the daemon sets on the assistant CLI's process (§4.5), read by the\n * assistant MCP server and forwarded on every verb as\n * `ASSISTANT_SESSION_ID_ARG`. Routing / ownership only — never an auth gate.\n */\nexport const ASSISTANT_SESSION_ID_ENV = 'ADHDEV_ASSISTANT_SESSION_ID'\n\n/** Request arg carrying the calling assistant session id. */\nexport const ASSISTANT_SESSION_ID_ARG = 'assistantSessionId'\n","/**\n * turn-evidence — the ONE vocabulary for \"what happened to a turn\".\n *\n * Wiring-unification Phase C1 (docs/design/2026-09-23-wiring-unification.md §5).\n *\n * Every producer that today decides \"done\" on its own (completion flush, stall\n * rescue, reconcile synthesis, MCP probes, worker report tools, …) instead\n * submits one of these evidence records to the turn ledger, whose pure reducer\n * is the only authority for a turn's state. Worker daemons and the MCP server\n * build them, so the types live here (a dependency-free leaf).\n *\n * CONTENT-FREE BY CONSTRUCTION\n * ----------------------------\n * Evidence crosses machines (seqscribe `mesh.<id>.events` replication) and must\n * never carry anything a user or an agent wrote. Every field is one of: an\n * identifier, a closed enum, a boolean, a number, or a `SummaryRef` — a pointer\n * `{topic, writer, seq}` to a content-class topic entry (`mesh.<id>.handoff`)\n * where the text actually lives. `TURN_EVIDENCE_FIELD_SPECS` declares the class\n * of every field of every member (the compiler forces it to stay total and\n * exact), the runtime guard validates against it, and a test walks it to prove\n * no free-text field exists.\n */\n\nimport { WORKER_BRANCH_STATES, WORKER_REPORT_OUTCOMES, type WorkerBranchState, type WorkerReportOutcome } from './mesh-vocabulary'\nimport { SESSION_STATUSES, type SessionStatus } from './session-status'\nimport { SEND_REFUSAL_REASONS, type SendRefusal } from './outbound-message'\n\n// ─── closed vocabularies ─────────────────────────────────────────────────\n\n/** Protocol version stamped on every `mesh.<id>.events` entry written by the turn ledger. */\nexport const MESH_TOPIC_PROTOCOL_VERSION = 2 as const\n\nexport const EVIDENCE_SOURCE_IDS = [\n 'fsm_edge', 'short_gen_inline', 'completion_flush_genuine', 'completion_flush_weak',\n 'monitor_final_summary', 'pre_cleanup_transcript', 'stall_transcript', 'startup_grace_collapse',\n 'acp_prompt_response', 'cdp_state', 'approval_gate', 'modal_button',\n 'mesh_stall_watchdog', 'status_monitor', 'pty_exit', 'provider_error',\n 'coordinator_probe', 'mcp_probe', 'worker_tool', 'dispatch', 'input_service',\n 'operator', 'intentional_cleanup', 'scheduler', 'git_probe', 'session_registry',\n] as const\nexport type EvidenceSourceId = typeof EVIDENCE_SOURCE_IDS[number]\n\nexport const TURN_SCOPES = ['mesh_queue', 'mesh_direct', 'plain'] as const\nexport type TurnScope = typeof TURN_SCOPES[number]\n\n/**\n * Refusals (D1 `SendRefusal`, owned by ./outbound-message) that mean the target\n * can never take this dispatch, so the attempt is reclaimed (R3). Every other\n * refusal is retried by the sender and only recorded.\n */\nexport const RECLAIMING_SEND_REFUSALS = ['session_exited', 'no_target', 'unsupported_input'] as const satisfies readonly SendRefusal[]\nexport type ReclaimingSendRefusal = typeof RECLAIMING_SEND_REFUSALS[number]\n\nexport const DELIVERY_OUTCOMES = ['delivered', 'queued'] as const\nexport type DeliveryOutcome = typeof DELIVERY_OUTCOMES[number]\nexport const DELIVERY_VIAS = ['local', 'p2p'] as const\nexport type DeliveryVia = typeof DELIVERY_VIAS[number]\n\nexport const DISPATCH_FAILURE_REASONS = ['worker_absent', 'transport_error', 'spawn_failed', 'rejected_by_worker', 'timeout'] as const\nexport type DispatchFailureReason = typeof DISPATCH_FAILURE_REASONS[number]\n\n/**\n * Normalize a worker's own refusal code (e.g. `session_busy_with_task`,\n * `mesh_sender_not_on_roster`, `provider_quota_exhausted`) into the shape\n * `dispatch_failed.refusalCode` accepts: lowercase ascii + underscore, capped\n * at 64 chars. Returns undefined for anything that yields no usable token, so\n * a malformed/foreign code degrades to \"no refusalCode\" rather than smuggling\n * arbitrary text through what must stay a closed-enum-like identifier slot\n * (see the field's doc comment — this evidence replicates cross-machine).\n */\nexport function sanitizeRefusalCode(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined\n const normalized = value.trim().toLowerCase().replace(/[^a-z_]/g, '_').replace(/_+/g, '_').replace(/^_+|_+$/g, '')\n if (!normalized) return undefined\n return normalized.slice(0, 64)\n}\n\nexport const CONSUME_PROFILES = ['default', 'native_source'] as const\nexport type ConsumeProfile = typeof CONSUME_PROFILES[number]\n\nexport const SESSION_REBOUND_REASONS = ['restart', 'live_holder'] as const\nexport type SessionReboundReason = typeof SESSION_REBOUND_REASONS[number]\n\nexport const SUSPENSION_MODALS = ['approval', 'choice'] as const\nexport type SuspensionModal = typeof SUSPENSION_MODALS[number]\nexport const SUSPENSION_RESOLUTIONS = ['approved', 'rejected', 'answered'] as const\nexport type SuspensionResolution = typeof SUSPENSION_RESOLUTIONS[number]\nexport const SUSPENSION_RESOLUTION_VIAS = ['modal_button', 'auto_approve', 'prompt_answer'] as const\nexport type SuspensionResolutionVia = typeof SUSPENSION_RESOLUTION_VIAS[number]\n\nexport const TURN_END_STRENGTHS = ['genuine', 'weak'] as const\nexport type TurnEndStrength = typeof TURN_END_STRENGTHS[number]\n\n/** Why a provider-side weak end was released (was free text `blockReason`). */\nexport const TURN_END_BLOCK_REASONS = [\n 'missing_final_assistant', 'finalization_timeout', 'terminal_block_hard_cap', 'decoupled_completion',\n] as const\nexport type TurnEndBlockReason = typeof TURN_END_BLOCK_REASONS[number]\n\nexport const NATIVE_TURN_OUTCOMES = ['completed', 'aborted'] as const\nexport type NativeTurnOutcome = typeof NATIVE_TURN_OUTCOMES[number]\n\nexport const LIVENESS_RESULTS = ['alive', 'unknown', 'read_failed', 'dead'] as const\nexport type LivenessResult = typeof LIVENESS_RESULTS[number]\n\nexport const PROVIDER_FAILURES = ['auth_failed', 'billing_failed'] as const\nexport type ProviderFailure = typeof PROVIDER_FAILURES[number]\n\n/**\n * `daemon_restart` (wiring-unification follow-up, design §5): boot-time\n * reconciliation observes this for a plain attempt that was open when the\n * daemon restarted — either its session is gone, or the session was restored\n * live but the turn in flight was cut by the restart. The daemon never saw\n * the session's own exit or commit, so it is not `provider_error` /\n * `adapter_error` / etc.; it is the daemon itself closing a turn it can no\n * longer follow.\n */\nexport const SESSION_ERROR_REASONS = ['provider_error', 'adapter_error', 'spawn_failed', 'auth_failed', 'billing_failed', 'unknown', 'daemon_restart'] as const\nexport type SessionErrorReason = typeof SESSION_ERROR_REASONS[number]\n\nexport const CANCEL_REASONS = ['operator_cancel', 'intentional_cleanup', 'task_removed', 'mission_abandoned', 'superseded'] as const\nexport type CancelReason = typeof CANCEL_REASONS[number]\n\nexport const OPERATOR_STATUSES = ['completed', 'failed'] as const\nexport type OperatorStatus = typeof OPERATOR_STATUSES[number]\nexport const OPERATOR_STATUS_REASONS = ['operator_update', 'refine_terminal', 'validation_terminal'] as const\nexport type OperatorStatusReason = typeof OPERATOR_STATUS_REASONS[number]\n\nexport const COORDINATOR_ACK_OUTCOMES = ['delivered', 'queued', 'duplicate'] as const\nexport type CoordinatorAckOutcome = typeof COORDINATOR_ACK_OUTCOMES[number]\n\n/** Observed status as a no-progress monitor saw it (canonical session status or `unknown`). */\nexport const NO_PROGRESS_OBSERVED_STATUSES = [...SESSION_STATUSES, 'unknown'] as const\nexport type NoProgressObservedStatus = SessionStatus | 'unknown'\n\n/**\n * Reasons a turn hold exists. Holds are attempt-scoped only (C2: delivery-side\n * waits are consumer deferral on the `turn.deliver` cursor, not hold rows).\n */\nexport const HOLD_REASONS = [\n 'await_delivery', 'await_consume', 'await_turn', 'liveness', 'hard_ceiling',\n 'live_pending', 'transcript_quiet', 'weak_candidate', 'suspension_before_consumed',\n // A genuine FSM end of a mesh turn whose worker holds a live worker-MCP bind:\n // the structured report is the primary evidence (design §F2), so the idle edge\n // only opens this hold (R9r) — a report commits (R17), a new busy edge cancels\n // it as a false idle (R12r), expiry commits weak (R13r).\n 'await_report',\n // A worker report recorded while the session is still generating (R17g):\n // the report is the verdict, the idle edge is only awaited as corroboration\n // — a turn_end commits the report (R9t), expiry commits it anyway (R13t) so\n // a session whose FSM never shows the idle edge again does not wait for\n // liveness / hard_ceiling.\n 'await_end',\n] as const\nexport type HoldReason = typeof HOLD_REASONS[number]\n\nexport const TURN_OUTCOMES = ['completed', 'failed', 'cancelled'] as const\nexport type TurnOutcome = typeof TURN_OUTCOMES[number]\n\nexport const COMMIT_STRENGTHS = ['genuine', 'weak', 'tool_report', 'operator'] as const\nexport type CommitStrength = typeof COMMIT_STRENGTHS[number]\n\n/** Every terminal or reclaim reason the ledger writes. Closed: no free-text reasons. */\nexport const TURN_REASONS = [\n // commits\n 'turn_end', 'weak_end_confirmed', 'transcript_final', 'worker_reported',\n 'finalization_timeout_no_response', 'session_error', 'provider_auth_failed', 'provider_billing_failed',\n 'operator_cancel', 'intentional_cleanup', 'task_removed', 'mission_abandoned', 'superseded',\n 'operator_update', 'refine_terminal', 'validation_terminal',\n 'hard_ceiling', 'reclaim_budget_exhausted', 'hollow_max_retries', 'migration_orphan',\n // reclaims (generation + 1)\n 'dispatch_refused_session_exited', 'dispatch_refused_no_target', 'dispatch_refused_unsupported_input', 'dispatch_failed',\n 'session_exit', 'session_exit_before_turn', 'session_dead', 'hollow_completion',\n 'assigned_stranded_dispatch_unconfirmed', 'delivered_not_consumed_redrive', 'delivered_no_turn_deadline',\n] as const\nexport type TurnReason = typeof TURN_REASONS[number]\n\n/**\n * What a `turn.notify` entry tells a coordinator.\n *\n * `late_completion` (C1 R27, owner revision 2026-09-23): a superseded\n * generation finished while the current one was already running; the\n * coordinator decides whether to salvage it (the entry carries the g−1\n * summary as its append `ref`). `mesh_event`: a non-turn coordinator notice\n * (refine terminal, worktree bootstrap, …) whose text lives only in the\n * owner's local `turn_events.payload_json` and is rendered at deliver time.\n */\nexport const NOTIFY_KINDS = [\n 'completed', 'failed', 'cancelled', 'stopped', 'approval', 'choice', 'approval_resolved',\n 'candidate', 'no_progress', 'progress', 'late_completion', 'mesh_event',\n] as const\nexport type NotifyKind = typeof NOTIFY_KINDS[number]\n\n// ─── shared shapes ───────────────────────────────────────────────────────\n\nexport interface TurnAttemptRef { attemptId: string; generation: number }\n\n/**\n * Pointer to text that lives in a content-class topic entry (`mesh.<id>.handoff`).\n * Text never travels inside evidence; the deliver side renders it from the ref.\n */\nexport interface SummaryRef { topic: string; writer: string; seq: number }\n\n/** Live-state observations that make a transcript end premature (admission input). */\nexport interface LiveTurnPending { modal: boolean; adapterPending: boolean; trailingTool: boolean; newestActivityAt?: number }\n\n/** Structural copy of daemon-core's `CoordinatorIdentity` (this package cannot import daemon-core). */\nexport interface EvidenceCoordinatorIdentity { daemonId: string; coordinatorRunId: string; sessionId?: string }\n\nexport interface NativeTurnMarkerRef { outcome: NativeTurnOutcome; turnId?: string }\n\nexport interface EvidenceEnvelope {\n /** Stable id of this observation; dedupe key across republish/replication. */\n eventId: string\n /** Producer clock, epoch ms. */\n at: number\n source: EvidenceSourceId\n /** The session that produced / is the subject of the observation. */\n sessionId: string\n attemptRef?: TurnAttemptRef\n /** Only when attemptRef is absent (legacy relay / MCP probe). */\n taskId?: string\n /** Daemon id that observed it. */\n observedBy: string\n}\n\n/** Kind-specific bodies. `TurnEvidence = EvidenceEnvelope & TurnEvidenceBody`. */\nexport type TurnEvidenceBody =\n // ── dispatch / delivery ──\n | { kind: 'dispatch_accepted'; scope: TurnScope; messageId: string; meshId?: string; nodeId?: string; providerType?: string\n attemptNo?: number; dispatchNonce?: number; consumeProfile?: ConsumeProfile; maxTaskRetries?: number\n coordinator?: EvidenceCoordinatorIdentity }\n | { kind: 'delivered'; messageId: string; outcome: DeliveryOutcome; via: DeliveryVia }\n | { kind: 'delivery_refused'; messageId: string; reason: SendRefusal }\n /**\n * `refusalCode` (wiring-unification live-gap fix, 2026-09-25): the worker's own\n * refusal code for an application-level `{success:false}` answer (e.g.\n * `session_busy_with_task`, `mesh_sender_not_on_roster`,\n * `mesh_node_bootstrap_pending`, `provider_quota_exhausted`) — optional and\n * ONLY ever populated for `reason: 'rejected_by_worker'`. Deliberately an `id`\n * (short enum-like token), never free text: this evidence replicates across\n * machines over `mesh.<id>.events` (CONTENT-FREE BY CONSTRUCTION above), so a\n * human-readable detail string must NOT travel here — it stays local (owner\n * WARN log, MCP tool JSON response). Producers sanitize to `[a-z_]{1,64}`\n * before emitting so a stray free-text code can never smuggle prose through\n * this slot.\n */\n | { kind: 'dispatch_failed'; workerAbsent: boolean; reason: DispatchFailureReason; refusalCode?: string }\n | { kind: 'duplicate_dispatch_refusal'; holderSessionId: string; holderAttemptId?: string }\n | { kind: 'session_rebound'; toSessionId: string; reason: SessionReboundReason }\n // ── worker turn lifecycle ──\n | { kind: 'turn_started'; retro: boolean }\n | { kind: 'suspension'; modal: SuspensionModal; modalKey?: string }\n | { kind: 'suspension_resolved'; resolution: SuspensionResolution; via: SuspensionResolutionVia }\n | { kind: 'turn_end'; strength: TurnEndStrength; afterFinalizationTimeout?: boolean; hollow?: boolean; summary?: SummaryRef\n blockReason?: TurnEndBlockReason; releasedByHardCap?: boolean; nativeOutcome?: NativeTurnOutcome; live?: LiveTurnPending\n /**\n * Stamped (true only) by the WORKER's daemon when the session holds a live\n * worker-MCP session bind, i.e. the worker can call report_completion. The\n * owner then treats a genuine end as a report-awaiting candidate (R9r), not\n * a commit. Absent = no reporting surface = today's genuine-end commit.\n */\n reportExpected?: boolean\n /**\n * Stamped by the WORKER's daemon when the turn's whole reply is a provider\n * auth/billing failure banner (claude-cli \"Login expired · Please run\n * /login\", 2026-10-06 preview incident). The owner commits the attempt\n * `failed / provider_auth_failed` (R9f) instead of reading the idle edge\n * as a completion. Closed enum — the banner text itself never travels.\n */\n providerFailure?: ProviderFailure }\n | { kind: 'transcript_final'; selfAttributing: boolean; nativeRead: boolean; nativeMarker?: NativeTurnMarkerRef\n live: LiveTurnPending; summary?: SummaryRef; messageAt?: number }\n | { kind: 'transcript_activity'; newestActivityAt: number }\n | { kind: 'no_progress'; stalledMs: number; observedStatus: NoProgressObservedStatus; finalAssistantPresent: boolean }\n | { kind: 'liveness'; result: LivenessResult }\n | { kind: 'process_exit'; exitCode: number | null; providerFailure?: ProviderFailure }\n | { kind: 'session_error'; reason: SessionErrorReason }\n // ── worker MCP (F2) ──\n /**\n * `summary` is the handoff-topic pointer when the report's text was published;\n * a report the owner daemon accepted itself carries its text in the evidence\n * row's local envelope instead (never published), so the pointer is optional.\n */\n | { kind: 'worker_report'; outcome: WorkerReportOutcome; summary?: SummaryRef; hasHandoffNotes: boolean\n branchState?: WorkerBranchState; touchedFileCount?: number }\n | { kind: 'worker_progress'; note?: SummaryRef }\n // ── coordinator / operator ──\n | { kind: 'git_side_effect'; dirty: boolean; commitsSinceDispatch: number; attributable: boolean }\n | { kind: 'cancel'; reason: CancelReason }\n | { kind: 'operator_status'; status: OperatorStatus; reason: OperatorStatusReason }\n | { kind: 'coordinator_ack'; notify: NotifyKind; outcome: CoordinatorAckOutcome }\n // ── scheduler-generated ──\n | { kind: 'hold_expired'; holdId: string; reason: HoldReason }\n\nexport type TurnEvidence = EvidenceEnvelope & TurnEvidenceBody\nexport type TurnEvidenceKind = TurnEvidenceBody['kind']\nexport type TurnEvidenceOf<K extends TurnEvidenceKind> = EvidenceEnvelope & Extract<TurnEvidenceBody, { kind: K }>\n\n// ─── field-class registry (drives the guard and the content-free test) ────\n\n/**\n * The class of every declared field. There is deliberately NO free-text class:\n * `id` strings are length-bounded and whitespace-free, so prose cannot be\n * smuggled through an identifier slot either.\n */\nexport type EvidenceFieldSpec =\n | { t: 'id'; optional?: true }\n | { t: 'enum'; values: readonly string[]; optional?: true }\n | { t: 'bool'; optional?: true }\n | { t: 'int'; optional?: true; nullable?: true }\n | { t: 'ms'; optional?: true }\n | { t: 'summary_ref'; optional?: true }\n | { t: 'attempt_ref'; optional?: true }\n | { t: 'live'; optional?: true }\n | { t: 'native_marker'; optional?: true }\n | { t: 'coordinator'; optional?: true }\n\ntype FieldsOf<K extends TurnEvidenceKind> = Exclude<keyof Extract<TurnEvidenceBody, { kind: K }>, 'kind'>\n/** Exact per-kind registry: a missing or extra field fails to compile. */\nexport type TurnEvidenceFieldSpecs = { readonly [K in TurnEvidenceKind]: { readonly [F in FieldsOf<K>]-?: EvidenceFieldSpec } }\n\nconst id = { t: 'id' } as const\nconst idOpt = { t: 'id', optional: true } as const\nconst bool = { t: 'bool' } as const\nconst boolOpt = { t: 'bool', optional: true } as const\nconst ms = { t: 'ms' } as const\nconst msOpt = { t: 'ms', optional: true } as const\nconst intOpt = { t: 'int', optional: true } as const\nconst en = (values: readonly string[]) => ({ t: 'enum', values }) as const\nconst enOpt = (values: readonly string[]) => ({ t: 'enum', values, optional: true }) as const\n\nexport const EVIDENCE_ENVELOPE_FIELD_SPECS: { readonly [F in keyof EvidenceEnvelope]-?: EvidenceFieldSpec } = {\n eventId: id,\n at: ms,\n source: en(EVIDENCE_SOURCE_IDS),\n sessionId: id,\n attemptRef: { t: 'attempt_ref', optional: true },\n taskId: idOpt,\n observedBy: id,\n}\n\nexport const TURN_EVIDENCE_FIELD_SPECS: TurnEvidenceFieldSpecs = {\n dispatch_accepted: {\n scope: en(TURN_SCOPES), messageId: id, meshId: idOpt, nodeId: idOpt, providerType: idOpt,\n attemptNo: intOpt, dispatchNonce: intOpt, consumeProfile: enOpt(CONSUME_PROFILES), maxTaskRetries: intOpt,\n coordinator: { t: 'coordinator', optional: true },\n },\n delivered: { messageId: id, outcome: en(DELIVERY_OUTCOMES), via: en(DELIVERY_VIAS) },\n delivery_refused: { messageId: id, reason: en(SEND_REFUSAL_REASONS) },\n dispatch_failed: { workerAbsent: bool, reason: en(DISPATCH_FAILURE_REASONS), refusalCode: idOpt },\n duplicate_dispatch_refusal: { holderSessionId: id, holderAttemptId: idOpt },\n session_rebound: { toSessionId: id, reason: en(SESSION_REBOUND_REASONS) },\n turn_started: { retro: bool },\n suspension: { modal: en(SUSPENSION_MODALS), modalKey: idOpt },\n suspension_resolved: { resolution: en(SUSPENSION_RESOLUTIONS), via: en(SUSPENSION_RESOLUTION_VIAS) },\n turn_end: {\n strength: en(TURN_END_STRENGTHS), afterFinalizationTimeout: boolOpt, hollow: boolOpt,\n summary: { t: 'summary_ref', optional: true }, blockReason: enOpt(TURN_END_BLOCK_REASONS),\n releasedByHardCap: boolOpt, nativeOutcome: enOpt(NATIVE_TURN_OUTCOMES), live: { t: 'live', optional: true },\n reportExpected: boolOpt, providerFailure: enOpt(PROVIDER_FAILURES),\n },\n transcript_final: {\n selfAttributing: bool, nativeRead: bool, nativeMarker: { t: 'native_marker', optional: true },\n live: { t: 'live' }, summary: { t: 'summary_ref', optional: true }, messageAt: msOpt,\n },\n transcript_activity: { newestActivityAt: ms },\n no_progress: { stalledMs: ms, observedStatus: en(NO_PROGRESS_OBSERVED_STATUSES), finalAssistantPresent: bool },\n liveness: { result: en(LIVENESS_RESULTS) },\n process_exit: { exitCode: { t: 'int', nullable: true }, providerFailure: enOpt(PROVIDER_FAILURES) },\n session_error: { reason: en(SESSION_ERROR_REASONS) },\n worker_report: {\n outcome: en(WORKER_REPORT_OUTCOMES), summary: { t: 'summary_ref', optional: true }, hasHandoffNotes: bool,\n branchState: enOpt(WORKER_BRANCH_STATES), touchedFileCount: intOpt,\n },\n worker_progress: { note: { t: 'summary_ref', optional: true } },\n git_side_effect: { dirty: bool, commitsSinceDispatch: { t: 'int' }, attributable: bool },\n cancel: { reason: en(CANCEL_REASONS) },\n operator_status: { status: en(OPERATOR_STATUSES), reason: en(OPERATOR_STATUS_REASONS) },\n coordinator_ack: { notify: en(NOTIFY_KINDS), outcome: en(COORDINATOR_ACK_OUTCOMES) },\n hold_expired: { holdId: id, reason: en(HOLD_REASONS) },\n}\n\nexport const TURN_EVIDENCE_KINDS = Object.keys(TURN_EVIDENCE_FIELD_SPECS) as readonly TurnEvidenceKind[]\n\n/** Evidence kinds that, on their own, can end a turn (the ones R18/R19/R27 reason about). */\nexport const TERMINAL_CLASS_EVIDENCE_KINDS = [\n 'turn_end', 'transcript_final', 'no_progress', 'worker_report', 'session_error', 'process_exit', 'cancel', 'operator_status',\n] as const satisfies readonly TurnEvidenceKind[]\n\n// ─── guards ──────────────────────────────────────────────────────────────\n\n/** Identifier shape: 1..256 chars, no whitespace or control characters. */\nconst IDENTIFIER_RE = /^[^\\s\\u0000-\\u001f\\u007f]{1,256}$/\n\nfunction makeGuard<T extends readonly string[]>(values: T): (value: unknown) => value is T[number] {\n const set: ReadonlySet<string> = new Set(values)\n return (value: unknown): value is T[number] => typeof value === 'string' && set.has(value)\n}\n\nexport const isTurnEvidenceKind = makeGuard(TURN_EVIDENCE_KINDS as readonly TurnEvidenceKind[])\nexport const isTurnReason = makeGuard(TURN_REASONS)\nexport const isNotifyKind = makeGuard(NOTIFY_KINDS)\nexport const isTurnOutcome = makeGuard(TURN_OUTCOMES)\nexport const isCommitStrength = makeGuard(COMMIT_STRENGTHS)\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nexport function isEvidenceIdentifier(value: unknown): value is string {\n return typeof value === 'string' && IDENTIFIER_RE.test(value)\n}\n\nfunction isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n\nexport function isSummaryRef(value: unknown): value is SummaryRef {\n return isRecord(value)\n && hasOnlyKeys(value, ['topic', 'writer', 'seq'])\n && isEvidenceIdentifier(value.topic)\n && isEvidenceIdentifier(value.writer)\n && Number.isSafeInteger(value.seq) && (value.seq as number) >= 0\n}\n\nexport function isTurnAttemptRef(value: unknown): value is TurnAttemptRef {\n return isRecord(value)\n && hasOnlyKeys(value, ['attemptId', 'generation'])\n && isEvidenceIdentifier(value.attemptId)\n && Number.isSafeInteger(value.generation) && (value.generation as number) >= 0\n}\n\nfunction isLiveTurnPending(value: unknown): value is LiveTurnPending {\n return isRecord(value)\n && hasOnlyKeys(value, ['modal', 'adapterPending', 'trailingTool', 'newestActivityAt'])\n && typeof value.modal === 'boolean'\n && typeof value.adapterPending === 'boolean'\n && typeof value.trailingTool === 'boolean'\n && (value.newestActivityAt === undefined || isFiniteNumber(value.newestActivityAt))\n}\n\nfunction isNativeMarkerRef(value: unknown): value is NativeTurnMarkerRef {\n return isRecord(value)\n && hasOnlyKeys(value, ['outcome', 'turnId'])\n && (NATIVE_TURN_OUTCOMES as readonly string[]).includes(value.outcome as string)\n && (value.turnId === undefined || isEvidenceIdentifier(value.turnId))\n}\n\nfunction isCoordinatorIdentity(value: unknown): value is EvidenceCoordinatorIdentity {\n return isRecord(value)\n && hasOnlyKeys(value, ['daemonId', 'coordinatorRunId', 'sessionId'])\n && isEvidenceIdentifier(value.daemonId)\n && isEvidenceIdentifier(value.coordinatorRunId)\n && (value.sessionId === undefined || isEvidenceIdentifier(value.sessionId))\n}\n\nfunction hasOnlyKeys(value: Record<string, unknown>, allowed: readonly string[]): boolean {\n for (const key of Object.keys(value)) {\n if (!allowed.includes(key)) return false\n }\n return true\n}\n\nfunction fieldMatches(spec: EvidenceFieldSpec, value: unknown): boolean {\n if (value === undefined) return spec.optional === true\n switch (spec.t) {\n case 'id': return isEvidenceIdentifier(value)\n case 'enum': return typeof value === 'string' && spec.values.includes(value)\n case 'bool': return typeof value === 'boolean'\n case 'int': return (value === null && spec.nullable === true) || Number.isSafeInteger(value)\n case 'ms': return isFiniteNumber(value) && value >= 0\n case 'summary_ref': return isSummaryRef(value)\n case 'attempt_ref': return isTurnAttemptRef(value)\n case 'live': return isLiveTurnPending(value)\n case 'native_marker': return isNativeMarkerRef(value)\n case 'coordinator': return isCoordinatorIdentity(value)\n }\n}\n\n/**\n * Strict structural guard: known kind, every declared field of the right class,\n * and NO undeclared field (an unknown key is how free text would sneak in).\n */\nexport function isTurnEvidence(value: unknown): value is TurnEvidence {\n if (!isRecord(value) || !isTurnEvidenceKind(value.kind)) return false\n const bodySpecs = TURN_EVIDENCE_FIELD_SPECS[value.kind] as Record<string, EvidenceFieldSpec>\n const envelopeSpecs = EVIDENCE_ENVELOPE_FIELD_SPECS as Record<string, EvidenceFieldSpec>\n for (const key of Object.keys(value)) {\n if (key === 'kind') continue\n if (!(key in bodySpecs) && !(key in envelopeSpecs)) return false\n }\n for (const [key, spec] of Object.entries(envelopeSpecs)) {\n if (!fieldMatches(spec, value[key])) return false\n }\n for (const [key, spec] of Object.entries(bodySpecs)) {\n if (!fieldMatches(spec, value[key])) return false\n }\n return true\n}\n\n\n// ─── mesh.<id>.events topic entries (C2) ─────────────────────────────────\n\nexport const TURN_EVIDENCE_FLAGS = ['hollow', 'afterFinalizationTimeout', 'nativeMarker', 'selfAttributing'] as const\nexport type TurnEvidenceFlag = typeof TURN_EVIDENCE_FLAGS[number]\n\n/** Scalar-only payload for `mesh.record` (the existing allow-list projection's output). */\nexport type ProjectedScalars = Readonly<Record<string, string | number | boolean | null>>\n\nexport const MESH_TOPIC_ENTRY_KINDS = ['turn.evidence', 'turn.committed', 'turn.notify', 'mesh.record'] as const\nexport type MeshTopicEntryKind = typeof MESH_TOPIC_ENTRY_KINDS[number]\n\nexport type MeshTopicEntry = { v: typeof MESH_TOPIC_PROTOCOL_VERSION; eventId: string; at: number } & (\n | { k: 'turn.evidence'; attemptId: string; generation: number; ownerDaemonId: string; taskId?: string; sessionId: string\n ev: TurnEvidenceKind; strength?: TurnEndStrength; flags?: Partial<Record<TurnEvidenceFlag, boolean>>\n /** The full (content-free) evidence, so a foreign `turn.ingest` can re-observe it losslessly. */\n evidence?: TurnEvidence }\n | { k: 'turn.committed'; attemptId: string; generation: number; taskId?: string; outcome: TurnOutcome; strength: CommitStrength; reason: TurnReason }\n | { k: 'turn.notify'; attemptId?: string; notify: NotifyKind; targetDaemonId: string; targetSessionId?: string; taskId?: string }\n | { k: 'mesh.record'; ledgerKind: string; nodeId?: string; sessionId?: string; taskId?: string; payload: ProjectedScalars }\n)\n\n\nfunction isOptionalId(value: unknown): boolean {\n return value === undefined || isEvidenceIdentifier(value)\n}\n\nfunction isGeneration(value: unknown): boolean {\n return Number.isSafeInteger(value) && (value as number) >= 0\n}\n\nfunction isProjectedScalars(value: unknown): value is ProjectedScalars {\n if (!isRecord(value)) return false\n for (const v of Object.values(value)) {\n if (!(v === null || typeof v === 'number' || typeof v === 'boolean' || typeof v === 'string')) return false\n }\n return true\n}\n\nexport function isMeshTopicEntry(value: unknown): value is MeshTopicEntry {\n if (!isRecord(value)) return false\n if (value.v !== MESH_TOPIC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.eventId) || !isFiniteNumber(value.at)) return false\n switch (value.k) {\n case 'turn.evidence': {\n if (!isEvidenceIdentifier(value.attemptId) || !isGeneration(value.generation)) return false\n if (!isEvidenceIdentifier(value.ownerDaemonId) || !isEvidenceIdentifier(value.sessionId) || !isOptionalId(value.taskId)) return false\n if (!isTurnEvidenceKind(value.ev)) return false\n if (value.strength !== undefined && !(TURN_END_STRENGTHS as readonly string[]).includes(value.strength as string)) return false\n if (value.flags !== undefined) {\n if (!isRecord(value.flags)) return false\n for (const [flag, on] of Object.entries(value.flags)) {\n if (!(TURN_EVIDENCE_FLAGS as readonly string[]).includes(flag) || typeof on !== 'boolean') return false\n }\n }\n if (value.evidence !== undefined && !(isTurnEvidence(value.evidence) && value.evidence.kind === value.ev)) return false\n return true\n }\n case 'turn.committed':\n return isEvidenceIdentifier(value.attemptId) && isGeneration(value.generation) && isOptionalId(value.taskId)\n && isTurnOutcome(value.outcome) && isCommitStrength(value.strength) && isTurnReason(value.reason)\n case 'turn.notify':\n return isOptionalId(value.attemptId) && isNotifyKind(value.notify) && isEvidenceIdentifier(value.targetDaemonId)\n && isOptionalId(value.targetSessionId) && isOptionalId(value.taskId)\n case 'mesh.record':\n return isEvidenceIdentifier(value.ledgerKind) && isOptionalId(value.nodeId) && isOptionalId(value.sessionId)\n && isOptionalId(value.taskId) && isProjectedScalars(value.payload)\n default:\n return false\n }\n}\n\n/**\n * Project evidence onto its `turn.evidence` topic entry. Pure; the attempt\n * identity comes from the resolved attempt (the evidence may lack attemptRef).\n */\nexport function projectTurnEvidenceEntry(\n evidence: TurnEvidence,\n attempt: { attemptId: string; generation: number; ownerDaemonId: string },\n): Extract<MeshTopicEntry, { k: 'turn.evidence' }> {\n const flags: Partial<Record<TurnEvidenceFlag, boolean>> = {}\n if (evidence.kind === 'turn_end') {\n if (evidence.hollow) flags.hollow = true\n if (evidence.afterFinalizationTimeout) flags.afterFinalizationTimeout = true\n }\n if (evidence.kind === 'transcript_final') {\n if (evidence.nativeMarker) flags.nativeMarker = true\n if (evidence.selfAttributing) flags.selfAttributing = true\n }\n const taskId = evidence.taskId\n return {\n v: MESH_TOPIC_PROTOCOL_VERSION,\n eventId: evidence.eventId,\n at: evidence.at,\n k: 'turn.evidence',\n attemptId: attempt.attemptId,\n generation: attempt.generation,\n ownerDaemonId: attempt.ownerDaemonId,\n ...(taskId ? { taskId } : {}),\n sessionId: evidence.sessionId,\n ev: evidence.kind,\n ...(evidence.kind === 'turn_end' ? { strength: evidence.strength } : {}),\n ...(Object.keys(flags).length > 0 ? { flags } : {}),\n evidence,\n }\n}\n","/**\n * session-launch — how a session was launched: provider, model and thinking\n * level, and WHERE each value came from.\n *\n * Wiring-unification Phase E (docs/design/2026-09-23-wiring-unification.md §7,\n * RC5). Before this record the only trace of a session's model was a display\n * string in recent-activity (`buildLegacyModelModeSummaryMetadata`), so nobody\n * could answer \"did I pick this model, did the dashboard restore it from last\n * time, did a mesh slot choose it, or is it just the provider default?\" — and\n * after a daemon restart not even the value survived.\n *\n * The daemon owns the record (daemon-core `SessionRegistry`); this file holds the\n * shape and the pure readers so daemon-core, web-core, the server and the MCP\n * server all read one definition. It is a dependency-free leaf, like the rest of\n * mesh-shared.\n *\n * ★Server content boundary (CLAUDE.md): the full record rides P2P only. The\n * server path carries exactly two derived fields — `model` (an identifier,\n * passed through {@link sanitizeModelIdentifier}) and `modelSource` (an enum,\n * passed through {@link isModelAxisSource}). Never widen that to the record.\n */\n\n/**\n * Where a model / thinking-level value came from.\n *\n * `restore` is deliberately NOT a member: a hosted session re-attached after a\n * daemon restart keeps the ORIGINAL source (the user still picked that model);\n * only `SessionLaunchRecord.launchedBy` records that the session came back via\n * restore.\n */\nimport { readString } from './json'\n\nexport const MODEL_AXIS_SOURCES = [\n /** Picked explicitly for this launch (dashboard dropdown, coordinator dialog). */\n 'user',\n /** The dashboard dialog restored it from the last launch (browser-local memory). */\n 'remembered',\n /** A mesh capability slot supplied it (or a difficulty preset the slot outranked). */\n 'mesh_slot',\n /** An explicit per-task model / thinking level on a mesh queue task. */\n 'task_override',\n /** Nothing was requested; the provider's default is known (discovery / manifest). */\n 'provider_default',\n /** A value was requested without saying where it came from, or nothing is known. */\n 'unspecified',\n] as const\n\nexport type ModelAxisSource = typeof MODEL_AXIS_SOURCES[number]\n\nexport function isModelAxisSource(value: unknown): value is ModelAxisSource {\n return typeof value === 'string' && (MODEL_AXIS_SOURCES as readonly string[]).includes(value)\n}\n\n/**\n * Which surface started the session. `restore` means \"re-attached to a hosted\n * runtime that outlived a daemon restart\" — the axis sources are preserved.\n * `assistant` is the assistant layer's own session (`launch_assistant`,\n * docs/design/2026-10-07-assistant-layer.md §4.5).\n */\nexport const SESSION_LAUNCHED_BY = ['dashboard', 'mesh', 'cli', 'api', 'restore', 'assistant'] as const\n\nexport type SessionLaunchedBy = typeof SESSION_LAUNCHED_BY[number]\n\nexport function isSessionLaunchedBy(value: unknown): value is SessionLaunchedBy {\n return typeof value === 'string' && (SESSION_LAUNCHED_BY as readonly string[]).includes(value)\n}\n\n/** How a value entered the axis history. */\nexport type ModelSelectionVia = 'launch' | 'change_model' | 'observed'\n\nexport interface ModelSelectionHistoryEntry {\n at: number\n value: string\n via: ModelSelectionVia\n}\n\n/** One axis (model, or thinking level) of a session launch. */\nexport interface ModelSelection {\n /** What the caller asked for. Absent = nothing requested. */\n requested?: string\n source: ModelAxisSource\n /**\n * The value actually handed to the provider: after `modelLaunchValueMap`\n * (CLI `--model` template) or the ACP `setConfigOption` call. Absent when the\n * request was not applied (no template, the config call failed) or nothing\n * was requested.\n */\n launchValue?: string\n /**\n * The provider default this session is expected to run with when nothing was\n * requested (`source === 'provider_default'` only): discovery `models[0]`,\n * else the manifest's first option. Nothing was passed to the provider.\n */\n resolvedDefault?: string\n /** Last explicit runtime change (`change_model` / `set_thought_level`). */\n current?: string\n /** Last value the provider itself reported (statusline, native history). */\n observed?: string\n observedAt?: number\n /** Every value change in order. The last entry is the value in force. */\n history: ModelSelectionHistoryEntry[]\n}\n\nexport interface SessionLaunchRecord {\n sessionId: string\n providerType: string\n providerVersion?: string\n providerChannel?: 'stable' | 'preview'\n /** `restore` = re-attached after a daemon restart; the axis sources stay the original ones. */\n launchedBy: SessionLaunchedBy\n launchedAt: number\n workspace?: string\n model: ModelSelection\n thinkingLevel: ModelSelection\n autoApproveModeId?: string\n /**\n * Reserved by the design (§7 E1) for sanitized launch argv. Not populated:\n * argv carries coordinator system-prompt text and config paths, and the\n * session-host record already keeps the raw argv for restore.\n */\n cliArgs?: string[]\n}\n\n/** History is bounded; the first `launch` entry is always kept. */\nexport const MODEL_SELECTION_HISTORY_LIMIT = 20\n\n/** The value in force now: the latest change, else the launch-time value. */\nexport function effectiveModelSelectionValue(selection: ModelSelection | null | undefined): string | undefined {\n if (!selection) return undefined\n const last = Array.isArray(selection.history) ? selection.history[selection.history.length - 1] : undefined\n return last?.value\n ?? selection.current\n ?? selection.observed\n ?? launchModelSelectionValue(selection)\n}\n\n/** The value the session started with (what was passed, else asked for, else the default). */\nexport function launchModelSelectionValue(selection: ModelSelection | null | undefined): string | undefined {\n if (!selection) return undefined\n const launch = Array.isArray(selection.history)\n ? selection.history.find((entry) => entry.via === 'launch')\n : undefined\n return launch?.value ?? selection.launchValue ?? selection.requested ?? selection.resolvedDefault\n}\n\nexport interface ModelSelectionDisplay {\n /** The value in force now. */\n value: string\n /** The value the session launched with, when it differs from `value`. */\n changedFrom?: string\n source: ModelAxisSource\n}\n\n/** Pure projection for UI chips: \"sonnet · chosen\", \"sonnet → opus (changed)\". */\nexport function describeModelSelection(selection: ModelSelection | null | undefined): ModelSelectionDisplay | undefined {\n const value = effectiveModelSelectionValue(selection)\n if (!selection || !value) return undefined\n const launched = launchModelSelectionValue(selection)\n return {\n value,\n ...(launched && launched !== value ? { changedFrom: launched } : {}),\n source: isModelAxisSource(selection.source) ? selection.source : 'unspecified',\n }\n}\n\n/**\n * The only form a model / thinking value may take on the server path: an\n * identifier (`claude-opus-4-1`, `gpt-5.6-sol`, `openai/gpt-4o`, `opus[1m]`,\n * `high`). No whitespace, bounded length — a free-text sentence cannot pass.\n * Human labels (`Gemini 3.7 Flash (High)`) are P2P-only and are dropped here.\n */\nconst MODEL_IDENTIFIER_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:/@[\\]+-]{0,95}$/\n\nexport function sanitizeModelIdentifier(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined\n const trimmed = value.trim()\n return MODEL_IDENTIFIER_PATTERN.test(trimmed) ? trimmed : undefined\n}\n\nfunction readFiniteNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n\nfunction parseModelSelection(raw: unknown): ModelSelection | undefined {\n if (!raw || typeof raw !== 'object') return undefined\n const record = raw as Record<string, unknown>\n const history: ModelSelectionHistoryEntry[] = []\n if (Array.isArray(record.history)) {\n for (const entry of record.history) {\n if (!entry || typeof entry !== 'object') continue\n const e = entry as Record<string, unknown>\n const value = readString(e.value)\n const at = readFiniteNumber(e.at)\n const via = e.via === 'launch' || e.via === 'change_model' || e.via === 'observed' ? e.via : undefined\n if (value && at !== undefined && via) history.push({ at, value, via })\n }\n }\n const requested = readString(record.requested)\n const launchValue = readString(record.launchValue)\n const resolvedDefault = readString(record.resolvedDefault)\n const current = readString(record.current)\n const observed = readString(record.observed)\n const observedAt = readFiniteNumber(record.observedAt)\n return {\n source: isModelAxisSource(record.source) ? record.source : 'unspecified',\n ...(requested ? { requested } : {}),\n ...(launchValue ? { launchValue } : {}),\n ...(resolvedDefault ? { resolvedDefault } : {}),\n ...(current ? { current } : {}),\n ...(observed ? { observed } : {}),\n ...(observedAt !== undefined ? { observedAt } : {}),\n history: history.slice(-MODEL_SELECTION_HISTORY_LIMIT),\n }\n}\n\n/**\n * Validate a record that crossed a process or storage boundary (session-host\n * record meta on restore, a P2P snapshot). Returns undefined for anything that\n * is not recognisably a launch record; unknown keys are dropped.\n */\nexport function parseSessionLaunchRecord(raw: unknown): SessionLaunchRecord | undefined {\n if (!raw || typeof raw !== 'object') return undefined\n const record = raw as Record<string, unknown>\n const sessionId = readString(record.sessionId)\n const providerType = readString(record.providerType)\n const launchedAt = readFiniteNumber(record.launchedAt)\n const model = parseModelSelection(record.model)\n const thinkingLevel = parseModelSelection(record.thinkingLevel)\n if (!sessionId || !providerType || launchedAt === undefined || !model || !thinkingLevel) return undefined\n const providerVersion = readString(record.providerVersion)\n const workspace = readString(record.workspace)\n const autoApproveModeId = readString(record.autoApproveModeId)\n return {\n sessionId,\n providerType,\n ...(providerVersion ? { providerVersion } : {}),\n ...(record.providerChannel === 'stable' || record.providerChannel === 'preview'\n ? { providerChannel: record.providerChannel }\n : {}),\n launchedBy: isSessionLaunchedBy(record.launchedBy) ? record.launchedBy : 'api',\n launchedAt,\n ...(workspace ? { workspace } : {}),\n model,\n thinkingLevel,\n ...(autoApproveModeId ? { autoApproveModeId } : {}),\n }\n}\n","/**\n * turn-ipc shared runtime-guard primitives (the protocol version stamp and the\n * small structural checks every command decoder composes). Part of the turn-ipc\n * wire contract (./turn-ipc.ts).\n */\n\nimport { isEvidenceIdentifier } from './turn-evidence';\nimport { isRecord } from './protocol/envelope';\n\n// ─── shared primitives ─────────────────────────────────────────────────────\n\n/** Every request in this file is versioned so a responder can reject a shape it predates. */\nexport const TURN_IPC_PROTOCOL_VERSION = 1 as const\n\nexport function isFiniteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n\nexport function isNonNegativeInt(value: unknown): value is number {\n return Number.isSafeInteger(value) && (value as number) >= 0\n}\n\nexport function isOptionalId(value: unknown): boolean {\n return value === undefined || isEvidenceIdentifier(value)\n}\n\nexport function hasOnlyKeys(value: Record<string, unknown>, allowed: readonly string[]): boolean {\n for (const key of Object.keys(value)) {\n if (!allowed.includes(key)) return false\n }\n return true\n}\n\nexport function makeGuard<T extends readonly string[]>(values: T): (value: unknown) => value is T[number] {\n const set: ReadonlySet<string> = new Set(values)\n return (value: unknown): value is T[number] => typeof value === 'string' && set.has(value)\n}\n\nexport function isStringArray(value: unknown): value is readonly string[] {\n return Array.isArray(value) && value.every((v) => typeof v === 'string')\n}\n\nexport function isOptionalShortString(value: unknown, max = 512): boolean {\n return value === undefined || (typeof value === 'string' && value.trim().length > 0 && value.length <= max)\n}\n\nexport function isRecordArray(value: unknown): value is readonly Record<string, unknown>[] {\n return Array.isArray(value) && value.every(isRecord)\n}\n\nexport function isOptionalRecord(value: unknown): boolean {\n return value === undefined || isRecord(value)\n}\n\nexport function isOptionalBoolean(value: unknown): boolean {\n return value === undefined || typeof value === 'boolean'\n}\n\nexport function isOptionalString(value: unknown): boolean {\n return value === undefined || typeof value === 'string'\n}\n","/**\n * turn-ipc — the turn-ledger commands: turn_observe, mesh_record, turn_cancel,\n * operator_status, turn_query, mesh_index_query. Part of the turn-ipc wire\n * contract (./turn-ipc.ts).\n */\n\nimport {\n makeGuard,\n TURN_IPC_PROTOCOL_VERSION,\n hasOnlyKeys,\n isNonNegativeInt,\n isOptionalId,\n isFiniteNumber,\n} from './turn-ipc-guards';\nimport {\n type TurnEvidence,\n type TurnAttemptRef,\n type TurnOutcome,\n isTurnEvidence,\n isEvidenceIdentifier,\n type ProjectedScalars,\n type TurnReason,\n isTurnReason,\n type TurnEvidenceKind,\n} from './turn-evidence';\nimport { isRecord } from './protocol/envelope';\n\n// ─── turn_observe ───────────────────────────────────────────────────────────\n\n/** Reducer verdict, mirrored from the C1 reducer's `reduce()` return shape. */\nexport const TURN_OBSERVE_VERDICTS = ['applied', 'recorded', 'rejected'] as const\nexport type TurnObserveVerdict = typeof TURN_OBSERVE_VERDICTS[number]\nconst isTurnObserveVerdict = makeGuard(TURN_OBSERVE_VERDICTS)\n\nexport interface TurnObserveRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n evidence: TurnEvidence\n}\n\nexport interface TurnObserveResponse {\n verdict: TurnObserveVerdict\n attemptRef: TurnAttemptRef\n /** Present only when the evidence committed the attempt (verdict 'applied' + a terminal-class kind). */\n outcome?: TurnOutcome\n}\n\nfunction isTurnObserveRequest(value: unknown): value is TurnObserveRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'evidence'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isTurnEvidence(value.evidence)\n}\n\nexport function decodeTurnObserveRequest(value: unknown): TurnObserveRequest | null {\n return isTurnObserveRequest(value) ? value : null\n}\n\nfunction isTurnAttemptRefValue(value: unknown): value is TurnAttemptRef {\n return isRecord(value) && hasOnlyKeys(value, ['attemptId', 'generation'])\n && isEvidenceIdentifier(value.attemptId) && isNonNegativeInt(value.generation)\n}\n\nfunction isTurnObserveResponse(value: unknown): value is TurnObserveResponse {\n return isRecord(value) && hasOnlyKeys(value, ['verdict', 'attemptRef', 'outcome'])\n && isTurnObserveVerdict(value.verdict)\n && isTurnAttemptRefValue(value.attemptRef)\n && (value.outcome === undefined || isTurnOutcomeValue(value.outcome))\n}\n\nconst TURN_OUTCOMES_LOCAL = ['completed', 'failed', 'cancelled'] as const\nfunction isTurnOutcomeValue(value: unknown): value is TurnOutcome {\n return typeof value === 'string' && (TURN_OUTCOMES_LOCAL as readonly string[]).includes(value)\n}\n\nexport function decodeTurnObserveResponse(value: unknown): TurnObserveResponse | null {\n return isTurnObserveResponse(value) ? value : null\n}\n\n// ─── mesh_record ────────────────────────────────────────────────────────────\n\n/**\n * Structural pin of `seqscribe/mesh-event-projection.ts` `PROJECTED_PAYLOAD_KEYS`\n * (daemon-core; this leaf cannot import it). A test in this package's test\n * suite AND a daemon-core test each assert their list equals this one — see\n * `mesh-shared/test/turn-ipc.test.ts` and the C-W6 report's break-once table.\n * Adding a key here is the SAME assertion as adding it there: non-content\n * (identifier, enum, boolean, or counter), never free text.\n */\nexport const MESH_RECORD_PAYLOAD_KEYS = [\n // Identifiers\n 'taskId', 'deliveryId', 'attemptId', 'missionId', 'checkpointId', 'promptId', 'providerSessionId', 'targetNoteId',\n // Routing / addressing\n 'nodeId', 'sessionId', 'providerType', 'transport', 'attemptedSessionId', 'holderSessionId',\n // Outcome enums\n 'reason', 'status', 'outcome', 'terminalKind', 'event',\n 'source', 'intentionalStopReason',\n // Booleans\n 'retryable', 'rebound', 'forced', 'fallback', 'membershipRemoved', 'requestedForce', 'removedByRemoteDaemon',\n 'completedViaReady', 'intentional', 'weak',\n // Counters\n 'attempt', 'attemptCount', 'count',\n] as const\n\nconst MESH_RECORD_PAYLOAD_KEY_SET: ReadonlySet<string> = new Set(MESH_RECORD_PAYLOAD_KEYS)\n\n/** Maximum length of any string value in a `mesh_record` payload (mirrors `MAX_PROJECTED_STRING`). */\nexport const MAX_MESH_RECORD_STRING = 200\n\nexport interface MeshRecordRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** The original ledger `kind` string (daemon-core `MeshLedgerKind`; mesh-shared cannot import that union, so it is an identifier here). */\n ledgerKind: string\n nodeId?: string\n sessionId?: string\n taskId?: string\n /** Restricted to `MESH_RECORD_PAYLOAD_KEYS` — an unknown key is a decode failure, not a silently dropped field. */\n payload: ProjectedScalars\n}\n\nexport interface MeshRecordResponse {\n /** `mesh.<id>.events` append coordinates, for callers that need to reference the entry (e.g. a `ref`'d handoff). */\n eventId: string\n seq: number\n}\n\nfunction isProjectedScalarsValue(value: unknown): value is ProjectedScalars {\n if (!isRecord(value)) return false\n for (const v of Object.values(value)) {\n if (v === null) continue\n if (typeof v === 'boolean' || typeof v === 'number') continue\n if (typeof v === 'string') { if (v.length > MAX_MESH_RECORD_STRING) return false; continue }\n return false\n }\n return true\n}\n\n/** Every payload key must be a member of `MESH_RECORD_PAYLOAD_KEYS` — the allow-list boundary at the wire. */\nexport function isMeshRecordPayload(value: unknown): value is ProjectedScalars {\n if (!isProjectedScalarsValue(value)) return false\n for (const key of Object.keys(value as Record<string, unknown>)) {\n if (!MESH_RECORD_PAYLOAD_KEY_SET.has(key)) return false\n }\n return true\n}\n\nfunction isMeshRecordRequest(value: unknown): value is MeshRecordRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'ledgerKind', 'nodeId', 'sessionId', 'taskId', 'payload'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isEvidenceIdentifier(value.meshId)\n && isEvidenceIdentifier(value.ledgerKind)\n && isOptionalId(value.nodeId) && isOptionalId(value.sessionId) && isOptionalId(value.taskId)\n && isMeshRecordPayload(value.payload)\n}\n\nexport function decodeMeshRecordRequest(value: unknown): MeshRecordRequest | null {\n return isMeshRecordRequest(value) ? value : null\n}\n\nfunction isMeshRecordResponse(value: unknown): value is MeshRecordResponse {\n return isRecord(value) && hasOnlyKeys(value, ['eventId', 'seq'])\n && isEvidenceIdentifier(value.eventId) && isNonNegativeInt(value.seq)\n}\n\nexport function decodeMeshRecordResponse(value: unknown): MeshRecordResponse | null {\n return isMeshRecordResponse(value) ? value : null\n}\n\n// ─── turn_cancel ────────────────────────────────────────────────────────────\n\nexport interface TurnCancelRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n /** Exactly one of the two must be present — the decoder rejects both-or-neither. */\n attemptId?: string\n taskId?: string\n reason: TurnReason\n}\n\nexport interface TurnCancelResponse {\n attemptRef: TurnAttemptRef\n verdict: TurnObserveVerdict\n}\n\nfunction isTurnCancelRequest(value: unknown): value is TurnCancelRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'attemptId', 'taskId', 'reason'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n const hasAttempt = value.attemptId !== undefined\n const hasTask = value.taskId !== undefined\n if (hasAttempt === hasTask) return false // exactly one of the two\n if (hasAttempt && !isEvidenceIdentifier(value.attemptId)) return false\n if (hasTask && !isEvidenceIdentifier(value.taskId)) return false\n return isTurnReason(value.reason)\n}\n\nexport function decodeTurnCancelRequest(value: unknown): TurnCancelRequest | null {\n return isTurnCancelRequest(value) ? value : null\n}\n\nfunction isTurnCancelResponse(value: unknown): value is TurnCancelResponse {\n return isRecord(value) && hasOnlyKeys(value, ['attemptRef', 'verdict'])\n && isTurnAttemptRefValue(value.attemptRef) && isTurnObserveVerdict(value.verdict)\n}\n\nexport function decodeTurnCancelResponse(value: unknown): TurnCancelResponse | null {\n return isTurnCancelResponse(value) ? value : null\n}\n\n// ─── operator_status ────────────────────────────────────────────────────────\n\n/**\n * Fire-and-forget operator/tool-call status record — replaces\n * `recordMeshCoordinatorToolCall` (10 sites, `mesh_tool_call_log`) and doubles\n * as the `operator_status` evidence kind's wire shape.\n *\n * NAMING NOTE (flagged for the C-W6 implementer, see report §\"mismatch\"):\n * the C-W6 brief's DELIVERABLES describes this request as\n * `{taskId, status: MeshTaskStatus, reason}`, but C1's `operator_status`\n * evidence kind (`turn-evidence.ts` `OPERATOR_STATUSES`) is the closed\n * 2-value set `'completed' | 'failed'` — a verdict on an operator ACTION, not\n * a `MeshTaskStatus` (5-value queue-row status: pending/assigned/completed/\n * failed/cancelled). This contract follows `turn-evidence.ts` because that is\n * what the C1 reducer actually consumes for this evidence kind; using the\n * 5-value `MeshTaskStatus` here would let this request carry `pending` or\n * `assigned`, which the reducer has no transition for.\n */\nexport const OPERATOR_STATUS_VALUES = ['completed', 'failed'] as const\nexport type OperatorStatusValue = typeof OPERATOR_STATUS_VALUES[number]\nconst isOperatorStatusValue = makeGuard(OPERATOR_STATUS_VALUES)\n\nexport const OPERATOR_STATUS_REASON_VALUES = ['operator_update', 'refine_terminal', 'validation_terminal'] as const\nexport type OperatorStatusReasonValue = typeof OPERATOR_STATUS_REASON_VALUES[number]\nconst isOperatorStatusReasonValue = makeGuard(OPERATOR_STATUS_REASON_VALUES)\n\nexport interface OperatorStatusRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n taskId: string\n status: OperatorStatusValue\n reason: OperatorStatusReasonValue\n}\n\n/** Acknowledgement only — this command is fire-and-forget by design (the daemon owns rate-limiting the underlying log). */\nexport interface OperatorStatusResponse {\n accepted: true\n}\n\nfunction isOperatorStatusRequest(value: unknown): value is OperatorStatusRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'taskId', 'status', 'reason'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isEvidenceIdentifier(value.taskId)\n && isOperatorStatusValue(value.status)\n && isOperatorStatusReasonValue(value.reason)\n}\n\nexport function decodeOperatorStatusRequest(value: unknown): OperatorStatusRequest | null {\n return isOperatorStatusRequest(value) ? value : null\n}\n\nfunction isOperatorStatusResponse(value: unknown): value is OperatorStatusResponse {\n return isRecord(value) && hasOnlyKeys(value, ['accepted']) && value.accepted === true\n}\n\nexport function decodeOperatorStatusResponse(value: unknown): OperatorStatusResponse | null {\n return isOperatorStatusResponse(value) ? value : null\n}\n\n// ─── turn_query ─────────────────────────────────────────────────────────────\n\n/** Row shape returned by `turn_query` — scalar projection of a `turn_attempts` row (C3 schema), never `data_json`/`payload_json` content. */\nexport interface TurnQueryAttemptRow {\n attemptId: string\n generation: number\n meshId?: string\n taskId?: string\n sessionId: string\n nodeId?: string\n providerType?: string\n state: string\n terminalOutcome?: TurnOutcome\n terminalReason?: TurnReason\n acceptedAt: number\n terminalAt?: number\n}\n\n/** Row shape returned by `turn_query` for the event stream — scalar projection of a `turn_events` row, `payload_json` NEVER included. */\nexport interface TurnQueryEventRow {\n eventId: string\n attemptId?: string\n generation?: number\n sessionId: string\n kind: TurnEvidenceKind\n source: string\n verdict: TurnObserveVerdict | 'forwarded'\n atMs: number\n}\n\nexport interface TurnQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n taskId?: string\n attemptId?: string\n sessionId?: string\n state?: string\n since?: number\n tail?: number\n}\n\nexport interface TurnQueryResponse {\n attempts: readonly TurnQueryAttemptRow[]\n events: readonly TurnQueryEventRow[]\n /** C7-5: set while `mesh.<id>.events` replication is behind for this mesh — the caller must not treat a fleet-scope answer as complete. */\n replicationPending?: boolean\n}\n\nfunction isTurnQueryRequest(value: unknown): value is TurnQueryRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'taskId', 'attemptId', 'sessionId', 'state', 'since', 'tail'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isEvidenceIdentifier(value.meshId)\n && isOptionalId(value.taskId) && isOptionalId(value.attemptId) && isOptionalId(value.sessionId)\n && (value.state === undefined || isEvidenceIdentifier(value.state))\n && (value.since === undefined || isFiniteNumber(value.since))\n && (value.tail === undefined || isNonNegativeInt(value.tail))\n}\n\nexport function decodeTurnQueryRequest(value: unknown): TurnQueryRequest | null {\n return isTurnQueryRequest(value) ? value : null\n}\n\nconst TURN_QUERY_ATTEMPT_ROW_KEYS = [\n 'attemptId', 'generation', 'meshId', 'taskId', 'sessionId', 'nodeId', 'providerType',\n 'state', 'terminalOutcome', 'terminalReason', 'acceptedAt', 'terminalAt',\n] as const\n\nfunction isTurnQueryAttemptRow(value: unknown): value is TurnQueryAttemptRow {\n if (!isRecord(value) || !hasOnlyKeys(value, TURN_QUERY_ATTEMPT_ROW_KEYS)) return false\n if (!isEvidenceIdentifier(value.attemptId) || !isNonNegativeInt(value.generation)) return false\n if (!isOptionalId(value.meshId) || !isOptionalId(value.taskId)) return false\n if (!isEvidenceIdentifier(value.sessionId)) return false\n if (!isOptionalId(value.nodeId) || !isOptionalId(value.providerType)) return false\n if (typeof value.state !== 'string') return false\n if (value.terminalOutcome !== undefined && !isTurnOutcomeValue(value.terminalOutcome)) return false\n if (value.terminalReason !== undefined && !isTurnReason(value.terminalReason)) return false\n if (!isFiniteNumber(value.acceptedAt)) return false\n if (value.terminalAt !== undefined && !isFiniteNumber(value.terminalAt)) return false\n return true\n}\n\nconst TURN_QUERY_EVENT_VERDICTS = ['applied', 'recorded', 'rejected', 'forwarded'] as const\nconst TURN_QUERY_EVENT_ROW_KEYS = ['eventId', 'attemptId', 'generation', 'sessionId', 'kind', 'source', 'verdict', 'atMs'] as const\n\nfunction isTurnQueryEventRow(value: unknown): value is TurnQueryEventRow {\n if (!isRecord(value) || !hasOnlyKeys(value, TURN_QUERY_EVENT_ROW_KEYS)) return false\n if (!isEvidenceIdentifier(value.eventId)) return false\n if (!isOptionalId(value.attemptId)) return false\n if (value.generation !== undefined && !isNonNegativeInt(value.generation)) return false\n if (!isEvidenceIdentifier(value.sessionId)) return false\n if (typeof value.kind !== 'string') return false\n if (typeof value.source !== 'string') return false\n if (!(TURN_QUERY_EVENT_VERDICTS as readonly string[]).includes(value.verdict as string)) return false\n if (!isFiniteNumber(value.atMs)) return false\n return true\n}\n\nfunction isTurnQueryResponse(value: unknown): value is TurnQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['attempts', 'events', 'replicationPending'])) return false\n if (!Array.isArray(value.attempts) || !value.attempts.every(isTurnQueryAttemptRow)) return false\n if (!Array.isArray(value.events) || !value.events.every(isTurnQueryEventRow)) return false\n if (value.replicationPending !== undefined && typeof value.replicationPending !== 'boolean') return false\n return true\n}\n\nexport function decodeTurnQueryResponse(value: unknown): TurnQueryResponse | null {\n return isTurnQueryResponse(value) ? value : null\n}\n\n// ─── mesh_index_query ───────────────────────────────────────────────────────\n\nexport const MESH_INDEX_QUERY_WRITER_SCOPES = ['own', 'fleet'] as const\nexport type MeshIndexQueryWriterScope = typeof MESH_INDEX_QUERY_WRITER_SCOPES[number]\nconst isMeshIndexQueryWriterScope = makeGuard(MESH_INDEX_QUERY_WRITER_SCOPES)\n\nexport interface MeshIndexQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n ledgerKind?: string\n sessionId?: string\n taskId?: string\n writer?: MeshIndexQueryWriterScope\n since?: number\n tail?: number\n}\n\n/** Row shape returned by `mesh_index_query` — a `mesh_topic_index` row (C3 schema). */\nexport interface MeshTopicIndexRow {\n writer: string\n seq: number\n meshId: string\n eventId: string\n kind: string\n ledgerKind?: string\n taskId?: string\n sessionId?: string\n nodeId?: string\n atMs: number\n payload: ProjectedScalars\n}\n\nexport interface MeshIndexQueryResponse {\n rows: readonly MeshTopicIndexRow[]\n /** C7-5: true while `mesh.<id>.events` replication is behind for this mesh. */\n replicationPending?: boolean\n}\n\nfunction isMeshIndexQueryRequest(value: unknown): value is MeshIndexQueryRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'ledgerKind', 'sessionId', 'taskId', 'writer', 'since', 'tail'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isEvidenceIdentifier(value.meshId)\n && isOptionalId(value.ledgerKind) && isOptionalId(value.sessionId) && isOptionalId(value.taskId)\n && (value.writer === undefined || isMeshIndexQueryWriterScope(value.writer))\n && (value.since === undefined || isFiniteNumber(value.since))\n && (value.tail === undefined || isNonNegativeInt(value.tail))\n}\n\nexport function decodeMeshIndexQueryRequest(value: unknown): MeshIndexQueryRequest | null {\n return isMeshIndexQueryRequest(value) ? value : null\n}\n\nconst MESH_TOPIC_INDEX_ROW_KEYS = [\n 'writer', 'seq', 'meshId', 'eventId', 'kind', 'ledgerKind', 'taskId', 'sessionId', 'nodeId', 'atMs', 'payload',\n] as const\n\nfunction isMeshTopicIndexRow(value: unknown): value is MeshTopicIndexRow {\n if (!isRecord(value) || !hasOnlyKeys(value, MESH_TOPIC_INDEX_ROW_KEYS)) return false\n if (!isEvidenceIdentifier(value.writer) || !isNonNegativeInt(value.seq)) return false\n if (!isEvidenceIdentifier(value.meshId) || !isEvidenceIdentifier(value.eventId)) return false\n if (typeof value.kind !== 'string') return false\n if (!isOptionalId(value.ledgerKind) || !isOptionalId(value.taskId) || !isOptionalId(value.sessionId) || !isOptionalId(value.nodeId)) return false\n if (!isFiniteNumber(value.atMs)) return false\n // Rows replay mesh.record entries, so the payload is held to the SAME\n // allow-list as a mesh_record request — not just \"any scalar map\" — to\n // stop a fleet-wide read from surfacing a key that was never reviewed.\n if (!isMeshRecordPayload(value.payload)) return false\n return true\n}\n\nexport function isMeshIndexQueryResponse(value: unknown): value is MeshIndexQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['rows', 'replicationPending'])) return false\n if (!Array.isArray(value.rows) || !value.rows.every(isMeshTopicIndexRow)) return false\n if (value.replicationPending !== undefined && typeof value.replicationPending !== 'boolean') return false\n return true\n}\n\nexport function decodeMeshIndexQueryResponse(value: unknown): MeshIndexQueryResponse | null {\n return isMeshIndexQueryResponse(value) ? value : null\n}\n","/**\n * turn-ipc — mission, note, tool-call and ledger commands: mission_upsert,\n * mission_query, mission_list_query, note_upsert, note_forget, tool_call_record,\n * ledger_query. Part of the turn-ipc wire contract (./turn-ipc.ts).\n */\n\nimport {\n makeGuard,\n hasOnlyKeys,\n isStringArray,\n TURN_IPC_PROTOCOL_VERSION,\n isNonNegativeInt,\n isOptionalShortString,\n isOptionalId,\n} from './turn-ipc-guards';\nimport { isRecord } from './protocol/envelope';\nimport { isEvidenceIdentifier } from './turn-evidence';\n\n// ─── mission_upsert / mission_query ────────────────────────────────────────\n//\n// Decision (2026-09-23, design doc §5 C2 update): missions and graph gates\n// have no home in the original six commands — `upsertMeshMission`/\n// `listMeshMissionsForTool` write/read structured state with a free-text\n// `goal`/`title` that cannot fit `mesh_record`'s scalar `ProjectedScalars`\n// allow-list (§ \"MESH_RECORD_PAYLOAD_KEYS\" above has no text field, on\n// purpose). Two more commands, not a widened allow-list:\n//\n// - mission_upsert — create/update a mission (mesh-missions.ts\n// `upsertMeshMission`'s shape).\n// - mission_query — list missions for a mesh, optionally filtered by\n// status (`getMeshMissions`'s shape).\n//\n// WHY FREE TEXT IS FINE HERE, UNLIKE mesh_record's payload: this is LOCAL\n// IPC between mcp-server and the daemon that owns the mission table — both\n// processes run on the operator's own machine. The content boundary this\n// program protects is \"the SERVER never receives chat content\" (CLAUDE.md);\n// IPC between two local processes was never inside that boundary, the same\n// way a direct in-process function call wasn't. Cross-machine mission text\n// (a worker learning about a mission a coordinator defined) travels as a\n// `mesh.<id>.handoff` ref per C10-1's precedent — mission_upsert/query never\n// themselves cross a machine boundary.\n\nexport const MESH_MISSION_STATUSES = ['active', 'paused', 'completed', 'abandoned'] as const\nexport type MeshMissionStatusValue = typeof MESH_MISSION_STATUSES[number]\nexport const isMeshMissionStatusValue = makeGuard(MESH_MISSION_STATUSES)\n\n// H2 (mission brief, wiring-unification Phase H — docs/design/2026-09-23-wiring-\n// unification.md §7c): free text, same \"local IPC is inside the boundary\" rationale\n// as `goal` above (section note). `MissionBriefWire` is a structural mirror of\n// mesh-shared's own `MissionBrief` (mission-brief.ts) rather than importing it —\n// this file's guards are all hand-rolled structural checks, and importing the type\n// only (not the class) would still couple this wire contract to that module's\n// internal shape; a mirror keeps the two independently reviewable, same as every\n// other wire type in this file.\nexport interface MissionBriefWire {\n goal: string\n constraints?: readonly string[]\n doneCriteria?: readonly string[]\n handoffNotes?: readonly string[]\n ownedPaths?: readonly string[]\n}\n\nfunction isMissionBriefWire(value: unknown): value is MissionBriefWire {\n if (!isRecord(value) || !hasOnlyKeys(value, ['goal', 'constraints', 'doneCriteria', 'handoffNotes', 'ownedPaths'])) return false\n if (typeof value.goal !== 'string' || value.goal.trim().length === 0) return false\n for (const k of ['constraints', 'doneCriteria', 'handoffNotes', 'ownedPaths'] as const) {\n if (value[k] !== undefined && !isStringArray(value[k])) return false\n }\n return true\n}\n\nexport interface MissionUpsertRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** Omitted = create a new mission; present = update (must resolve to an existing mission — see mesh-missions.ts MISSION-UPSERT-SILENT-CREATE). */\n id?: string\n title: string\n /** Free text — see file-header note on why this is fine over local IPC. */\n goal?: string\n status?: MeshMissionStatusValue\n /**\n * H2: `undefined` = do not touch the stored brief. `null` = explicitly clear it.\n * A present object with no usable `goal` is treated by the daemon's own\n * `normalizeMissionBrief` as \"no brief\" (see mesh-missions.ts upsertMeshMission) —\n * this wire guard only checks SHAPE, not that decision.\n */\n brief?: MissionBriefWire | null\n}\n\nexport interface MeshMissionRecordWire {\n id: string\n meshId: string\n title: string\n goal: string\n status: MeshMissionStatusValue\n /** H2: absent = no brief attached to this mission. */\n brief?: MissionBriefWire\n}\n\nexport interface MissionUpsertResponse {\n mission: MeshMissionRecordWire\n}\n\nfunction isMeshMissionRecordWire(value: unknown): value is MeshMissionRecordWire {\n if (!isRecord(value) || !hasOnlyKeys(value, ['id', 'meshId', 'title', 'goal', 'status', 'brief'])) return false\n if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false\n if (typeof value.title !== 'string' || typeof value.goal !== 'string') return false\n if (!isMeshMissionStatusValue(value.status)) return false\n if (value.brief !== undefined && !isMissionBriefWire(value.brief)) return false\n return true\n}\n\nfunction isMissionUpsertRequest(value: unknown): value is MissionUpsertRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'id', 'title', 'goal', 'status', 'brief'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n if (value.id !== undefined && !isEvidenceIdentifier(value.id)) return false\n if (typeof value.title !== 'string' || value.title.trim().length === 0) return false\n if (value.goal !== undefined && typeof value.goal !== 'string') return false\n if (value.status !== undefined && !isMeshMissionStatusValue(value.status)) return false\n if (value.brief !== undefined && value.brief !== null && !isMissionBriefWire(value.brief)) return false\n return true\n}\n\nexport function decodeMissionUpsertRequest(value: unknown): MissionUpsertRequest | null {\n return isMissionUpsertRequest(value) ? value : null\n}\n\nexport function isMissionUpsertResponse(value: unknown): value is MissionUpsertResponse {\n return isRecord(value) && hasOnlyKeys(value, ['mission']) && isMeshMissionRecordWire(value.mission)\n}\n\nexport function decodeMissionUpsertResponse(value: unknown): MissionUpsertResponse | null {\n return isMissionUpsertResponse(value) ? value : null\n}\n\nexport interface MissionQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** Omitted = every status. */\n statuses?: readonly MeshMissionStatusValue[]\n /** Single-mission lookup (mesh-missions.ts `getMeshMission`'s shape) — mutually exclusive with `statuses`. */\n id?: string\n}\n\nexport interface MissionQueryResponse {\n missions: readonly MeshMissionRecordWire[]\n}\n\nfunction isMissionQueryRequest(value: unknown): value is MissionQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'statuses', 'id'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n if (value.id !== undefined && !isEvidenceIdentifier(value.id)) return false\n if (value.statuses !== undefined) {\n if (!Array.isArray(value.statuses) || value.statuses.length === 0) return false\n if (!value.statuses.every(isMeshMissionStatusValue)) return false\n }\n return true\n}\n\nexport function decodeMissionQueryRequest(value: unknown): MissionQueryRequest | null {\n return isMissionQueryRequest(value) ? value : null\n}\n\nfunction isMissionQueryResponse(value: unknown): value is MissionQueryResponse {\n return isRecord(value) && hasOnlyKeys(value, ['missions'])\n && Array.isArray(value.missions) && value.missions.every(isMeshMissionRecordWire)\n}\n\nexport function decodeMissionQueryResponse(value: unknown): MissionQueryResponse | null {\n return isMissionQueryResponse(value) ? value : null\n}\n\n// ─── mission_list_query ─────────────────────────────────────────────────────\n//\n// Wiring-unification Phase C, workstream C-W9b.\n//\n// `mesh-tools-mission.ts`'s own file-header note (2026-09-24, C-W6) flagged\n// this exact gap: `mission_query`'s landed response is `{missions:\n// MeshMissionRecordWire[]}` only — no `verbose`/`withStats`/\n// `limit`/`truncated`/`overflowIds`/`historyFold`, all of which\n// `listMeshMissionsForTool` (daemon-core `mesh-missions.ts`) computes for the\n// `mesh_mission_list` tool. Rather than widen `mission_query` itself (an\n// already-landed, already-tested contract other callers rely on for its\n// narrow shape), this is an ADDITIVE sibling command carrying\n// `listMeshMissionsForTool`'s full output shape — request/response fields\n// mirror its options/`MeshMissionListResult` one-for-one (see\n// mesh-missions.ts). `goal`/`goalPreview` are free text, same local-IPC\n// rationale as `mission_upsert`'s `goal` above.\n\nexport interface MissionListQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n statuses?: readonly MeshMissionStatusValue[]\n verbose?: boolean\n withStats?: boolean\n limit?: number\n historyIdLimit?: number\n /**\n * The mesh_status mission projection, computed in the daemon (the MCP no longer\n * opens the daemon's store for it): 'compact' = `getMeshStatusMissionsCompact`\n * (live missions goal-elided + folded history), 'verbose' =\n * `getMeshStatusMissionSummaries({verbose: true})` (live + capped history, full\n * goal, no stats — stats ride one batched `task_stats_query`). Rows then also\n * carry `createdAt`/`updatedAt`/`closeCandidateEmittedAt`. When set, every other\n * option except `historyIdLimit` is ignored. An older daemon rejects the key.\n */\n meshStatusView?: 'compact' | 'verbose'\n}\n\nexport interface MeshMissionTaskAggregateWire {\n total: number\n pending: number\n assigned: number\n completed: number\n failed: number\n cancelled: number\n blocked: number\n lastActivityAt: string | null\n}\n\nexport interface MeshMissionStatsWire {\n missionId: string\n taskCount: number\n completed: number\n failed: number\n totalDurationMs: number\n wallClockMs: number | null\n retries: number\n incompleteTaskIds: readonly string[]\n}\n\n/** Verbose (full-goal) mission row. `goal` present, `goalPreview`/`goalTruncated` absent. */\nexport interface MissionListSummaryVerboseWire {\n id: string\n meshId: string\n title: string\n goal: string\n status: MeshMissionStatusValue\n tasks: MeshMissionTaskAggregateWire\n stats?: MeshMissionStatsWire\n /** H2: absent = no brief attached. */\n brief?: MissionBriefWire\n /** `meshStatusView` rows only. */\n createdAt?: string\n updatedAt?: string\n closeCandidateEmittedAt?: string | null\n}\n\n/** Compact (default) mission row. `goalPreview`/`goalTruncated` present, `goal` absent. */\nexport interface MissionListSummarySlimWire {\n id: string\n meshId: string\n title: string\n goalPreview: string\n goalTruncated: boolean\n status: MeshMissionStatusValue\n tasks: MeshMissionTaskAggregateWire\n stats?: MeshMissionStatsWire\n /** H2: absent = no brief attached. */\n brief?: MissionBriefWire\n /** `meshStatusView` rows only. */\n createdAt?: string\n updatedAt?: string\n closeCandidateEmittedAt?: string | null\n}\n\nexport type MissionListSummaryWire = MissionListSummaryVerboseWire | MissionListSummarySlimWire\n\nexport interface MeshMissionHistoryFoldWire {\n count: number\n byStatus: Record<string, number>\n missionIds: readonly string[]\n note: string\n}\n\nexport interface MissionListQueryResponse {\n missions: readonly MissionListSummaryWire[]\n historyFold: MeshMissionHistoryFoldWire | null\n truncated: boolean\n matched: number\n overflowIds?: readonly string[]\n}\n\nfunction isMissionListQueryRequest(value: unknown): value is MissionListQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'statuses', 'verbose', 'withStats', 'limit', 'historyIdLimit', 'meshStatusView'])) return false\n if (value.meshStatusView !== undefined && value.meshStatusView !== 'compact' && value.meshStatusView !== 'verbose') return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n if (value.statuses !== undefined) {\n if (!Array.isArray(value.statuses) || value.statuses.length === 0) return false\n if (!value.statuses.every(isMeshMissionStatusValue)) return false\n }\n if (value.verbose !== undefined && typeof value.verbose !== 'boolean') return false\n if (value.withStats !== undefined && typeof value.withStats !== 'boolean') return false\n if (value.limit !== undefined && !isNonNegativeInt(value.limit)) return false\n if (value.historyIdLimit !== undefined && !isNonNegativeInt(value.historyIdLimit)) return false\n return true\n}\n\nexport function decodeMissionListQueryRequest(value: unknown): MissionListQueryRequest | null {\n return isMissionListQueryRequest(value) ? value : null\n}\n\nfunction isMeshMissionTaskAggregateWire(value: unknown): value is MeshMissionTaskAggregateWire {\n const keys = ['total', 'pending', 'assigned', 'completed', 'failed', 'cancelled', 'blocked', 'lastActivityAt'] as const\n if (!isRecord(value) || !hasOnlyKeys(value, keys)) return false\n for (const k of ['total', 'pending', 'assigned', 'completed', 'failed', 'cancelled', 'blocked'] as const) {\n if (!isNonNegativeInt(value[k])) return false\n }\n return value.lastActivityAt === null || typeof value.lastActivityAt === 'string'\n}\n\nfunction isMeshMissionStatsWire(value: unknown): value is MeshMissionStatsWire {\n const keys = ['missionId', 'taskCount', 'completed', 'failed', 'totalDurationMs', 'wallClockMs', 'retries', 'incompleteTaskIds'] as const\n if (!isRecord(value) || !hasOnlyKeys(value, keys)) return false\n if (!isEvidenceIdentifier(value.missionId)) return false\n for (const k of ['taskCount', 'completed', 'failed', 'totalDurationMs', 'retries'] as const) {\n if (!isNonNegativeInt(value[k])) return false\n }\n if (value.wallClockMs !== null && !isNonNegativeInt(value.wallClockMs)) return false\n if (!Array.isArray(value.incompleteTaskIds) || !value.incompleteTaskIds.every(isEvidenceIdentifier)) return false\n return true\n}\n\nfunction isMissionListSummaryWire(value: unknown): value is MissionListSummaryWire {\n if (!isRecord(value)) return false\n const hasGoal = 'goal' in value\n const hasPreview = 'goalPreview' in value && 'goalTruncated' in value\n if (hasGoal === hasPreview) return false // exactly one of the two shapes\n const baseKeys = ['id', 'meshId', 'title', 'status', 'tasks', 'stats', 'brief', 'createdAt', 'updatedAt', 'closeCandidateEmittedAt'] as const\n const allowed = hasGoal ? [...baseKeys, 'goal'] : [...baseKeys, 'goalPreview', 'goalTruncated']\n if (!hasOnlyKeys(value, allowed)) return false\n if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false\n if (typeof value.title !== 'string') return false\n if (!isMeshMissionStatusValue(value.status)) return false\n if (!isMeshMissionTaskAggregateWire(value.tasks)) return false\n if (value.stats !== undefined && !isMeshMissionStatsWire(value.stats)) return false\n if (value.brief !== undefined && !isMissionBriefWire(value.brief)) return false\n if (hasGoal && typeof value.goal !== 'string') return false\n if (hasPreview && (typeof value.goalPreview !== 'string' || typeof value.goalTruncated !== 'boolean')) return false\n if (value.createdAt !== undefined && typeof value.createdAt !== 'string') return false\n if (value.updatedAt !== undefined && typeof value.updatedAt !== 'string') return false\n if (value.closeCandidateEmittedAt !== undefined && value.closeCandidateEmittedAt !== null && typeof value.closeCandidateEmittedAt !== 'string') return false\n return true\n}\n\nfunction isMeshMissionHistoryFoldWire(value: unknown): value is MeshMissionHistoryFoldWire {\n if (!isRecord(value) || !hasOnlyKeys(value, ['count', 'byStatus', 'missionIds', 'note'])) return false\n if (!isNonNegativeInt(value.count)) return false\n if (!isRecord(value.byStatus) || !Object.values(value.byStatus).every((n) => isNonNegativeInt(n))) return false\n if (!Array.isArray(value.missionIds) || !value.missionIds.every(isEvidenceIdentifier)) return false\n return typeof value.note === 'string'\n}\n\nfunction isMissionListQueryResponse(value: unknown): value is MissionListQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['missions', 'historyFold', 'truncated', 'matched', 'overflowIds'])) return false\n if (!Array.isArray(value.missions) || !value.missions.every(isMissionListSummaryWire)) return false\n if (value.historyFold !== null && !isMeshMissionHistoryFoldWire(value.historyFold)) return false\n if (typeof value.truncated !== 'boolean') return false\n if (!isNonNegativeInt(value.matched)) return false\n if (value.overflowIds !== undefined && (!Array.isArray(value.overflowIds) || !value.overflowIds.every(isEvidenceIdentifier))) return false\n return true\n}\n\nexport function decodeMissionListQueryResponse(value: unknown): MissionListQueryResponse | null {\n return isMissionListQueryResponse(value) ? value : null\n}\n\n// ─── note_upsert / note_forget ──────────────────────────────────────────────\n//\n// Decision (2026-09-24, C-W6b; implemented C-W8): coordinator operating notes\n// get their own two local-IPC commands. A note's text is coordinator-authored\n// free text, so — exactly like mission_upsert's `goal` — it cannot ride\n// `mesh_record`'s scalar allow-list, and it never needs to: notes live in the\n// owning daemon's `mesh_operating_notes` table (local-only; never on\n// `mesh.<id>.events`). The same \"local IPC is inside the boundary\" rationale as\n// the mission commands above applies.\n\nexport const OPERATING_NOTE_CATEGORIES = ['provider_quirk', 'pattern_to_avoid', 'recovery_lesson'] as const\nexport type OperatingNoteCategory = typeof OPERATING_NOTE_CATEGORIES[number]\nconst isOperatingNoteCategory = makeGuard(OPERATING_NOTE_CATEGORIES)\n\nexport interface NoteUpsertRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** Free text (local IPC — see the section note). */\n text: string\n category?: OperatingNoteCategory\n pinned?: boolean\n /** Explicit expiry, ISO-8601. */\n expiresAt?: string\n /** Note id (or subject key) this note supersedes. */\n supersedes?: string\n subjectKey?: string\n /** Best-effort identity of the recording coordinator (session id / daemon id / host). */\n sourceCoordinator?: string\n}\n\nexport interface NoteUpsertResponse {\n noteId: string\n /** True when the same text was already among the recent live notes (no new note). */\n deduped: boolean\n createdAt: string\n}\n\nfunction isNoteUpsertRequest(value: unknown): value is NoteUpsertRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'text', 'category', 'pinned', 'expiresAt', 'supersedes', 'subjectKey', 'sourceCoordinator'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n if (typeof value.text !== 'string' || value.text.trim().length === 0) return false\n if (value.category !== undefined && !isOperatingNoteCategory(value.category)) return false\n if (value.pinned !== undefined && typeof value.pinned !== 'boolean') return false\n if (value.expiresAt !== undefined && (typeof value.expiresAt !== 'string' || Number.isNaN(Date.parse(value.expiresAt)))) return false\n return isOptionalShortString(value.supersedes) && isOptionalShortString(value.subjectKey) && isOptionalShortString(value.sourceCoordinator)\n}\n\nexport function decodeNoteUpsertRequest(value: unknown): NoteUpsertRequest | null {\n return isNoteUpsertRequest(value) ? value : null\n}\n\nfunction isNoteUpsertResponse(value: unknown): value is NoteUpsertResponse {\n return isRecord(value) && hasOnlyKeys(value, ['noteId', 'deduped', 'createdAt'])\n && isEvidenceIdentifier(value.noteId) && typeof value.deduped === 'boolean' && typeof value.createdAt === 'string'\n}\n\nexport function decodeNoteUpsertResponse(value: unknown): NoteUpsertResponse | null {\n return isNoteUpsertResponse(value) ? value : null\n}\n\nexport interface NoteForgetRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** At least one of `noteId` / `text` (a text forget retracts every note with that exact text, and any recorded later). */\n noteId?: string\n text?: string\n reason?: string\n}\n\nexport interface NoteForgetResponse {\n /** Live notes this forget hid. */\n matched: number\n tombstoneId: string\n}\n\nfunction isNoteForgetRequest(value: unknown): value is NoteForgetRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'noteId', 'text', 'reason'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n if (value.noteId !== undefined && !isEvidenceIdentifier(value.noteId)) return false\n if (value.text !== undefined && (typeof value.text !== 'string' || value.text.trim().length === 0)) return false\n if (value.noteId === undefined && value.text === undefined) return false\n return value.reason === undefined || typeof value.reason === 'string'\n}\n\nexport function decodeNoteForgetRequest(value: unknown): NoteForgetRequest | null {\n return isNoteForgetRequest(value) ? value : null\n}\n\nfunction isNoteForgetResponse(value: unknown): value is NoteForgetResponse {\n return isRecord(value) && hasOnlyKeys(value, ['matched', 'tombstoneId'])\n && typeof value.matched === 'number' && Number.isInteger(value.matched) && value.matched >= 0\n && isEvidenceIdentifier(value.tombstoneId)\n}\n\nexport function decodeNoteForgetResponse(value: unknown): NoteForgetResponse | null {\n return isNoteForgetResponse(value) ? value : null\n}\n\n// ─── tool_call_record ───────────────────────────────────────────────────────\n//\n// Wiring-unification Phase C, workstream C-W9b\n// (docs/design/2026-09-23-wiring-unification.md §5 C2 \"MCP server\" paragraph,\n// 2026-09-24 14:00 stamp \"C-W9\").\n//\n// Replaces `recordMeshToolCall`/`recordMeshCoordinatorToolCall`\n// (`daemon-core/src/mesh/mesh-direct-dispatch.ts`) — an in-process,\n// per-mesh-tool-call rate-limit/advisory bump mcp-server called directly\n// against its own store handle. Every field is an identifier, a closed enum,\n// a boolean or a counter — squarely inside `mesh_record`'s content boundary,\n// but this is its own command (not a `mesh_record` payload) because it is a\n// COUNTER MUTATION with a computed return value (`rateLimitExceeded`,\n// `callsInWindow`, `advisory`), not an append-only scalar record.\n\nexport const TOOL_CALLER_ROLES = ['coordinator', 'unknown'] as const\nexport type ToolCallerRole = typeof TOOL_CALLER_ROLES[number]\nconst isToolCallerRole = makeGuard(TOOL_CALLER_ROLES)\n\nexport interface ToolCallRecordRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** The mesh tool name, e.g. `mesh_status` (identifier, not free text — always a fixed tool-name string). */\n tool: string\n sessionId?: string\n callerRole: ToolCallerRole\n}\n\nexport interface ToolCallRecordResponse {\n rateLimitExceeded: boolean\n callsInWindow: number\n /** Short machine-oriented advisory string, or null. Never free text describing content. */\n advisory: string | null\n}\n\nfunction isToolCallRecordRequest(value: unknown): value is ToolCallRecordRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'tool', 'sessionId', 'callerRole'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isEvidenceIdentifier(value.meshId)\n && isEvidenceIdentifier(value.tool)\n && isOptionalId(value.sessionId)\n && isToolCallerRole(value.callerRole)\n}\n\nexport function decodeToolCallRecordRequest(value: unknown): ToolCallRecordRequest | null {\n return isToolCallRecordRequest(value) ? value : null\n}\n\nfunction isToolCallRecordResponse(value: unknown): value is ToolCallRecordResponse {\n return isRecord(value) && hasOnlyKeys(value, ['rateLimitExceeded', 'callsInWindow', 'advisory'])\n && typeof value.rateLimitExceeded === 'boolean'\n && isNonNegativeInt(value.callsInWindow)\n && (value.advisory === null || typeof value.advisory === 'string')\n}\n\nexport function decodeToolCallRecordResponse(value: unknown): ToolCallRecordResponse | null {\n return isToolCallRecordResponse(value) ? value : null\n}\n\n// ─── ledger_query ───────────────────────────────────────────────────────────\n//\n// Wiring-unification Phase C, workstream C-W9b.\n//\n// Replaces the remaining bare `readLedgerEntries(meshId, opts)` /\n// `getLedgerSummary(meshId)` in-process reads that `turn_query` cannot serve\n// (§5 C2's `mesh-tools-mission.ts` file-header note, 2026-09-24: \"general\n// ledger browsing by arbitrary `kind`/`since`/`node` filters —\n// `turn_query`'s shape... has no free-form kind-list or node filter, so this\n// is a real API mismatch, not a mechanical rename\"). `turn_query` stays\n// scoped to the turn-ledger's own attempt/event rows; `ledger_query` is the\n// general record browse surface (C-W9a: the daemon's `mesh_local_records` plus\n// the turn ledger's task outcomes, `readLocalRecords`) `meshTaskHistory` /\n// `meshLedgerQuery` need.\n//\n// CONTENT BOUNDARY: `MeshLedgerEntry.payload` (daemon-core `mesh-ledger.ts`)\n// is `Record<string, unknown>` — genuinely unbounded JSON (a graph plan, a free-text checkpoint message), NOT constrained to\n// `mesh_record`'s scalar allow-list. This is fine for the SAME reason\n// `mission_upsert`'s `goal` and `note_upsert`'s `text` are fine (see that\n// section's note above): this is local IPC between mcp-server and the\n// daemon that owns the ledger, both on the operator's own machine — never a\n// cross-machine or server hop. `entryPayload` below is therefore an\n// intentionally-unvalidated `Record<string, unknown>` passthrough, exactly\n// like `MissionUpsertRequest.goal` is unvalidated free text.\n\nexport interface LedgerQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** One or more ledger `kind` strings (daemon-core `MeshLedgerKind`; mesh-shared cannot import that union, so these are identifiers here). Omitted = every kind. */\n kind?: readonly string[]\n /** ISO-8601 or epoch-ms-as-string — passed through to `readLedgerEntries`'s `since` (parsed via `new Date()`). */\n since?: string\n /** Filter to entries whose nodeId is equivalent to this daemon id (matched via `daemonIdsEquivalent` daemon-side, not raw `===`). */\n node?: string\n tail?: number\n /** Also return `getLedgerSummary(meshId)` alongside the entries — saves a second round trip for callers that want both (the common case: every existing call site fetches both together). */\n includeSummary?: boolean\n}\n\nexport interface LedgerQueryEntryWire {\n id: string\n meshId: string\n timestamp: string\n kind: string\n nodeId?: string\n sessionId?: string\n providerType?: string\n taskId?: string\n /** Unbounded JSON passthrough — see file section's CONTENT BOUNDARY note. */\n payload: Record<string, unknown>\n}\n\nexport interface LedgerQuerySummaryWire {\n meshId: string\n totalEntries: number\n taskDispatched: number\n taskCompleted: number\n taskFailed: number\n taskStalled: number\n sessionLaunched: number\n checkpointCreated: number\n lastActivityAt: string | null\n recentFailures: number\n}\n\nexport interface LedgerQueryResponse {\n entries: readonly LedgerQueryEntryWire[]\n summary?: LedgerQuerySummaryWire\n}\n\nfunction isLedgerQueryRequest(value: unknown): value is LedgerQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'kind', 'since', 'node', 'tail', 'includeSummary'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n if (value.kind !== undefined && (!Array.isArray(value.kind) || value.kind.length === 0 || !value.kind.every(isEvidenceIdentifier))) return false\n if (value.since !== undefined && typeof value.since !== 'string') return false\n if (!isOptionalId(value.node)) return false\n if (value.tail !== undefined && !isNonNegativeInt(value.tail)) return false\n if (value.includeSummary !== undefined && typeof value.includeSummary !== 'boolean') return false\n return true\n}\n\nexport function decodeLedgerQueryRequest(value: unknown): LedgerQueryRequest | null {\n return isLedgerQueryRequest(value) ? value : null\n}\n\nconst LEDGER_QUERY_ENTRY_KEYS = ['id', 'meshId', 'timestamp', 'kind', 'nodeId', 'sessionId', 'providerType', 'taskId', 'payload'] as const\n\nfunction isLedgerQueryEntryWire(value: unknown): value is LedgerQueryEntryWire {\n if (!isRecord(value) || !hasOnlyKeys(value, LEDGER_QUERY_ENTRY_KEYS)) return false\n if (!isEvidenceIdentifier(value.id) || !isEvidenceIdentifier(value.meshId)) return false\n if (typeof value.timestamp !== 'string' || typeof value.kind !== 'string') return false\n if (!isOptionalId(value.nodeId) || !isOptionalId(value.sessionId) || !isOptionalId(value.providerType) || !isOptionalId(value.taskId)) return false\n if (!isRecord(value.payload)) return false\n return true\n}\n\nfunction isLedgerQuerySummaryWire(value: unknown): value is LedgerQuerySummaryWire {\n const keys = ['meshId', 'totalEntries', 'taskDispatched', 'taskCompleted', 'taskFailed', 'taskStalled', 'sessionLaunched', 'checkpointCreated', 'lastActivityAt', 'recentFailures'] as const\n if (!isRecord(value) || !hasOnlyKeys(value, keys)) return false\n if (!isEvidenceIdentifier(value.meshId)) return false\n for (const k of ['totalEntries', 'taskDispatched', 'taskCompleted', 'taskFailed', 'taskStalled', 'sessionLaunched', 'checkpointCreated', 'recentFailures'] as const) {\n if (!isNonNegativeInt(value[k])) return false\n }\n if (value.lastActivityAt !== null && typeof value.lastActivityAt !== 'string') return false\n return true\n}\n\nfunction isLedgerQueryResponse(value: unknown): value is LedgerQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['entries', 'summary'])) return false\n if (!Array.isArray(value.entries) || !value.entries.every(isLedgerQueryEntryWire)) return false\n if (value.summary !== undefined && !isLedgerQuerySummaryWire(value.summary)) return false\n return true\n}\n\nexport function decodeLedgerQueryResponse(value: unknown): LedgerQueryResponse | null {\n return isLedgerQueryResponse(value) ? value : null\n}\n","/**\n * turn-ipc — local records, queue composites and active work (C-W9a):\n * record_local, queue_query, queue_enqueue, queue_enqueue_batch, queue_cancel,\n * queue_requeue, direct_dispatch_record, active_work_query,\n * recovery_context_query. Part of the turn-ipc wire contract (./turn-ipc.ts).\n */\n\n// ─── C-W9a: local records, queue composites, active work ────────────────────\n//\n// Wiring-unification Phase C, workstream C-W9a (the 2026-09-24 14:00 stamp\n// \"Left for C-W9\"): the event ledger and its JSONL mirror are gone, and every\n// mcp-server call that still reached the daemon's `mesh-runtime.db` in-process\n// — record appends, queue mutations, the queue/active-work reads that fed\n// `buildMeshActiveWork`, recovery hints — moves behind the commands below,\n// executed in the daemon that owns the store.\n//\n// CONTENT BOUNDARY: like `mission_upsert`'s `goal`, `note_upsert`'s `text` and\n// `ledger_query`'s entry payloads, several fields here are free text or\n// unbounded JSON (a task message, a queue row with its\n// message, an active-work record with its task summary). This is fine for the\n// same reason: local IPC between the mcp-server and the daemon on the\n// operator's own machine — never a cross-machine or server hop. Those fields\n// are documented as passthroughs and validated only for shape (object/array),\n// exactly like `LedgerQueryEntryWire.payload`. Nothing here is ever published\n// to a topic: `record_local`'s topic leg is the daemon's `mesh.record`\n// allow-list projection, which drops free text by construction.\n\nimport { isRecord } from './protocol/envelope';\nimport { isEvidenceIdentifier } from './turn-evidence';\nimport {\n TURN_IPC_PROTOCOL_VERSION,\n hasOnlyKeys,\n isOptionalId,\n isNonNegativeInt,\n isOptionalBoolean,\n isOptionalRecord,\n isRecordArray,\n isOptionalString,\n} from './turn-ipc-guards';\n\n/** A queue row as the daemon's `getQueue` returns it — a JSON passthrough (see the section note). */\nexport type QueueEntryWire = Record<string, unknown> & { id: string; status: string }\n\nfunction isQueueEntryWire(value: unknown): value is QueueEntryWire {\n return isRecord(value) && isEvidenceIdentifier(value.id) && typeof value.status === 'string'\n}\n\n// ── record_local ──\n//\n// `meshRecord(meshId, kind, scalars, { local: true })` over IPC: the scalar\n// projection goes to `mesh.<id>.events` (content-free), the FULL payload lands\n// in the daemon's `mesh_local_records` (local-only). Replaces every mcp-server\n// `appendLedgerEntry` (dispatch / checkpoint message /\n// reconcile records). `payload` is free-form JSON (see the section note).\n\nexport interface RecordLocalRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** A `MeshLedgerKind` (daemon-core); an identifier here (mesh-shared cannot import that union). */\n kind: string\n nodeId?: string\n sessionId?: string\n providerType?: string\n taskId?: string\n payload: Record<string, unknown>\n}\n\nexport interface RecordLocalResponse {\n eventId: string\n timestamp: string\n storedLocally: boolean\n published: boolean\n}\n\nfunction isRecordLocalRequest(value: unknown): value is RecordLocalRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'kind', 'nodeId', 'sessionId', 'providerType', 'taskId', 'payload'])\n && value.v === TURN_IPC_PROTOCOL_VERSION\n && isEvidenceIdentifier(value.meshId)\n && isEvidenceIdentifier(value.kind)\n && isOptionalId(value.nodeId) && isOptionalId(value.sessionId) && isOptionalId(value.providerType) && isOptionalId(value.taskId)\n && isRecord(value.payload)\n}\n\nexport function decodeRecordLocalRequest(value: unknown): RecordLocalRequest | null {\n return isRecordLocalRequest(value) ? value : null\n}\n\nfunction isRecordLocalResponse(value: unknown): value is RecordLocalResponse {\n return isRecord(value) && hasOnlyKeys(value, ['eventId', 'timestamp', 'storedLocally', 'published'])\n && isEvidenceIdentifier(value.eventId) && typeof value.timestamp === 'string'\n && typeof value.storedLocally === 'boolean' && typeof value.published === 'boolean'\n}\n\nexport function decodeRecordLocalResponse(value: unknown): RecordLocalResponse | null {\n return isRecordLocalResponse(value) ? value : null\n}\n\n// ── queue_query ──\n\nexport interface QueueQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** Status filter (queue statuses); omitted = every row. */\n statuses?: readonly string[]\n /** One row by id (returns 0 or 1 entries). */\n taskId?: string\n /** Project for a VIEW surface: the persisted input envelope → `inputSummary` (summarizeQueueEntryInputForView). */\n view?: boolean\n /**\n * Also return the per-status row counts of the WHOLE mesh queue (columns only,\n * no payload parse) — lets a view read only the rows it shows yet report\n * mesh-wide counts. An older daemon rejects the key.\n */\n withCounts?: boolean\n /** With `withCounts`: also count terminal rows whose `updated_at` is older than this age. */\n historicalOlderThanMs?: number\n /**\n * Also return `dependencyHeads`: id/status/cancelReason of every\n * row the returned entries list in `dependsOn` that is not itself returned —\n * enough to annotate dependency state without reading the whole queue.\n */\n withDependencyHeads?: boolean\n}\n\n/** A dependency row reduced to the fields dependency-state annotation reads. */\nexport interface QueueDependencyHeadWire {\n id: string\n status: string\n cancelReason?: string\n}\n\nexport interface QueueQueryResponse {\n entries: readonly QueueEntryWire[]\n /** `withCounts`: row count per status over the whole mesh queue. */\n counts?: Record<string, number>\n /** `withCounts` + `historicalOlderThanMs`: terminal rows older than that age. */\n oldHistoricalCount?: number\n /** `withDependencyHeads`. */\n dependencyHeads?: readonly QueueDependencyHeadWire[]\n}\n\nfunction isQueueQueryRequest(value: unknown): value is QueueQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'statuses', 'taskId', 'view', 'withCounts', 'historicalOlderThanMs', 'withDependencyHeads'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId)) return false\n if (value.statuses !== undefined && (!Array.isArray(value.statuses) || !value.statuses.every(isEvidenceIdentifier))) return false\n if (value.historicalOlderThanMs !== undefined && !isNonNegativeInt(value.historicalOlderThanMs)) return false\n return isOptionalId(value.taskId) && isOptionalBoolean(value.view)\n && isOptionalBoolean(value.withCounts) && isOptionalBoolean(value.withDependencyHeads)\n}\n\nexport function decodeQueueQueryRequest(value: unknown): QueueQueryRequest | null {\n return isQueueQueryRequest(value) ? value : null\n}\n\nfunction isQueueDependencyHeadWire(value: unknown): value is QueueDependencyHeadWire {\n return isRecord(value) && hasOnlyKeys(value, ['id', 'status', 'cancelReason'])\n && typeof value.id === 'string' && typeof value.status === 'string'\n && (value.cancelReason === undefined || typeof value.cancelReason === 'string')\n}\n\nfunction isQueueQueryResponse(value: unknown): value is QueueQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['entries', 'counts', 'oldHistoricalCount', 'dependencyHeads'])) return false\n if (!Array.isArray(value.entries) || !value.entries.every(isQueueEntryWire)) return false\n if (value.counts !== undefined && (!isRecord(value.counts) || !Object.values(value.counts).every(isNonNegativeInt))) return false\n if (value.oldHistoricalCount !== undefined && !isNonNegativeInt(value.oldHistoricalCount)) return false\n if (value.dependencyHeads !== undefined && (!Array.isArray(value.dependencyHeads) || !value.dependencyHeads.every(isQueueDependencyHeadWire))) return false\n return true\n}\n\nexport function decodeQueueQueryResponse(value: unknown): QueueQueryResponse | null {\n return isQueueQueryResponse(value) ? value : null\n}\n\n// ── queue_enqueue ──\n//\n// `enqueueTask(meshId, message, options)` in the daemon. `options` is\n// `MeshEnqueueTaskOptions` (daemon-core) as a JSON\n// passthrough; the daemon's enqueue guards (message, task-mode, difficulty,\n// dependency cycle) run unchanged and a refusal comes back as the error.\n\nexport interface QueueEnqueueRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** Free text (the task message — see the section note). */\n message: string\n options?: Record<string, unknown>\n}\n\nexport interface QueueEnqueueResponse {\n entry: QueueEntryWire\n}\n\nfunction isQueueEnqueueRequest(value: unknown): value is QueueEnqueueRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'message', 'options'])\n && value.v === TURN_IPC_PROTOCOL_VERSION && isEvidenceIdentifier(value.meshId)\n && typeof value.message === 'string'\n && isOptionalRecord(value.options)\n}\n\nexport function decodeQueueEnqueueRequest(value: unknown): QueueEnqueueRequest | null {\n return isQueueEnqueueRequest(value) ? value : null\n}\n\nfunction isQueueEnqueueResponse(value: unknown): value is QueueEnqueueResponse {\n return isRecord(value) && hasOnlyKeys(value, ['entry']) && isQueueEntryWire(value.entry)\n}\n\nexport function decodeQueueEnqueueResponse(value: unknown): QueueEnqueueResponse | null {\n return isQueueEnqueueResponse(value) ? value : null\n}\n\n// ── queue_enqueue_batch ──\n//\n// The atomic multi-task enqueue in the daemon: `enqueueTaskBatch(meshId, specs)`\n// — every task inserts or none does. A refusal answers\n// `{ ok: false, refusalCode?, message, extra? }` (a domain refusal is a RESULT\n// here, not a transport error, so the caller keeps its code/extra for the tool\n// response). NOT `code`/`error`: those two keys belong to the command envelope\n// (`{ success, error, code }`) the client unwraps, so a result must never\n// reuse them.\n\nexport interface QueueEnqueueBatchRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** `MeshTaskBatchEntrySpec[]` (daemon-core, JSON passthrough). */\n specs: readonly Record<string, unknown>[]\n}\n\nexport type QueueEnqueueBatchResponse =\n | { ok: true; tasks: readonly QueueEntryWire[] }\n | { ok: false; refusalCode?: string; message: string; extra?: Record<string, unknown> }\n\nfunction isQueueEnqueueBatchRequest(value: unknown): value is QueueEnqueueBatchRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'specs'])\n && value.v === TURN_IPC_PROTOCOL_VERSION && isEvidenceIdentifier(value.meshId)\n && isRecordArray(value.specs)\n}\n\nexport function decodeQueueEnqueueBatchRequest(value: unknown): QueueEnqueueBatchRequest | null {\n return isQueueEnqueueBatchRequest(value) ? value : null\n}\n\nfunction isQueueEnqueueBatchResponse(value: unknown): value is QueueEnqueueBatchResponse {\n if (!isRecord(value)) return false\n if (value.ok === true) {\n return hasOnlyKeys(value, ['ok', 'tasks']) && Array.isArray(value.tasks) && value.tasks.every(isQueueEntryWire)\n }\n if (value.ok === false) {\n return hasOnlyKeys(value, ['ok', 'refusalCode', 'message', 'extra']) && typeof value.message === 'string'\n && isOptionalString(value.refusalCode) && isOptionalRecord(value.extra)\n }\n return false\n}\n\nexport function decodeQueueEnqueueBatchResponse(value: unknown): QueueEnqueueBatchResponse | null {\n return isQueueEnqueueBatchResponse(value) ? value : null\n}\n\n// ── queue_cancel ──\n\nexport interface QueueCancelRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n taskId: string\n /** Operator reason (free text, local IPC). */\n reason?: string\n}\n\nexport interface QueueCancelResponse {\n /** The cancelled row, or null when no such task. */\n task: QueueEntryWire | null\n /** The row as it was BEFORE the cancel (its assignment is what a caller stops). */\n before: QueueEntryWire | null\n}\n\nfunction isQueueCancelRequest(value: unknown): value is QueueCancelRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'taskId', 'reason'])\n && value.v === TURN_IPC_PROTOCOL_VERSION && isEvidenceIdentifier(value.meshId) && isEvidenceIdentifier(value.taskId)\n && isOptionalString(value.reason)\n}\n\nexport function decodeQueueCancelRequest(value: unknown): QueueCancelRequest | null {\n return isQueueCancelRequest(value) ? value : null\n}\n\nfunction isQueueCancelResponse(value: unknown): value is QueueCancelResponse {\n return isRecord(value) && hasOnlyKeys(value, ['task', 'before'])\n && (value.task === null || isQueueEntryWire(value.task))\n && (value.before === null || isQueueEntryWire(value.before))\n}\n\nexport function decodeQueueCancelResponse(value: unknown): QueueCancelResponse | null {\n return isQueueCancelResponse(value) ? value : null\n}\n\n// ── queue_requeue ──\n\nexport interface QueueRequeueRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n taskId: string\n /** `requeueTask` options (reason / targetNodeId / targetSessionId / clear* / force / message / maxRetries / notBefore), JSON passthrough. */\n options?: Record<string, unknown>\n}\n\nexport interface QueueRequeueResponse {\n task: QueueEntryWire | null\n}\n\nfunction isQueueRequeueRequest(value: unknown): value is QueueRequeueRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'taskId', 'options'])\n && value.v === TURN_IPC_PROTOCOL_VERSION && isEvidenceIdentifier(value.meshId) && isEvidenceIdentifier(value.taskId)\n && isOptionalRecord(value.options)\n}\n\nexport function decodeQueueRequeueRequest(value: unknown): QueueRequeueRequest | null {\n return isQueueRequeueRequest(value) ? value : null\n}\n\nfunction isQueueRequeueResponse(value: unknown): value is QueueRequeueResponse {\n return isRecord(value) && hasOnlyKeys(value, ['task']) && (value.task === null || isQueueEntryWire(value.task))\n}\n\nexport function decodeQueueRequeueResponse(value: unknown): QueueRequeueResponse | null {\n return isQueueRequeueResponse(value) ? value : null\n}\n\n// ── direct_dispatch_record ──\n//\n// The post-dispatch bookkeeping of `mesh_send_task`'s direct arms, in the\n// daemon: `recordDirectDispatchTask` (materialise the queue row, stamped with\n// the already-open `mesh_direct` attempt). Best-effort and reported — a\n// dispatch that already happened must never fail on its bookkeeping.\n\nexport interface DirectDispatchRecordRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n taskId: string\n /** Free text (the authored task message — the materialised row keeps it). */\n message: string\n /** `recordDirectDispatchTask` options minus `id` (JSON passthrough). */\n task?: Record<string, unknown>\n}\n\nexport interface DirectDispatchRecordResponse {\n taskRecorded: boolean\n}\n\nfunction isDirectDispatchRecordRequest(value: unknown): value is DirectDispatchRecordRequest {\n return isRecord(value) && hasOnlyKeys(value, ['v', 'meshId', 'taskId', 'message', 'task'])\n && value.v === TURN_IPC_PROTOCOL_VERSION && isEvidenceIdentifier(value.meshId) && isEvidenceIdentifier(value.taskId)\n && typeof value.message === 'string' && isOptionalRecord(value.task)\n}\n\nexport function decodeDirectDispatchRecordRequest(value: unknown): DirectDispatchRecordRequest | null {\n return isDirectDispatchRecordRequest(value) ? value : null\n}\n\nfunction isDirectDispatchRecordResponse(value: unknown): value is DirectDispatchRecordResponse {\n return isRecord(value) && hasOnlyKeys(value, ['taskRecorded'])\n && typeof value.taskRecorded === 'boolean'\n}\n\nexport function decodeDirectDispatchRecordResponse(value: unknown): DirectDispatchRecordResponse | null {\n return isDirectDispatchRecordResponse(value) ? value : null\n}\n\n// ── active_work_query ──\n//\n// The active-work view, COMPUTED in the daemon: it reads the queue, the open\n// direct dispatches (`mesh_direct` attempts) and its local records (+ turn\n// outcomes), and runs `buildMeshActiveWork` over them with the caller's live\n// node probe results. `includeInputs` also returns the records + dispatches it\n// used (the transcript-reconcile pass and the stale-direct prune read them);\n// `compute: false` returns only those inputs. `includeSchedulingRuntime` adds\n// `buildMeshSchedulingRuntime(mesh, queue)` for the caller's `mesh` snapshot.\n// `queue` lets a caller substitute its own annotated queue view.\n\nexport interface ActiveWorkQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n /** Live node probe results (`buildMeshActiveWork`'s `nodes`), JSON passthrough. */\n nodes?: readonly Record<string, unknown>[]\n /** Substitute queue rows (default: the daemon's `getQueue`). */\n queue?: readonly Record<string, unknown>[]\n /** Record tail fed to active work (default 200). */\n recordTail?: number\n includeTerminalDirect?: boolean\n /** Default true. */\n compute?: boolean\n includeInputs?: boolean\n includeSummary?: boolean\n includeSchedulingRuntime?: boolean\n /**\n * The caller's mesh snapshot for the scheduling runtime, JSON passthrough.\n * Optional since the daemon resolves its own mesh record when it is absent;\n * an older daemon rejects `includeSchedulingRuntime` without it (the caller's\n * feature-detect signal to resend with the mesh).\n */\n mesh?: Record<string, unknown>\n}\n\nexport interface ActiveWorkQueryResponse {\n /** `MeshActiveWorkEvidence` (daemon-core), JSON passthrough; absent when `compute: false`. */\n activeWork?: Record<string, unknown>\n records?: readonly Record<string, unknown>[]\n directDispatches?: readonly Record<string, unknown>[]\n /** `MeshLedgerSummary`-shaped record summary. */\n summary?: Record<string, unknown>\n schedulingRuntime?: Record<string, unknown>\n}\n\nfunction isActiveWorkQueryRequest(value: unknown): value is ActiveWorkQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'nodes', 'queue', 'recordTail', 'includeTerminalDirect', 'compute', 'includeInputs', 'includeSummary', 'includeSchedulingRuntime', 'mesh'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId)) return false\n if (value.nodes !== undefined && !isRecordArray(value.nodes)) return false\n if (value.queue !== undefined && !isRecordArray(value.queue)) return false\n if (value.recordTail !== undefined && !isNonNegativeInt(value.recordTail)) return false\n return isOptionalBoolean(value.includeTerminalDirect) && isOptionalBoolean(value.compute) && isOptionalBoolean(value.includeInputs)\n && isOptionalBoolean(value.includeSummary) && isOptionalBoolean(value.includeSchedulingRuntime) && isOptionalRecord(value.mesh)\n}\n\nexport function decodeActiveWorkQueryRequest(value: unknown): ActiveWorkQueryRequest | null {\n return isActiveWorkQueryRequest(value) ? value : null\n}\n\nfunction isActiveWorkQueryResponse(value: unknown): value is ActiveWorkQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['activeWork', 'records', 'directDispatches', 'summary', 'schedulingRuntime'])) return false\n if (value.records !== undefined && !isRecordArray(value.records)) return false\n if (value.directDispatches !== undefined && !isRecordArray(value.directDispatches)) return false\n return isOptionalRecord(value.activeWork) && isOptionalRecord(value.summary) && isOptionalRecord(value.schedulingRuntime)\n}\n\nexport function decodeActiveWorkQueryResponse(value: unknown): ActiveWorkQueryResponse | null {\n return isActiveWorkQueryResponse(value) ? value : null\n}\n\n// ── recovery_context_query ──\n//\n// `getSessionRecoveryContext` (daemon-core `mesh-local-records.ts`) in the\n// daemon. `lastTaskMessage` / `advice` are free text (local IPC).\n\nexport interface RecoveryContextQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n nodeId?: string\n sessionId?: string\n maxRetries?: number\n /**\n * Batch: one context per node id, computed over ONE record read (answers\n * `contexts`). Exclusive with `nodeId`/`sessionId`. An older daemon rejects it.\n */\n nodeIds?: readonly string[]\n}\n\nexport interface RecoveryContextQueryResponse {\n /** Single mode (nodeId/sessionId). */\n context?: Record<string, unknown>\n /** Batch mode (`nodeIds`): context per node id. */\n contexts?: Record<string, Record<string, unknown>>\n}\n\nfunction isRecoveryContextQueryRequest(value: unknown): value is RecoveryContextQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'nodeId', 'sessionId', 'maxRetries', 'nodeIds'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId)) return false\n if (!isOptionalId(value.nodeId) || !isOptionalId(value.sessionId)) return false\n if (value.maxRetries !== undefined && !isNonNegativeInt(value.maxRetries)) return false\n if (value.nodeIds !== undefined) {\n if (!Array.isArray(value.nodeIds) || value.nodeIds.length === 0 || !value.nodeIds.every(isEvidenceIdentifier)) return false\n return value.nodeId === undefined && value.sessionId === undefined\n }\n return value.nodeId !== undefined || value.sessionId !== undefined\n}\n\nexport function decodeRecoveryContextQueryRequest(value: unknown): RecoveryContextQueryRequest | null {\n return isRecoveryContextQueryRequest(value) ? value : null\n}\n\nfunction isRecoveryContextWire(value: unknown): boolean {\n return isRecord(value) && typeof value.consecutiveNodeFailures === 'number'\n}\n\nfunction isRecoveryContextQueryResponse(value: unknown): value is RecoveryContextQueryResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['context', 'contexts'])) return false\n if (value.context === undefined && value.contexts === undefined) return false\n if (value.context !== undefined && !isRecoveryContextWire(value.context)) return false\n if (value.contexts !== undefined && (!isRecord(value.contexts) || !Object.values(value.contexts).every(isRecoveryContextWire))) return false\n return true\n}\n\nexport function decodeRecoveryContextQueryResponse(value: unknown): RecoveryContextQueryResponse | null {\n return isRecoveryContextQueryResponse(value) ? value : null\n}\n","/**\n * turn-ipc — task stats and maintenance commands: task_stats_query,\n * prune_stale_direct, orphaned_pin_notify. Part of the turn-ipc wire contract\n * (./turn-ipc.ts).\n */\n\nimport {\n TURN_IPC_PROTOCOL_VERSION,\n hasOnlyKeys,\n isOptionalBoolean,\n isOptionalRecord,\n isNonNegativeInt,\n isRecordArray,\n} from './turn-ipc-guards';\nimport { isRecord } from './protocol/envelope';\nimport { isEvidenceIdentifier } from './turn-evidence';\n\n// ─── task_stats_query ───────────────────────────────────────────────────────\n//\n// C-W9c: replaces the in-process `computeMeshTaskStats` / `computeMeshMissionStats`\n// (daemon-core `mesh-task-stats.ts`) — both scan the daemon's queue + local\n// records, so both move behind one command. Exactly one of `taskIds` /\n// `missionId` selects the per-task mode; `missionId` alone with `rollup: true`\n// additionally returns the mission-level aggregate.\n\nexport interface TaskStatsQueryRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n taskIds?: readonly string[]\n missionId?: string\n tail?: number\n /** Also compute `computeMeshMissionStats` — requires `missionId`. */\n rollup?: boolean\n /**\n * Batch rollups: `computeMeshMissionStats` for every id, over ONE queue read and\n * ONE record read (answers `missions`, `tasks` empty). Exclusive with\n * `taskIds`/`missionId`. An older daemon rejects the key.\n */\n missionIds?: readonly string[]\n}\n\nexport interface TaskStatsQueryResponse {\n /** `MeshTaskStats[]`, JSON passthrough. */\n tasks: readonly Record<string, unknown>[]\n /** `MeshMissionStats`, JSON passthrough; present only when `rollup: true` was requested and satisfiable. */\n mission?: Record<string, unknown>\n /** Batch mode: `MeshMissionStats` per requested mission id, JSON passthrough. */\n missions?: Record<string, Record<string, unknown>>\n}\n\nfunction isTaskStatsQueryRequest(value: unknown): value is TaskStatsQueryRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'taskIds', 'missionId', 'tail', 'rollup', 'missionIds'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId)) return false\n if (value.taskIds !== undefined) {\n if (!Array.isArray(value.taskIds) || value.taskIds.length === 0 || !value.taskIds.every(isEvidenceIdentifier)) return false\n }\n if (value.missionId !== undefined && !isEvidenceIdentifier(value.missionId)) return false\n if (value.tail !== undefined && !isNonNegativeInt(value.tail)) return false\n if (value.missionIds !== undefined) {\n if (!Array.isArray(value.missionIds) || value.missionIds.length === 0 || !value.missionIds.every(isEvidenceIdentifier)) return false\n if (value.taskIds !== undefined || value.missionId !== undefined) return false\n }\n if (value.rollup === true && value.missionId === undefined) return false\n return isOptionalBoolean(value.rollup)\n}\n\nexport function decodeTaskStatsQueryRequest(value: unknown): TaskStatsQueryRequest | null {\n return isTaskStatsQueryRequest(value) ? value : null\n}\n\nfunction isTaskStatsQueryResponse(value: unknown): value is TaskStatsQueryResponse {\n return isRecord(value) && hasOnlyKeys(value, ['tasks', 'mission', 'missions']) && isRecordArray(value.tasks) && isOptionalRecord(value.mission)\n && (value.missions === undefined || (isRecord(value.missions) && Object.values(value.missions).every(isRecord)))\n}\n\nexport function decodeTaskStatsQueryResponse(value: unknown): TaskStatsQueryResponse | null {\n return isTaskStatsQueryResponse(value) ? value : null\n}\n\n// ─── prune_stale_direct ─────────────────────────────────────────────────────\n//\n// C-W9c: replaces the in-process `pruneStaleDirectDispatches` call\n// (`mesh_cleanup_sessions` mode=prune_stale_direct, `mesh-tools-session.ts`). Unlike the other\n// C-W9 commands this one does NOT take its inputs (queue/records/direct\n// dispatches) on the wire — the daemon already reads them itself\n// (`getQueue`/`readLocalRecords`/`getActiveDirectDispatches`), so the request\n// carries only the decision knobs. `closeDispatches` (the C-W8 `turn_cancel`\n// callback) also runs daemon-side now, since it is the same process.\n\nexport interface PruneStaleDirectRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n execute?: boolean\n includeTerminal?: boolean\n source?: string\n}\n\nexport interface PruneStaleDirectResponse {\n mode: 'execute' | 'dry_run'\n includeTerminal: boolean\n candidateCount: number\n /** `MeshActiveWorkRecord[]`, JSON passthrough. */\n prunable: readonly Record<string, unknown>[]\n prunedCount: number\n preservedUnacknowledged: readonly Record<string, unknown>[]\n preservedLedgerOnly: readonly Record<string, unknown>[]\n preservedNotOrphan: readonly Record<string, unknown>[]\n}\n\nfunction isPruneStaleDirectRequest(value: unknown): value is PruneStaleDirectRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'execute', 'includeTerminal', 'source'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId)) return false\n if (value.source !== undefined && typeof value.source !== 'string') return false\n return isOptionalBoolean(value.execute) && isOptionalBoolean(value.includeTerminal)\n}\n\nexport function decodePruneStaleDirectRequest(value: unknown): PruneStaleDirectRequest | null {\n return isPruneStaleDirectRequest(value) ? value : null\n}\n\nfunction isPruneStaleDirectResponse(value: unknown): value is PruneStaleDirectResponse {\n if (!isRecord(value) || !hasOnlyKeys(value, ['mode', 'includeTerminal', 'candidateCount', 'prunable', 'prunedCount', 'preservedUnacknowledged', 'preservedLedgerOnly', 'preservedNotOrphan'])) return false\n if (value.mode !== 'execute' && value.mode !== 'dry_run') return false\n if (typeof value.includeTerminal !== 'boolean') return false\n if (!isNonNegativeInt(value.candidateCount) || !isNonNegativeInt(value.prunedCount)) return false\n return isRecordArray(value.prunable) && isRecordArray(value.preservedUnacknowledged)\n && isRecordArray(value.preservedLedgerOnly) && isRecordArray(value.preservedNotOrphan)\n}\n\nexport function decodePruneStaleDirectResponse(value: unknown): PruneStaleDirectResponse | null {\n return isPruneStaleDirectResponse(value) ? value : null\n}\n\n// ─── orphaned_pin_notify ────────────────────────────────────────────────────\n//\n// C-W9c: replaces the in-process `notifyCoordinatorOfOrphanedPins` call\n// (`mesh_queue_cancel` tool, `mesh-tools-queue.ts`, CANCEL-ORPHANS-PINNED-TASK).\n// The core reads the daemon's live queue (`getQueue`) and, when it finds\n// orphans, calls `notifyMeshCoordinator` to page the coordinator — both are\n// daemon-only concerns, so the whole call moves, not just its queue read.\n// `title` is a task-message-derived label (first line, truncated) — free text,\n// hence local IPC only, same rationale as `record_local`'s payload.\n\nexport interface OrphanedPinNotifyRequest {\n v: typeof TURN_IPC_PROTOCOL_VERSION\n meshId: string\n stoppedSessionId: string\n excludeTaskId?: string\n cause?: string\n nodeId?: string\n coordinatorSessionId?: string\n}\n\nexport interface OrphanedPinnedTaskWire {\n taskId: string\n title: string\n targetSessionId: string\n targetNodeId?: string\n missionId?: string\n}\n\nexport interface OrphanedPinNotifyResponse {\n orphans: readonly OrphanedPinnedTaskWire[]\n}\n\nfunction isOrphanedPinnedTaskWire(value: unknown): value is OrphanedPinnedTaskWire {\n if (!isRecord(value) || !hasOnlyKeys(value, ['taskId', 'title', 'targetSessionId', 'targetNodeId', 'missionId'])) return false\n if (!isEvidenceIdentifier(value.taskId) || !isEvidenceIdentifier(value.targetSessionId)) return false\n if (typeof value.title !== 'string') return false\n if (value.targetNodeId !== undefined && !isEvidenceIdentifier(value.targetNodeId)) return false\n return value.missionId === undefined || isEvidenceIdentifier(value.missionId)\n}\n\nfunction isOrphanedPinNotifyRequest(value: unknown): value is OrphanedPinNotifyRequest {\n if (!isRecord(value) || !hasOnlyKeys(value, ['v', 'meshId', 'stoppedSessionId', 'excludeTaskId', 'cause', 'nodeId', 'coordinatorSessionId'])) return false\n if (value.v !== TURN_IPC_PROTOCOL_VERSION || !isEvidenceIdentifier(value.meshId) || !isEvidenceIdentifier(value.stoppedSessionId)) return false\n if (value.excludeTaskId !== undefined && !isEvidenceIdentifier(value.excludeTaskId)) return false\n if (value.cause !== undefined && typeof value.cause !== 'string') return false\n if (value.nodeId !== undefined && !isEvidenceIdentifier(value.nodeId)) return false\n return value.coordinatorSessionId === undefined || isEvidenceIdentifier(value.coordinatorSessionId)\n}\n\nexport function decodeOrphanedPinNotifyRequest(value: unknown): OrphanedPinNotifyRequest | null {\n return isOrphanedPinNotifyRequest(value) ? value : null\n}\n\nfunction isOrphanedPinNotifyResponse(value: unknown): value is OrphanedPinNotifyResponse {\n return isRecord(value) && hasOnlyKeys(value, ['orphans']) && Array.isArray(value.orphans) && value.orphans.every(isOrphanedPinnedTaskWire)\n}\n\nexport function decodeOrphanedPinNotifyResponse(value: unknown): OrphanedPinNotifyResponse | null {\n return isOrphanedPinNotifyResponse(value) ? value : null\n}\n","/**\n * turn-ipc — typed IPC command contracts for the six commands that replace\n * mcp-server's direct `mesh-runtime.db` access (design §5 C2 \"MCP server\").\n *\n * Wiring-unification Phase C, workstream C-W6\n * (docs/design/2026-09-23-wiring-unification.md §5 C2/C3, C9 row C-W6).\n *\n * WHY THIS FILE EXISTS\n * ---------------------\n * mcp-server is a second, in-process writer of `mesh-runtime.db` (~45-69\n * direct-mutation call sites, ~54 reads, per the C-W6 brief). C2 moves every\n * one of those call sites behind IPC, executed in the daemon that owns the\n * turn ledger and the seqscribe node, so mcp-server never opens the SQLite\n * file itself. This file is the WIRE CONTRACT for that IPC surface — request/\n * response shapes, closed enums, runtime decoders — shared by the daemon-core\n * command handlers (added with C-W6 proper; NOT this file) and the mcp-server\n * client (`mcp-server/src/ipc/turn-commands.ts`, this workstream).\n *\n * The six commands (§5 C2):\n * - turn_observe — submit one TurnEvidence; returns the reducer verdict.\n * - mesh_record — append a content-free scalar record (`mesh.record`\n * topic entry), replacing `appendLedgerEntry`.\n * - turn_cancel — cancel an attempt (`cancel` evidence, source `mcp_probe`\n * or `operator`).\n * - operator_status — record a fire-and-forget operator/tool-call status\n * (`operator_status` evidence + the former\n * `recordMeshCoordinatorToolCall` log write).\n * - turn_query — read attempt/event rows (own or fleet scope).\n * - mesh_index_query — read `mesh_topic_index` rows (fleet-wide, replacing\n * the in-memory read model / parity reads).\n *\n * CONTENT BOUNDARY\n * -----------------\n * Every request/response field is an identifier, a closed enum, a boolean, a\n * counter or a timestamp. `turn_observe` carries a `TurnEvidence`, which is\n * content-free by construction (`turn-evidence.ts`). `mesh_record` carries a\n * `ProjectedScalars` payload restricted to the SAME allow-list keys\n * `seqscribe/mesh-event-projection.ts` already reviews and ships\n * (`PROJECTED_PAYLOAD_KEYS`, 35 keys) — this file pins a STRUCTURAL COPY of\n * that key list (`MESH_RECORD_PAYLOAD_KEYS`) so mesh-shared does not import\n * daemon-core (leaf constraint), with a test asserting the two lists agree.\n * Summaries, report bodies, progress notes and modal text never travel in any\n * of these payloads — they go to the content-class `mesh.<id>.handoff` topic\n * and are referenced by `SummaryRef {topic, writer, seq}` (already declared\n * in `./turn-evidence.ts`).\n *\n * VERSIONING\n * -----------\n * Every request carries `v: 1` so a future incompatible change can be\n * detected by the responder before it tries to interpret the args.\n *\n * LAYOUT\n * -------\n * This module holds the error codes and the command registry; the per-command\n * contracts live in ./turn-ipc-{turn,mission,queue,stats}.ts (re-exported here)\n * over the shared guard primitives in ./turn-ipc-guards.ts.\n */\n\nimport { isRecord } from './protocol/envelope'\nimport { hasOnlyKeys, makeGuard } from './turn-ipc-guards';\n\nexport { TURN_IPC_PROTOCOL_VERSION } from './turn-ipc-guards';\nexport * from './turn-ipc-turn';\nexport * from './turn-ipc-mission';\nexport * from './turn-ipc-queue';\nexport * from './turn-ipc-stats';\n\n// ─── error codes ────────────────────────────────────────────────────────────\n\n/**\n * Closed error-code union every command response may carry instead of (or in\n * addition to, for the client-side wrapper) a result.\n *\n * daemon_required — no daemon reachable (no IPC/local transport\n * connection could be established). Distinct from\n * every other failure: it means \"there is nobody to\n * ask\", not \"the ask failed.\"\n * turn_ledger_unavailable — a daemon answered but its turn ledger is not\n * armed yet (mid-boot, mid-migration).\n * ledger_not_owner — the daemon that answered does not own the\n * attempt/mesh addressed by the request (routing\n * mistake, or the owner changed after a reclaim).\n * session_busy_with_task — `turn_observe{dispatch_accepted}` was REFUSED: the\n * target session already holds an open mesh attempt\n * (≤1 open attempt per session). The error message\n * carries the machine token\n * `session_busy_with_task[task=<id> attempt=<id>]`\n * (daemon-core mesh-session-busy-dispatch.ts) naming\n * the attempt in the way. Unlike the codes above this\n * is a definite answer, not \"the ledger is not there\":\n * the dispatch must not be sent.\n */\nexport const TURN_IPC_ERROR_CODES = ['daemon_required', 'turn_ledger_unavailable', 'ledger_not_owner', 'session_busy_with_task'] as const\nexport type TurnIpcErrorCode = typeof TURN_IPC_ERROR_CODES[number]\n\nexport const isTurnIpcErrorCode = makeGuard(TURN_IPC_ERROR_CODES)\n\n/** Structured failure shape a responder returns instead of a result. Never thrown across the wire — the client maps it to a typed error (see mcp-server/src/ipc/turn-commands.ts). */\nexport interface TurnIpcError {\n code: TurnIpcErrorCode\n /** Short machine-oriented detail, e.g. which daemon was expected. Never free text describing content. */\n detail?: string\n}\n\nexport function isTurnIpcError(value: unknown): value is TurnIpcError {\n return isRecord(value) && hasOnlyKeys(value, ['code', 'detail']) && isTurnIpcErrorCode(value.code)\n && (value.detail === undefined || typeof value.detail === 'string')\n}\n\n// ─── command registry ───────────────────────────────────────────────────────\n\n/** The complete, closed set of IPC command names this contract defines. */\nexport const TURN_IPC_COMMANDS = [\n 'turn_observe',\n 'mesh_record',\n 'turn_cancel',\n 'operator_status',\n 'turn_query',\n 'mesh_index_query',\n 'mission_upsert',\n 'mission_query',\n 'note_upsert',\n 'note_forget',\n // C-W9b additions (2026-09-24 14:00 stamp \"C-W9\"):\n 'tool_call_record',\n 'ledger_query',\n 'mission_list_query',\n // C-W9a additions (the event ledger retired; the queue behind IPC):\n 'record_local',\n 'queue_query',\n 'queue_enqueue',\n 'queue_enqueue_batch',\n 'queue_cancel',\n 'queue_requeue',\n 'direct_dispatch_record',\n 'active_work_query',\n 'recovery_context_query',\n // C-W9c additions (2026-09-24 19:00 stamp — the last mcp-server in-process\n // daemon-core paths: mission reads, task/mission stats, orphaned-pin\n // helpers, one prune audit):\n 'task_stats_query',\n 'prune_stale_direct',\n 'orphaned_pin_notify',\n] as const\nexport type TurnIpcCommand = typeof TURN_IPC_COMMANDS[number]\nexport const isTurnIpcCommand = makeGuard(TURN_IPC_COMMANDS)\n","/**\n * path-ownership — declared file-ownership sets for `code_change` mesh tasks\n * (wiring-unification Phase H1, `docs/design/2026-09-23-wiring-unification.md`\n * §7c).\n *\n * Today two `code_change` tasks on two different nodes (two worktrees of the\n * same branch, or main + a worktree) can silently touch the same file with\n * zero warning — the only existing isolation is node-level (\"one active write\n * task per node\"), never path-level. This module is the pure, dependency-free\n * core of the fix: normalizing a caller-declared `owned_paths` list, and\n * comparing declared sets for overlap. It has NO opinion on enforcement policy\n * (refuse vs warn, which axis a caller compares against) — that is the mesh\n * runtime's job (`claimNextTask` / `claimNextQueueTask` in daemon-core); this\n * module only answers \"do these two declarations conflict\" and \"did the\n * touched-files report stay inside the declaration\".\n *\n * SCOPE DECISION (glob support): minimal, deliberately. A declaration entry is\n * either an exact repo-relative path (`src/foo.ts`) or a directory prefix\n * spelled with a trailing `/**` (`src/mesh/**`) meaning \"this path and\n * everything under it\". No `*`/`?` mid-segment wildcards, no `!` negation, no\n * brace expansion. Two `code_change` tasks racing on overlapping files is a\n * coordination bug to catch, not a general glob engine to build — a full\n * minimatch-style matcher would need its own test suite and still leave the\n * same ambiguity (does `src/*.ts` \"contain\" `src/foo.ts`?) the design doc's\n * risk list calls out. `src/` (no `**`) is treated as an exact single-path\n * entry, i.e. it owns a literal file/dir node named `src`, NOT everything\n * under it — callers who want subtree ownership must write `src/**`.\n *\n * Rejected inputs (absolute paths, `..` segments, backslash-only entries that\n * still resolve outside the repo after normalization) are dropped rather than\n * silently coerced — `normalizeOwnedPaths` reports what it dropped so the\n * caller (enqueue-time validation) can decide whether to warn or refuse.\n */\n\n/** One normalized ownership entry: a repo-relative path, optionally a `**` subtree prefix. */\nexport interface OwnedPathEntry {\n /** Repo-relative path with forward slashes, no leading `./`, no trailing slash. */\n readonly path: string\n /** True when this entry was declared as `<path>/**` (owns the whole subtree). */\n readonly subtree: boolean\n}\n\n/** A caller's normalized ownership declaration. */\nexport interface OwnedPathsDeclaration {\n readonly paths: readonly OwnedPathEntry[]\n}\n\nexport interface NormalizeOwnedPathsResult {\n readonly declaration: OwnedPathsDeclaration\n /** Raw input entries that were dropped, with why — surfaced to the caller, never silently coerced. */\n readonly rejected: ReadonlyArray<{ input: string; reason: string }>\n}\n\n/** Cap mirrors `depends_on`'s implicit list-size discipline (design doc H1 proposal). */\nexport const MAX_OWNED_PATHS = 64\n\nfunction toPosix(raw: string): string {\n return raw.replace(/\\\\/g, '/')\n}\n\n/**\n * Normalize one raw entry. Returns `null` (with a reason pushed to `rejected`)\n * for anything absolute, escaping the repo via `..`, or empty after trimming.\n */\nfunction normalizeOne(raw: unknown, rejected: Array<{ input: string; reason: string }>): OwnedPathEntry | null {\n if (typeof raw !== 'string') {\n rejected.push({ input: String(raw), reason: 'not_a_string' })\n return null\n }\n const trimmed = raw.trim()\n if (!trimmed) {\n rejected.push({ input: raw, reason: 'empty' })\n return null\n }\n let posix = toPosix(trimmed)\n\n // Absolute paths (POSIX `/…`, Windows drive letter `C:\\…` or `C:/…`, or a\n // stray leading `~`) are refused outright — ownership is repo-relative by\n // construction, and accepting an absolute path would let a declaration\n // silently escape the workspace it is meant to scope.\n if (posix.startsWith('/') || /^[a-zA-Z]:\\//.test(posix) || posix.startsWith('~')) {\n rejected.push({ input: raw, reason: 'absolute_path' })\n return null\n }\n\n // Strip a leading './'.\n posix = posix.replace(/^\\.\\/+/, '')\n\n // Reject any '..' segment anywhere — no escaping the repo root.\n const segments = posix.split('/').filter(Boolean)\n if (segments.some(seg => seg === '..')) {\n rejected.push({ input: raw, reason: 'parent_traversal' })\n return null\n }\n if (segments.length === 0) {\n rejected.push({ input: raw, reason: 'empty' })\n return null\n }\n\n // Minimal glob support: a trailing '**' segment (from '<path>/**') marks a\n // subtree declaration. Any OTHER '*'/'?' anywhere is rejected — this module\n // does not implement general glob matching (see module doc).\n let subtree = false\n if (segments[segments.length - 1] === '**') {\n subtree = true\n segments.pop()\n if (segments.length === 0) {\n // '**' alone (or './**') claims the entire repo — allowed, but the\n // caller (enqueue-time validation) is expected to lint/warn on it\n // per the design doc's deadlock risk; this module only normalizes.\n }\n }\n if (segments.some(seg => seg.includes('*') || seg.includes('?'))) {\n rejected.push({ input: raw, reason: 'unsupported_glob' })\n return null\n }\n\n return { path: segments.join('/'), subtree }\n}\n\n/**\n * Normalize a caller-supplied `owned_paths` array. Never throws — invalid\n * entries are dropped and reported in `rejected`; duplicates (after\n * normalization) collapse to one entry (subtree wins if either declaration\n * form is present for the same path). Entries beyond `MAX_OWNED_PATHS` (after\n * dedup) are dropped with reason `over_cap`, preserving declaration order.\n */\nexport function normalizeOwnedPaths(input: unknown): NormalizeOwnedPathsResult {\n const rejected: Array<{ input: string; reason: string }> = []\n if (input === undefined || input === null) {\n return { declaration: { paths: [] }, rejected }\n }\n if (!Array.isArray(input)) {\n return { declaration: { paths: [] }, rejected: [{ input: String(input), reason: 'not_an_array' }] }\n }\n\n const byPath = new Map<string, OwnedPathEntry>()\n for (const raw of input) {\n const entry = normalizeOne(raw, rejected)\n if (!entry) continue\n const existing = byPath.get(entry.path)\n if (!existing) {\n byPath.set(entry.path, entry)\n } else if (entry.subtree && !existing.subtree) {\n byPath.set(entry.path, entry)\n }\n // else: duplicate, existing entry already at least as broad — keep it.\n }\n\n const all = [...byPath.values()]\n const kept = all.slice(0, MAX_OWNED_PATHS)\n for (const dropped of all.slice(MAX_OWNED_PATHS)) {\n rejected.push({ input: dropped.path, reason: 'over_cap' })\n }\n\n return { declaration: { paths: kept }, rejected }\n}\n\n/** True when `path` is exactly `base`, or (when `base` is a subtree entry) nested under it. */\nfunction entryContains(base: OwnedPathEntry, path: string): boolean {\n if (path === base.path) return true\n if (base.subtree && (path === base.path || path.startsWith(`${base.path}/`))) return true\n return false\n}\n\n/** True when two normalized entries' claimed sets intersect (exact match, or one contains the other's directory). */\nfunction entriesOverlap(a: OwnedPathEntry, b: OwnedPathEntry): boolean {\n if (a.path === b.path) return true\n if (a.subtree && (b.path === a.path || b.path.startsWith(`${a.path}/`))) return true\n if (b.subtree && (a.path === b.path || a.path.startsWith(`${b.path}/`))) return true\n return false\n}\n\n/** True when two declarations claim any overlapping path. Pure set comparison — no policy (refuse vs warn) here. */\nexport function pathsOverlap(a: OwnedPathsDeclaration, b: OwnedPathsDeclaration): boolean {\n if (a.paths.length === 0 || b.paths.length === 0) return false\n for (const pa of a.paths) {\n for (const pb of b.paths) {\n if (entriesOverlap(pa, pb)) return true\n }\n }\n return false\n}\n\nexport interface InFlightOwnership {\n readonly taskId: string\n readonly paths: OwnedPathsDeclaration\n}\n\nexport interface OwnershipConflict {\n readonly taskId: string\n /** The specific overlapping paths, for a readable refusal message. */\n readonly overlappingPaths: readonly string[]\n}\n\n/**\n * Compare a candidate declaration against every other in-flight task's\n * declaration and return every conflict found (not just the first), each\n * naming the owning task id and the specific overlapping path(s) — so a\n * refusal message can say exactly what collided, not just that it did.\n *\n * Backward compatibility (design doc risk #4): an EMPTY candidate declaration\n * never conflicts (opt-in only — absent `owned_paths` performs no overlap\n * check for that task), and an in-flight entry with an empty declaration is\n * never reported as a conflict source either.\n */\nexport function findOwnershipConflicts(\n candidate: OwnedPathsDeclaration,\n inFlight: readonly InFlightOwnership[],\n): OwnershipConflict[] {\n if (candidate.paths.length === 0) return []\n const conflicts: OwnershipConflict[] = []\n for (const other of inFlight) {\n if (other.paths.paths.length === 0) continue\n const overlappingPaths: string[] = []\n for (const pa of candidate.paths) {\n for (const pb of other.paths.paths) {\n if (entriesOverlap(pa, pb)) {\n const narrower = pa.path.length >= pb.path.length ? pa.path : pb.path\n if (!overlappingPaths.includes(narrower)) overlappingPaths.push(narrower)\n }\n }\n }\n if (overlappingPaths.length > 0) {\n conflicts.push({ taskId: other.taskId, overlappingPaths })\n }\n }\n return conflicts\n}\n\nexport interface TouchedFilesOutsideOwnershipResult {\n /** Touched files not covered by any declared owned-path entry. */\n readonly undeclaredTouched: readonly string[]\n /** Declared entries that no touched file matched (informational only — under-reporting is not flagged as a mismatch by policy, just visible here). */\n readonly unusedDeclarations: readonly string[]\n}\n\n/**\n * Compare a worker's `report_completion.touched_files` against its task's\n * declared `owned_paths`. Pure comparison only — per the design doc, a\n * mismatch is \"surfaced as evidence, not silently accepted\"; this function\n * does not decide whether that is an error. Each `touched` entry is\n * normalized with the same rules as a declaration (invalid entries — e.g. an\n * absolute path a worker reported by mistake — are treated as undeclared\n * rather than silently dropped, since they cannot match anything).\n */\nexport function touchedFilesOutsideOwnership(\n touched: readonly string[],\n owned: OwnedPathsDeclaration,\n): TouchedFilesOutsideOwnershipResult {\n const undeclaredTouched: string[] = []\n const usedDeclarations = new Set<string>()\n\n for (const raw of touched ?? []) {\n const rejectedSink: Array<{ input: string; reason: string }> = []\n const entry = normalizeOne(raw, rejectedSink)\n if (!entry) {\n undeclaredTouched.push(raw)\n continue\n }\n const matches = owned.paths.filter(base => entryContains(base, entry.path))\n if (matches.length === 0) {\n undeclaredTouched.push(entry.path)\n } else {\n for (const m of matches) usedDeclarations.add(m.path)\n }\n }\n\n const unusedDeclarations = owned.paths.map(p => p.path).filter(p => !usedDeclarations.has(p))\n return { undeclaredTouched, unusedDeclarations }\n}\n","/**\n * Keyed document delta — THE diff/fold engine behind every keyed dashboard\n * lane: `daemon.metadata` (the daemon's state, sessions keyed by id) and\n * `mesh.status` (the coordinator's mesh view, nodes / queue tasks / missions\n * keyed) — data-path audit 2026-09-29 P1-4 (one engine, one spec per lane).\n *\n * A document is plain top-level fields, optional SPLIT objects (an object whose\n * fields are diffed one by one, e.g. daemon.metadata's `status`), and named\n * keyed COLLECTIONS (arrays of rows identified by an id field, possibly nested\n * one object deep, e.g. `queue.tasks` / `status.sessions`). The daemon digests\n * every body it would have sent, diffs it against the digest of the last body\n * DELIVERED to a subscription, and sends only the difference: changed fields,\n * and per collection the rows whose content changed (changed fields only), the\n * fields a row lost, and the rows that disappeared. An unchanged document\n * diffs to `null` — zero bytes on the wire. The dashboard folds each delta\n * into its held snapshot; the fold of every delta since a snapshot equals the\n * latest snapshot apart from `ignore`d fields (pinned by keyed-doc-delta.test.ts).\n *\n * Volatile fields (a build stamp, live process counters, a row's per-build\n * stamps via `stableRow`) are not a change by themselves; when something else\n * changed they ride along.\n *\n * Pure leaf: plain objects in, plain objects out; no transport, no clock.\n */\n\nexport interface KeyedDocSpec {\n /** Collection path (`nodes`, `queue.tasks`, `status.sessions`) → the id field of its rows. */\n collections: Readonly<Record<string, string>>\n /** Top-level objects whose own fields are diffed one by one (the rest of the object is not re-sent). */\n splitObjects?: readonly string[]\n /** Field paths (`daemonId`, `status.timestamp`) that are never diffed — envelope identity / clock. */\n ignore?: readonly string[]\n /** Field paths (top-level or inside a split object) that change on every build without meaning anything. */\n volatileTopLevel?: readonly string[]\n /**\n * The part of a collection row that decides whether it CHANGED (drop the\n * per-build stamps inside it). A row whose stable view is unchanged sends\n * nothing; a changed row sends every field whose value differs, stamps\n * included. Must not mutate `row`.\n */\n stableRow?: (collection: string, row: Record<string, unknown>) => Record<string, unknown>\n}\n\ntype Row = Record<string, unknown>\n\ninterface RowDigest {\n readonly value: Row\n /** The row as compared (stableRow view). */\n readonly stable: Row\n readonly sig: string\n fieldSigs?: Map<string, string>\n}\n\ninterface CollectionDigest {\n readonly rows: ReadonlyMap<string, RowDigest>\n readonly order: readonly string[]\n}\n\nexport interface KeyedDocDigest {\n /** Field signatures by path (`field`, or `object.field` for a split object). */\n readonly top: ReadonlyMap<string, string>\n readonly topValues: Readonly<Record<string, unknown>>\n readonly collections: ReadonlyMap<string, CollectionDigest>\n readonly volatile: ReadonlySet<string>\n}\n\nexport interface KeyedCollectionDelta {\n /** New rows (whole) and changed rows (id + changed fields). */\n upsert?: Row[]\n /** Fields a row lost, by row id. */\n unsetFields?: Record<string, string[]>\n removed?: string[]\n order?: string[]\n /** The collection is no longer present in the document at all. */\n absent?: true\n}\n\nexport interface KeyedDocDelta {\n set?: Record<string, unknown>\n unset?: string[]\n /** Per split object: its changed / lost fields. */\n objects?: Record<string, { set?: Record<string, unknown>; unset?: string[] }>\n collections?: Record<string, KeyedCollectionDelta>\n}\n\nfunction sig(value: unknown): string | undefined {\n if (value === undefined) return undefined\n try {\n return JSON.stringify(value)\n } catch {\n return undefined\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value)\n}\n\n/** Read the array at `path` (`a` or `a.b`) — undefined when absent. */\nfunction readPath(doc: Record<string, unknown>, path: string): unknown {\n const [head, tail] = splitPath(path)\n if (!tail) return doc[head]\n const parent = doc[head]\n return isRecord(parent) ? parent[tail] : undefined\n}\n\nfunction splitPath(path: string): [string, string | undefined] {\n const dot = path.indexOf('.')\n return dot < 0 ? [path, undefined] : [path.slice(0, dot), path.slice(dot + 1)]\n}\n\n/**\n * The document minus its collections (a nested collection is removed from a\n * shallow copy of its parent, so the parent's other fields stay top-level data).\n */\nfunction stripCollections(doc: Record<string, unknown>, spec: KeyedDocSpec): Record<string, unknown> {\n const out: Record<string, unknown> = { ...doc }\n for (const path of Object.keys(spec.collections)) {\n const [head, tail] = splitPath(path)\n if (!tail) {\n delete out[head]\n continue\n }\n const parent = out[head]\n if (!isRecord(parent) || !(tail in parent)) continue\n const copy = { ...parent }\n delete copy[tail]\n out[head] = copy\n }\n return out\n}\n\nfunction fieldSigsOf(digest: RowDigest): Map<string, string> {\n if (!digest.fieldSigs) {\n const sigs = new Map<string, string>()\n for (const [key, value] of Object.entries(digest.stable)) {\n const s = sig(value)\n if (s !== undefined) sigs.set(key, s)\n }\n digest.fieldSigs = sigs\n }\n return digest.fieldSigs\n}\n\n/** Digest one document. Cheap to hold: values are referenced, not copied. */\nexport function digestKeyedDoc(doc: Record<string, unknown>, spec: KeyedDocSpec): KeyedDocDigest {\n const top = new Map<string, string>()\n const topValues: Record<string, unknown> = {}\n const ignore = new Set(spec.ignore ?? [])\n const split = new Set(spec.splitObjects ?? [])\n const add = (path: string, value: unknown) => {\n if (ignore.has(path)) return\n const s = sig(value)\n if (s === undefined) return\n top.set(path, s)\n topValues[path] = value\n }\n for (const [key, value] of Object.entries(stripCollections(doc, spec))) {\n if (split.has(key) && isRecord(value)) {\n for (const [field, fieldValue] of Object.entries(value)) add(`${key}.${field}`, fieldValue)\n continue\n }\n add(key, value)\n }\n const collections = new Map<string, CollectionDigest>()\n for (const [path, idField] of Object.entries(spec.collections)) {\n const list = readPath(doc, path)\n if (!Array.isArray(list)) continue\n const rows = new Map<string, RowDigest>()\n const order: string[] = []\n for (const row of list) {\n if (!isRecord(row)) continue\n const id = row[idField]\n if (typeof id !== 'string' || !id || rows.has(id)) continue\n const stable = spec.stableRow ? spec.stableRow(path, row) : row\n rows.set(id, { value: row, stable, sig: sig(stable) ?? '' })\n order.push(id)\n }\n collections.set(path, { rows, order })\n }\n return { top, topValues, collections, volatile: new Set(spec.volatileTopLevel ?? []) }\n}\n\nfunction sameOrder(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i += 1) if (a[i] !== b[i]) return false\n return true\n}\n\nfunction diffCollection(prev: CollectionDigest | undefined, next: CollectionDigest | undefined, idField: string): KeyedCollectionDelta | null {\n if (!next) return prev ? { absent: true } : null\n const delta: KeyedCollectionDelta = {}\n const prevRows = prev?.rows ?? new Map<string, RowDigest>()\n const nextRows = next?.rows ?? new Map<string, RowDigest>()\n for (const [id, nextRow] of nextRows) {\n const prevRow = prevRows.get(id)\n if (!prevRow) {\n ;(delta.upsert ??= []).push(nextRow.value)\n continue\n }\n if (prevRow.sig === nextRow.sig) continue\n const prevSigs = fieldSigsOf(prevRow)\n const nextSigs = fieldSigsOf(nextRow)\n const change: Row = { [idField]: id }\n let changed = false\n for (const [key, s] of nextSigs) {\n if (key === idField || prevSigs.get(key) === s) continue\n change[key] = nextRow.value[key]\n changed = true\n }\n // A real change carries the row's volatile fields (dropped by stableRow) along.\n if (changed) {\n for (const [key, value] of Object.entries(nextRow.value)) {\n if (key in nextRow.stable || key in change) continue\n if (sig(prevRow.value[key]) !== sig(value)) change[key] = value\n }\n }\n const gone: string[] = []\n for (const key of prevSigs.keys()) if (!nextSigs.has(key) && !(key in nextRow.value)) gone.push(key)\n if (changed) (delta.upsert ??= []).push(change)\n if (gone.length > 0) (delta.unsetFields ??= {})[id] = gone\n }\n for (const id of prevRows.keys()) {\n if (!nextRows.has(id)) (delta.removed ??= []).push(id)\n }\n if (!sameOrder(prev?.order ?? [], next?.order ?? [])) delta.order = [...(next?.order ?? [])]\n return Object.keys(delta).length > 0 ? delta : null\n}\n\n/**\n * The difference `prev → next`, or `null` when nothing a consumer can observe\n * changed (volatile top-level fields alone are not a change).\n */\nexport function diffKeyedDoc(prev: KeyedDocDigest, next: KeyedDocDigest, spec: KeyedDocSpec): KeyedDocDelta | null {\n const delta: KeyedDocDelta = {}\n let meaningful = false\n let set: Record<string, unknown> | undefined\n let unset: string[] | undefined\n const split = spec.splitObjects ?? []\n const objectOf = (path: string): [string, string] | null => {\n for (const object of split) {\n if (path.startsWith(`${object}.`)) return [object, path.slice(object.length + 1)]\n }\n return null\n }\n const objects: NonNullable<KeyedDocDelta['objects']> = {}\n for (const [path, s] of next.top) {\n if (prev.top.get(path) === s) continue\n const inObject = objectOf(path)\n if (inObject) ((objects[inObject[0]] ??= {}).set ??= {})[inObject[1]] = next.topValues[path]\n else (set ??= {})[path] = next.topValues[path]\n if (!next.volatile.has(path)) meaningful = true\n }\n for (const path of prev.top.keys()) {\n if (next.top.has(path)) continue\n const inObject = objectOf(path)\n if (inObject) ((objects[inObject[0]] ??= {}).unset ??= []).push(inObject[1])\n else (unset ??= []).push(path)\n if (!next.volatile.has(path)) meaningful = true\n }\n for (const [path, idField] of Object.entries(spec.collections)) {\n const change = diffCollection(prev.collections.get(path), next.collections.get(path), idField)\n if (!change) continue\n ;(delta.collections ??= {})[path] = change\n meaningful = true\n }\n if (!meaningful) return null\n if (set) delta.set = set\n if (unset) delta.unset = unset\n if (Object.keys(objects).length > 0) delta.objects = objects\n return delta\n}\n\nfunction foldCollection(held: unknown, change: KeyedCollectionDelta, idField: string): Row[] {\n const byId = new Map<string, Row>()\n const heldOrder: string[] = []\n for (const row of Array.isArray(held) ? held : []) {\n if (!isRecord(row) || typeof row[idField] !== 'string') continue\n byId.set(row[idField] as string, row)\n heldOrder.push(row[idField] as string)\n }\n for (const id of change.removed ?? []) byId.delete(id)\n for (const row of change.upsert ?? []) {\n const id = row[idField]\n if (typeof id !== 'string') continue\n const base = byId.get(id)\n byId.set(id, base ? { ...base, ...row } : { ...row })\n }\n for (const [id, keys] of Object.entries(change.unsetFields ?? {})) {\n const base = byId.get(id)\n if (!base) continue\n const trimmed = { ...base }\n for (const key of keys) delete trimmed[key]\n byId.set(id, trimmed)\n }\n const order = change.order ?? heldOrder\n const out: Row[] = []\n const placed = new Set<string>()\n for (const id of order) {\n const row = byId.get(id)\n if (!row || placed.has(id)) continue\n out.push(row)\n placed.add(id)\n }\n for (const [id, row] of byId) if (!placed.has(id)) out.push(row)\n return out\n}\n\n/** Rebuild the full document from a held one plus a delta. Never mutates `held`. */\nexport function foldKeyedDoc<T extends Record<string, unknown>>(held: T, delta: KeyedDocDelta, spec: KeyedDocSpec): T {\n // Collections are re-inserted below from the held ones, so the plain fields\n // are folded on the stripped view (a nested parent keeps its other fields).\n const heldCollections = new Map<string, unknown>()\n for (const path of Object.keys(spec.collections)) heldCollections.set(path, readPath(held, path))\n const next: Record<string, unknown> = stripCollections(held, spec)\n for (const key of delta.unset ?? []) delete next[key]\n Object.assign(next, delta.set ?? {})\n for (const [object, change] of Object.entries(delta.objects ?? {})) {\n const folded: Record<string, unknown> = isRecord(next[object]) ? { ...(next[object] as Record<string, unknown>) } : {}\n for (const key of change.unset ?? []) delete folded[key]\n Object.assign(folded, change.set ?? {})\n next[object] = folded\n }\n for (const [path, idField] of Object.entries(spec.collections)) {\n const change = delta.collections?.[path]\n const heldList = heldCollections.get(path)\n if (change?.absent) {\n const [head, tail] = splitPath(path)\n if (!tail) delete next[head]\n continue\n }\n if (!change && heldList === undefined) continue\n const list = change ? foldCollection(heldList, change, idField) : heldList\n const [head, tail] = splitPath(path)\n if (!tail) {\n next[head] = list\n continue\n }\n const parent = isRecord(next[head]) ? { ...(next[head] as Record<string, unknown>) } : {}\n parent[tail] = list\n next[head] = parent\n }\n return next as T\n}\n\n/**\n * The `daemon.metadata` document (the snapshot body minus its envelope):\n * `status` is split field by field, its sessions keyed by `id`. `daemonId` is\n * envelope identity and `status.timestamp` the build clock — never diffed (the\n * fold re-stamps them from the frame); a session's `lastUpdated` build stamp is\n * not a change by itself.\n */\nexport const DAEMON_METADATA_DOC_SPEC: KeyedDocSpec = {\n collections: { 'status.sessions': 'id' },\n splitObjects: ['status'],\n ignore: ['daemonId', 'status.timestamp'],\n stableRow: (_collection, row) => {\n if (!('lastUpdated' in row)) return row\n const { lastUpdated: _stamp, ...stable } = row\n return stable\n },\n}\n\n/**\n * The `mesh.status` document: nodes keyed by `nodeId`, queue tasks and missions\n * by `id`. `refreshedAt` and `sourceOfTruth` (its aggregate-cache age /\n * returnedAt) are per-call stamps and the counters are live process tallies —\n * none of them is a change by itself.\n */\nexport const MESH_STATUS_DOC_SPEC: KeyedDocSpec = {\n collections: { nodes: 'nodeId', 'queue.tasks': 'id', missions: 'id' },\n volatileTopLevel: [\n 'refreshedAt', 'sourceOfTruth',\n 'turnPresentationCounters', 'meshProtocolV2Counters', 'pendingRetentionCounters', 'meshProtocolMetrics',\n ],\n stableRow: (collection, row) => (collection === 'nodes' ? stableMeshNodeRow(row) : row),\n}\n\nfunction without(value: unknown, keys: readonly string[]): unknown {\n if (!isRecord(value)) return value\n const out = { ...value }\n for (const key of keys) delete out[key]\n return out\n}\n\n/**\n * A mesh node minus the stamps an aggregate rebuild re-derives from the clock\n * (last-seen / updated / freshness age, the local read's check time, a local\n * facts bundle's reportedAt). A REMOTE node's `gitObservation.observedAt` is\n * real news (the member's own check time — the dashboard's \"aged\" hint) and\n * is compared; the coordinator's own / local checkout's is its read time.\n */\nfunction stableMeshNodeRow(row: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = { ...row }\n delete out.lastSeenAt\n delete out.updatedAt\n delete out.last_seen_at\n delete out.updated_at\n if ('dataFreshness' in out) out.dataFreshness = without(out.dataFreshness, ['ageMs', 'lastProbeAt', 'staleness'])\n if ('connection' in out) out.connection = without(out.connection, ['lastStateChangeAt'])\n if ('git' in out) {\n const git = without(out.git, ['lastCheckedAt'])\n // \"No submodules\" is the same fact whether a read listed none or skipped the scan.\n if (isRecord(git) && Array.isArray(git.submodules) && git.submodules.length === 0) delete git.submodules\n out.git = git\n }\n if ('nodeFacts' in out) out.nodeFacts = without(out.nodeFacts, ['reportedAt'])\n const observation = out.gitObservation\n if (isRecord(observation) && (observation.source === 'self' || observation.source === 'local')) {\n out.gitObservation = without(observation, ['observedAt'])\n }\n return out\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","names":["id","makeGuard","isRecord","isFiniteNumber","isFiniteNumber","isOptionalId","hasOnlyKeys","makeGuard","makeGuard","hasOnlyKeys","isOptionalId","isFiniteNumber","makeGuard","hasOnlyKeys","isOptionalId","hasOnlyKeys","isOptionalId","hasOnlyKeys","makeGuard","hasOnlyKeys","isRecord","id","head","tail"]}